feat: Implement TTS playback store and enhance reading progress synchronization
Build Android APK / build-apk (push) Has been cancelled
Build Android AAB / build-aab (push) Has been cancelled

- Added ReaderTtsPlaybackStore to manage TTS start requests with a maximum of 4 pending requests.
- Updated app configuration to use a production API URL.
- Enhanced BookmarkModel to infer type when not provided by the API for backward compatibility.
- Introduced methods in LocalStore for saving, loading, and clearing the last route path.
- Implemented syncProgress method in BookshelfNotifier to update reading progress and bookmarks from the server.
- Modified ReaderScreen to handle chapter navigation and TTS playback more effectively, including auto-start logic.
- Updated TtsPlayerWidget to accept additional parameters for chapter navigation.
- Enhanced TtsNotifier to handle new parameters for TTS requests and manage playback state.
- Improved SplashScreen to restore the last visited route after splash screen display.
This commit is contained in:
2026-04-27 00:48:05 +07:00
parent 66613857e8
commit c3e6d66f43
14 changed files with 758 additions and 128 deletions
+16 -1
View File
@@ -39,13 +39,28 @@ class BookmarkModel extends Equatable {
factory BookmarkModel.fromJson(Map<String, dynamic> json) => BookmarkModel(
id: json['id'] as String,
novelId: json['novelId'] as String,
type: BookmarkType.fromString(json['type'] as String?),
lastChapterId: json['lastChapterId'] as String?,
lastChapterNumber: json['lastChapterNumber'] as int?,
readChapters: (json['readChapters'] as List<dynamic>?)
?.map((e) => (e as num).toInt())
.toList() ??
[],
type: () {
final explicitType = BookmarkType.fromString(json['type'] as String?);
if ((json['type'] as String?) != null) {
return explicitType;
}
// Backward-compatible inference when API does not return `type`.
final inferredLastChapter = json['lastChapterNumber'] as int?;
final inferredReadChapters = (json['readChapters'] as List<dynamic>?)
?.map((e) => (e as num).toInt())
.toList() ??
const <int>[];
return (inferredLastChapter != null || inferredReadChapters.isNotEmpty)
? BookmarkType.reading
: BookmarkType.bookmarked;
}(),
novel: json['novel'] != null
? NovelModel.fromJson(json['novel'] as Map<String, dynamic>)
: null,