saving novel chapter progress + removed sync for now

This commit is contained in:
Schnitzel5 2024-12-21 21:18:21 +01:00
parent c01aa6d023
commit 3bc85cf5aa
33 changed files with 141 additions and 2962 deletions

View file

@ -18,8 +18,6 @@ import 'package:mangayomi/modules/more/settings/appearance/providers/blend_level
import 'package:mangayomi/modules/more/settings/appearance/providers/flex_scheme_color_state_provider.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/flex_scheme_color_state_provider.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_state_provider.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/services/sync_server.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:mangayomi/src/rust/frb_generated.dart'; import 'package:mangayomi/src/rust/frb_generated.dart';
import 'package:media_kit/media_kit.dart'; import 'package:media_kit/media_kit.dart';
@ -82,10 +80,6 @@ class _MyAppState extends ConsumerState<MyApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final syncOnAppLaunch = ref.watch(syncOnAppLaunchStateProvider);
if (syncOnAppLaunch) {
ref.read(syncServerProvider(syncId: 1).notifier).checkForSync(true);
}
final isDarkTheme = ref.watch(themeModeStateProvider); final isDarkTheme = ref.watch(themeModeStateProvider);
final blendLevel = ref.watch(blendLevelStateProvider); final blendLevel = ref.watch(blendLevelStateProvider);
final appFontFamily = ref.watch(appFontFamilyProvider); final appFontFamily = ref.watch(appFontFamilyProvider);

View file

@ -1,86 +0,0 @@
import 'package:isar/isar.dart';
part 'changed_items.g.dart';
@collection
@Name("Changed Items")
class ChangedItems {
Id? id;
List<DeletedManga>? deletedMangas;
List<UpdatedChapter>? updatedChapters;
List<DeletedCategory>? deletedCategories;
ChangedItems(
{this.id = Isar.autoIncrement,
this.deletedMangas = const [],
this.updatedChapters = const [],
this.deletedCategories = const []});
ChangedItems.fromJson(Map<String, dynamic> json) {
id = json['id'];
deletedMangas = json['deletedMangas'];
updatedChapters = json['updatedChapters'];
deletedCategories = json['deletedCategories'];
}
Map<String, dynamic> toJson() => {
'id': id,
'deletedMangas': deletedMangas,
'updatedChapters': updatedChapters,
'deletedCategories': deletedCategories
};
}
@embedded
class DeletedManga {
int? mangaId;
DeletedManga({this.mangaId});
DeletedManga.fromJson(Map<String, dynamic> json) {
mangaId = json['mangaId'];
}
Map<String, dynamic> toJson() => {'mangaId': mangaId};
}
@embedded
class UpdatedChapter {
int? chapterId;
int? mangaId;
bool? isBookmarked;
bool? isRead;
String? lastPageRead;
bool? deleted;
UpdatedChapter(
{this.chapterId,
this.mangaId,
this.isBookmarked,
this.isRead,
this.lastPageRead,
this.deleted});
UpdatedChapter.fromJson(Map<String, dynamic> json) {
chapterId = json['chapterId'];
mangaId = json['mangaId'];
isBookmarked = json['isBookmarked'];
isRead = json['isRead'];
lastPageRead = json['lastPageRead'];
deleted = json['deleted'];
}
Map<String, dynamic> toJson() => {
'chapterId': chapterId,
'mangaId': mangaId,
'isBookmarked': isBookmarked,
'isRead': isRead,
'lastPageRead': lastPageRead,
'deleted': deleted
};
}
@embedded
class DeletedCategory {
int? categoryId;
DeletedCategory({this.categoryId});
DeletedCategory.fromJson(Map<String, dynamic> json) {
categoryId = json['categoryId'];
}
Map<String, dynamic> toJson() => {'categoryId': categoryId};
}

File diff suppressed because it is too large Load diff

View file

@ -135,10 +135,6 @@ class Settings {
List<int>? backupFrequencyOptions; List<int>? backupFrequencyOptions;
bool? syncOnAppLaunch;
bool? syncAfterReading;
String? autoBackupLocation; String? autoBackupLocation;
bool? usePageTapZones; bool? usePageTapZones;
@ -276,8 +272,6 @@ class Settings {
this.personalPageModeList, this.personalPageModeList,
this.backupFrequency, this.backupFrequency,
this.backupFrequencyOptions, this.backupFrequencyOptions,
this.syncOnAppLaunch,
this.syncAfterReading,
this.autoBackupLocation, this.autoBackupLocation,
this.startDatebackup, this.startDatebackup,
this.usePageTapZones = true, this.usePageTapZones = true,
@ -436,8 +430,6 @@ class Settings {
userAgent = json['userAgent']; userAgent = json['userAgent'];
backupFrequency = json['backupFrequency']; backupFrequency = json['backupFrequency'];
backupFrequencyOptions = json['backupFrequencyOptions']?.cast<int>(); backupFrequencyOptions = json['backupFrequencyOptions']?.cast<int>();
syncOnAppLaunch = json['syncOnAppLaunch'];
syncAfterReading = json['syncAfterReading'];
autoBackupLocation = json['autoBackupLocation']; autoBackupLocation = json['autoBackupLocation'];
startDatebackup = json['startDatebackup']; startDatebackup = json['startDatebackup'];
usePageTapZones = json['usePageTapZones']; usePageTapZones = json['usePageTapZones'];
@ -559,8 +551,6 @@ class Settings {
'userAgent': userAgent, 'userAgent': userAgent,
'backupFrequency': backupFrequency, 'backupFrequency': backupFrequency,
'backupFrequencyOptions': backupFrequencyOptions, 'backupFrequencyOptions': backupFrequencyOptions,
'syncOnAppLaunch': syncOnAppLaunch,
'syncAfterReading': syncAfterReading,
'autoBackupLocation': autoBackupLocation, 'autoBackupLocation': autoBackupLocation,
'startDatebackup': startDatebackup, 'startDatebackup': startDatebackup,
'usePageTapZones': usePageTapZones, 'usePageTapZones': usePageTapZones,

View file

@ -508,38 +508,28 @@ const SettingsSchema = CollectionSchema(
name: r'startDatebackup', name: r'startDatebackup',
type: IsarType.long, type: IsarType.long,
), ),
r'syncAfterReading': PropertySchema(
id: 93,
name: r'syncAfterReading',
type: IsarType.bool,
),
r'syncOnAppLaunch': PropertySchema(
id: 94,
name: r'syncOnAppLaunch',
type: IsarType.bool,
),
r'themeIsDark': PropertySchema( r'themeIsDark': PropertySchema(
id: 95, id: 93,
name: r'themeIsDark', name: r'themeIsDark',
type: IsarType.bool, type: IsarType.bool,
), ),
r'updateProgressAfterReading': PropertySchema( r'updateProgressAfterReading': PropertySchema(
id: 96, id: 94,
name: r'updateProgressAfterReading', name: r'updateProgressAfterReading',
type: IsarType.bool, type: IsarType.bool,
), ),
r'useLibass': PropertySchema( r'useLibass': PropertySchema(
id: 97, id: 95,
name: r'useLibass', name: r'useLibass',
type: IsarType.bool, type: IsarType.bool,
), ),
r'usePageTapZones': PropertySchema( r'usePageTapZones': PropertySchema(
id: 98, id: 96,
name: r'usePageTapZones', name: r'usePageTapZones',
type: IsarType.bool, type: IsarType.bool,
), ),
r'userAgent': PropertySchema( r'userAgent': PropertySchema(
id: 99, id: 97,
name: r'userAgent', name: r'userAgent',
type: IsarType.string, type: IsarType.string,
) )
@ -1017,13 +1007,11 @@ void _settingsSerialize(
object.sortLibraryNovel, object.sortLibraryNovel,
); );
writer.writeLong(offsets[92], object.startDatebackup); writer.writeLong(offsets[92], object.startDatebackup);
writer.writeBool(offsets[93], object.syncAfterReading); writer.writeBool(offsets[93], object.themeIsDark);
writer.writeBool(offsets[94], object.syncOnAppLaunch); writer.writeBool(offsets[94], object.updateProgressAfterReading);
writer.writeBool(offsets[95], object.themeIsDark); writer.writeBool(offsets[95], object.useLibass);
writer.writeBool(offsets[96], object.updateProgressAfterReading); writer.writeBool(offsets[96], object.usePageTapZones);
writer.writeBool(offsets[97], object.useLibass); writer.writeString(offsets[97], object.userAgent);
writer.writeBool(offsets[98], object.usePageTapZones);
writer.writeString(offsets[99], object.userAgent);
} }
Settings _settingsDeserialize( Settings _settingsDeserialize(
@ -1200,13 +1188,11 @@ Settings _settingsDeserialize(
allOffsets, allOffsets,
), ),
startDatebackup: reader.readLongOrNull(offsets[92]), startDatebackup: reader.readLongOrNull(offsets[92]),
syncAfterReading: reader.readBoolOrNull(offsets[93]), themeIsDark: reader.readBoolOrNull(offsets[93]),
syncOnAppLaunch: reader.readBoolOrNull(offsets[94]), updateProgressAfterReading: reader.readBoolOrNull(offsets[94]),
themeIsDark: reader.readBoolOrNull(offsets[95]), useLibass: reader.readBoolOrNull(offsets[95]),
updateProgressAfterReading: reader.readBoolOrNull(offsets[96]), usePageTapZones: reader.readBoolOrNull(offsets[96]),
useLibass: reader.readBoolOrNull(offsets[97]), userAgent: reader.readStringOrNull(offsets[97]),
usePageTapZones: reader.readBoolOrNull(offsets[98]),
userAgent: reader.readStringOrNull(offsets[99]),
); );
object.chapterFilterBookmarkedList = object.chapterFilterBookmarkedList =
reader.readObjectList<ChapterFilterBookmarked>( reader.readObjectList<ChapterFilterBookmarked>(
@ -1533,10 +1519,6 @@ P _settingsDeserializeProp<P>(
case 96: case 96:
return (reader.readBoolOrNull(offset)) as P; return (reader.readBoolOrNull(offset)) as P;
case 97: case 97:
return (reader.readBoolOrNull(offset)) as P;
case 98:
return (reader.readBoolOrNull(offset)) as P;
case 99:
return (reader.readStringOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
default: default:
throw IsarError('Unknown property with id $propertyId'); throw IsarError('Unknown property with id $propertyId');
@ -7545,62 +7527,6 @@ extension SettingsQueryFilter
}); });
} }
QueryBuilder<Settings, Settings, QAfterFilterCondition>
syncAfterReadingIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'syncAfterReading',
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
syncAfterReadingIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'syncAfterReading',
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
syncAfterReadingEqualTo(bool? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'syncAfterReading',
value: value,
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
syncOnAppLaunchIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'syncOnAppLaunch',
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
syncOnAppLaunchIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'syncOnAppLaunch',
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition>
syncOnAppLaunchEqualTo(bool? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'syncOnAppLaunch',
value: value,
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition> themeIsDarkIsNull() { QueryBuilder<Settings, Settings, QAfterFilterCondition> themeIsDarkIsNull() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull( return query.addFilterCondition(const FilterCondition.isNull(
@ -9032,30 +8958,6 @@ extension SettingsQuerySortBy on QueryBuilder<Settings, Settings, QSortBy> {
}); });
} }
QueryBuilder<Settings, Settings, QAfterSortBy> sortBySyncAfterReading() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'syncAfterReading', Sort.asc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> sortBySyncAfterReadingDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'syncAfterReading', Sort.desc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> sortBySyncOnAppLaunch() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'syncOnAppLaunch', Sort.asc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> sortBySyncOnAppLaunchDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'syncOnAppLaunch', Sort.desc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> sortByThemeIsDark() { QueryBuilder<Settings, Settings, QAfterSortBy> sortByThemeIsDark() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'themeIsDark', Sort.asc); return query.addSortBy(r'themeIsDark', Sort.asc);
@ -10122,30 +10024,6 @@ extension SettingsQuerySortThenBy
}); });
} }
QueryBuilder<Settings, Settings, QAfterSortBy> thenBySyncAfterReading() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'syncAfterReading', Sort.asc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> thenBySyncAfterReadingDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'syncAfterReading', Sort.desc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> thenBySyncOnAppLaunch() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'syncOnAppLaunch', Sort.asc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> thenBySyncOnAppLaunchDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'syncOnAppLaunch', Sort.desc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> thenByThemeIsDark() { QueryBuilder<Settings, Settings, QAfterSortBy> thenByThemeIsDark() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'themeIsDark', Sort.asc); return query.addSortBy(r'themeIsDark', Sort.asc);
@ -10715,18 +10593,6 @@ extension SettingsQueryWhereDistinct
}); });
} }
QueryBuilder<Settings, Settings, QDistinct> distinctBySyncAfterReading() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'syncAfterReading');
});
}
QueryBuilder<Settings, Settings, QDistinct> distinctBySyncOnAppLaunch() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'syncOnAppLaunch');
});
}
QueryBuilder<Settings, Settings, QDistinct> distinctByThemeIsDark() { QueryBuilder<Settings, Settings, QDistinct> distinctByThemeIsDark() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'themeIsDark'); return query.addDistinctBy(r'themeIsDark');
@ -11393,18 +11259,6 @@ extension SettingsQueryProperty
}); });
} }
QueryBuilder<Settings, bool?, QQueryOperations> syncAfterReadingProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'syncAfterReading');
});
}
QueryBuilder<Settings, bool?, QQueryOperations> syncOnAppLaunchProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'syncOnAppLaunch');
});
}
QueryBuilder<Settings, bool?, QQueryOperations> themeIsDarkProperty() { QueryBuilder<Settings, bool?, QQueryOperations> themeIsDarkProperty() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'themeIsDark'); return query.addPropertyName(r'themeIsDark');

View file

@ -324,7 +324,6 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage>
_currentPosition.value, _currentTotalDuration.value, _currentPosition.value, _currentTotalDuration.value,
save: save); save: save);
_streamController.setAnimeHistoryUpdate(); _streamController.setAnimeHistoryUpdate();
_streamController.checkAndSyncProgress();
} }
void _setLandscapeMode(bool state) { void _setLandscapeMode(bool state) {

View file

@ -7,9 +7,7 @@ import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/track.dart'; import 'package:mangayomi/models/track.dart';
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart'; import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/modules/more/settings/player/providers/player_state_provider.dart'; import 'package:mangayomi/modules/more/settings/player/providers/player_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/services/aniskip.dart'; import 'package:mangayomi/services/aniskip.dart';
import 'package:mangayomi/services/sync_server.dart';
import 'package:mangayomi/utils/chapter_recognition.dart'; import 'package:mangayomi/utils/chapter_recognition.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'anime_player_controller_provider.g.dart'; part 'anime_player_controller_provider.g.dart';
@ -151,13 +149,6 @@ class AnimeStreamController extends _$AnimeStreamController {
}); });
} }
void checkAndSyncProgress() {
final syncAfterReading = ref.watch(syncAfterReadingStateProvider);
if (syncAfterReading) {
ref.read(syncServerProvider(syncId: 1).notifier).checkForSync(true);
}
}
void setCurrentPosition(Duration duration, Duration? totalDuration, void setCurrentPosition(Duration duration, Duration? totalDuration,
{bool save = false}) { {bool save = false}) {
if (episode.isRead!) return; if (episode.isRead!) return;
@ -174,9 +165,6 @@ class AnimeStreamController extends _$AnimeStreamController {
isar.writeTxnSync(() { isar.writeTxnSync(() {
ep.isRead = isWatch; ep.isRead = isWatch;
ep.lastPageRead = (duration.inMilliseconds).toString(); ep.lastPageRead = (duration.inMilliseconds).toString();
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(ep, false, false);
isar.chapters.putSync(ep); isar.chapters.putSync(ep);
}); });
if (isWatch) { if (isWatch) {

View file

@ -7,7 +7,7 @@ part of 'anime_player_controller_provider.dart';
// ************************************************************************** // **************************************************************************
String _$animeStreamControllerHash() => String _$animeStreamControllerHash() =>
r'd3ec7fe7ac2af84393b128e430fd2f5b9224ed14'; r'57ebd35f033d51fd213763173c26cd887f5c42d7';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -10,7 +10,6 @@ import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/history.dart'; import 'package:mangayomi/models/history.dart';
import 'package:mangayomi/models/manga.dart'; import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/modules/history/providers/isar_providers.dart'; import 'package:mangayomi/modules/history/providers/isar_providers.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/cached_network.dart'; import 'package:mangayomi/utils/cached_network.dart';
import 'package:mangayomi/utils/constant.dart'; import 'package:mangayomi/utils/constant.dart';
@ -380,29 +379,12 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
.id!); .id!);
for (var chapter for (var chapter
in chapters) { in chapters) {
await ref
.read(changedItemsManagerProvider(
managerId:
1)
.notifier)
.addUpdatedChapterAsync(
chapter,
true,
false);
await isar await isar
.chapters .chapters
.delete( .delete(
chapter chapter
.id!); .id!);
} }
await ref
.read(changedItemsManagerProvider(
managerId:
1)
.notifier)
.addDeletedMangaAsync(
manga,
false);
await isar.mangas await isar.mangas
.delete(manga .delete(manga
.id!); .id!);

View file

@ -21,7 +21,6 @@ import 'package:mangayomi/modules/library/providers/add_torrent.dart';
import 'package:mangayomi/modules/library/providers/local_archive.dart'; import 'package:mangayomi/modules/library/providers/local_archive.dart';
import 'package:mangayomi/modules/manga/detail/providers/update_manga_detail_providers.dart'; import 'package:mangayomi/modules/manga/detail/providers/update_manga_detail_providers.dart';
import 'package:mangayomi/modules/more/categories/providers/isar_providers.dart'; import 'package:mangayomi/modules/more/categories/providers/isar_providers.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart'; import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart'; import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart';
import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/providers/l10n_providers.dart';
@ -1163,12 +1162,6 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
} }
for (var chapter in manga.chapters) { for (var chapter in manga.chapters) {
ref
.read(changedItemsManagerProvider(
managerId: 1)
.notifier)
.addUpdatedChapter(
chapter, true, false);
isar.updates isar.updates
.filter() .filter()
.mangaIdEqualTo(chapter.mangaId) .mangaIdEqualTo(chapter.mangaId)
@ -1176,11 +1169,6 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
.deleteAllSync(); .deleteAllSync();
isar.chapters.deleteSync(chapter.id!); isar.chapters.deleteSync(chapter.id!);
} }
ref
.read(changedItemsManagerProvider(
managerId: 1)
.notifier)
.addDeletedManga(manga, false);
isar.mangas.deleteSync(manga.id!); isar.mangas.deleteSync(manga.id!);
} else { } else {
manga.favorite = false; manga.favorite = false;

View file

@ -4,7 +4,6 @@ import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart'; import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart'; import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart'; import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'library_state_provider.g.dart'; part 'library_state_provider.g.dart';
@ -786,9 +785,6 @@ class MangasSetIsReadState extends _$MangasSetIsReadState {
for (var chapter in chapters) { for (var chapter in chapters) {
chapter.isRead = true; chapter.isRead = true;
chapter.lastPageRead = "1"; chapter.lastPageRead = "1";
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(chapter, false, false);
isar.chapters.putSync(chapter..manga.value = manga); isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync(); chapter.manga.saveSync();
} }
@ -813,9 +809,6 @@ class MangasSetUnReadState extends _$MangasSetUnReadState {
isar.writeTxnSync(() { isar.writeTxnSync(() {
for (var chapter in chapters) { for (var chapter in chapters) {
chapter.isRead = false; chapter.isRead = false;
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(chapter, false, false);
isar.chapters.putSync(chapter..manga.value = manga); isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync(); chapter.manga.saveSync();
} }

View file

@ -2551,7 +2551,7 @@ final isLongPressedMangaStateProvider =
typedef _$IsLongPressedMangaState = AutoDisposeNotifier<bool>; typedef _$IsLongPressedMangaState = AutoDisposeNotifier<bool>;
String _$mangasSetIsReadStateHash() => String _$mangasSetIsReadStateHash() =>
r'cb88914fe1c47c1e3a29d43c23a6652b0e8f2ac1'; r'8f86296f588a48747de625e0471048978ee9bdeb';
abstract class _$MangasSetIsReadState abstract class _$MangasSetIsReadState
extends BuildlessAutoDisposeNotifier<void> { extends BuildlessAutoDisposeNotifier<void> {
@ -2698,7 +2698,7 @@ class _MangasSetIsReadStateProviderElement
} }
String _$mangasSetUnReadStateHash() => String _$mangasSetUnReadStateHash() =>
r'7b2f4c579f9cb392830ed4d70aff9ccc3e7952a0'; r'3413e731b2fd8476a4032d3e47b943ca12f25090';
abstract class _$MangasSetUnReadState abstract class _$MangasSetUnReadState
extends BuildlessAutoDisposeNotifier<void> { extends BuildlessAutoDisposeNotifier<void> {

View file

@ -22,7 +22,6 @@ import 'package:mangayomi/modules/manga/detail/widgets/tracker_search_widget.dar
import 'package:mangayomi/modules/manga/detail/widgets/tracker_widget.dart'; import 'package:mangayomi/modules/manga/detail/widgets/tracker_widget.dart';
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart'; import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.dart'; import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.dart';
import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart'; import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart'; import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
@ -733,11 +732,6 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
isar.writeTxnSync(() { isar.writeTxnSync(() {
for (var chapter in chapters) { for (var chapter in chapters) {
chapter.isBookmarked = !chapter.isBookmarked!; chapter.isBookmarked = !chapter.isBookmarked!;
ref
.read(changedItemsManagerProvider(
managerId: 1)
.notifier)
.addUpdatedChapter(chapter, false, false);
isar.chapters.putSync( isar.chapters.putSync(
chapter..manga.value = widget.manga); chapter..manga.value = widget.manga);
chapter.manga.saveSync(); chapter.manga.saveSync();
@ -778,11 +772,6 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
if (!chapter.isRead!) { if (!chapter.isRead!) {
chapter.lastPageRead = "1"; chapter.lastPageRead = "1";
} }
ref
.read(changedItemsManagerProvider(
managerId: 1)
.notifier)
.addUpdatedChapter(chapter, false, false);
isar.chapters.putSync( isar.chapters.putSync(
chapter..manga.value = widget.manga); chapter..manga.value = widget.manga);
chapter.manga.saveSync(); chapter.manga.saveSync();
@ -828,12 +817,6 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
if (!chapters[i].isRead!) { if (!chapters[i].isRead!) {
chapters[i].isRead = true; chapters[i].isRead = true;
chapters[i].lastPageRead = "1"; chapters[i].lastPageRead = "1";
ref
.read(changedItemsManagerProvider(
managerId: 1)
.notifier)
.addUpdatedChapter(
chapters[i], false, false);
isar.chapters.putSync(chapters[i] isar.chapters.putSync(chapters[i]
..manga.value = widget.manga); ..manga.value = widget.manga);
chapters[i].manga.saveSync(); chapters[i].manga.saveSync();

View file

@ -5,7 +5,6 @@ import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/manga.dart'; import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart'; import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/modules/manga/download/providers/download_provider.dart'; import 'package:mangayomi/modules/manga/download/providers/download_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'state_providers.g.dart'; part 'state_providers.g.dart';
@ -310,9 +309,6 @@ class ChapterSetIsBookmarkState extends _$ChapterSetIsBookmarkState {
isar.writeTxnSync(() { isar.writeTxnSync(() {
for (var chapter in chapters) { for (var chapter in chapters) {
chapter.isBookmarked = !chapter.isBookmarked!; chapter.isBookmarked = !chapter.isBookmarked!;
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(chapter, false, false);
isar.chapters.putSync(chapter..manga.value = manga); isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync(); chapter.manga.saveSync();
} }
@ -332,9 +328,6 @@ class ChapterSetIsReadState extends _$ChapterSetIsReadState {
isar.writeTxnSync(() { isar.writeTxnSync(() {
for (var chapter in chapters) { for (var chapter in chapters) {
chapter.isRead = !chapter.isRead!; chapter.isRead = !chapter.isRead!;
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(chapter, false, false);
isar.chapters.putSync(chapter..manga.value = manga); isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync(); chapter.manga.saveSync();
} }

View file

@ -816,7 +816,7 @@ class _ChapterFilterResultStateProviderElement
} }
String _$chapterSetIsBookmarkStateHash() => String _$chapterSetIsBookmarkStateHash() =>
r'48d4f203ba51616e9d1142e0dd482d3ae065a4f4'; r'113131bb13e50566390ee3e34aa2f08820a8870c';
abstract class _$ChapterSetIsBookmarkState abstract class _$ChapterSetIsBookmarkState
extends BuildlessAutoDisposeNotifier<void> { extends BuildlessAutoDisposeNotifier<void> {
@ -963,7 +963,7 @@ class _ChapterSetIsBookmarkStateProviderElement
} }
String _$chapterSetIsReadStateHash() => String _$chapterSetIsReadStateHash() =>
r'1e219dd68898fc30b6cb64d294377776516775d4'; r'c319f81ec30565ad81a28cb0a8ce7fddcb47cd77';
abstract class _$ChapterSetIsReadState abstract class _$ChapterSetIsReadState
extends BuildlessAutoDisposeNotifier<void> { extends BuildlessAutoDisposeNotifier<void> {

View file

@ -4,7 +4,6 @@ import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart'; import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/update.dart'; import 'package:mangayomi/models/update.dart';
import 'package:mangayomi/models/manga.dart'; import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/services/get_detail.dart'; import 'package:mangayomi/services/get_detail.dart';
import 'package:mangayomi/utils/utils.dart'; import 'package:mangayomi/utils/utils.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
@ -80,9 +79,6 @@ Future<dynamic> updateMangaDetail(Ref ref,
} }
if (chapters.isNotEmpty) { if (chapters.isNotEmpty) {
for (var chap in chapters.reversed.toList()) { for (var chap in chapters.reversed.toList()) {
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(chap, false, false);
isar.chapters.putSync(chap); isar.chapters.putSync(chap);
chap.manga.saveSync(); chap.manga.saveSync();
if (manga.chapters.isNotEmpty) { if (manga.chapters.isNotEmpty) {
@ -108,9 +104,6 @@ Future<dynamic> updateMangaDetail(Ref ref,
newChap.name == oldChap.name) { newChap.name == oldChap.name) {
oldChap.url = newChap.url; oldChap.url = newChap.url;
oldChap.scanlator = newChap.scanlator; oldChap.scanlator = newChap.scanlator;
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(oldChap, false, false);
isar.chapters.putSync(oldChap); isar.chapters.putSync(oldChap);
oldChap.manga.saveSync(); oldChap.manga.saveSync();
} }

View file

@ -6,7 +6,7 @@ part of 'update_manga_detail_providers.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$updateMangaDetailHash() => r'a058dcca7f99974e89fce2aa7f048edf1a0f7854'; String _$updateMangaDetailHash() => r'57330e79e3d1afcd9db5e8e0587bbc23d1e02379';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -11,9 +11,7 @@ import 'package:mangayomi/models/track.dart';
import 'package:mangayomi/models/track_preference.dart'; import 'package:mangayomi/models/track_preference.dart';
import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart'; import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart';
import 'package:mangayomi/modules/more/providers/incognito_mode_state_provider.dart'; import 'package:mangayomi/modules/more/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/more/settings/track/providers/track_providers.dart'; import 'package:mangayomi/modules/more/settings/track/providers/track_providers.dart';
import 'package:mangayomi/services/sync_server.dart';
import 'package:mangayomi/utils/chapter_recognition.dart'; import 'package:mangayomi/utils/chapter_recognition.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'reader_controller_provider.g.dart'; part 'reader_controller_provider.g.dart';
@ -189,22 +187,12 @@ class ReaderController extends _$ReaderController {
}); });
} }
void checkAndSyncProgress() {
final syncAfterReading = ref.watch(syncAfterReadingStateProvider);
if (syncAfterReading) {
ref.read(syncServerProvider(syncId: 1).notifier).checkForSync(true);
}
}
void setChapterBookmarked() { void setChapterBookmarked() {
if (incognitoMode) return; if (incognitoMode) return;
final isBookmarked = getChapterBookmarked(); final isBookmarked = getChapterBookmarked();
final chap = chapter; final chap = chapter;
isar.writeTxnSync(() { isar.writeTxnSync(() {
chap.isBookmarked = !isBookmarked; chap.isBookmarked = !isBookmarked;
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(chap, false, false);
isar.chapters.putSync(chap); isar.chapters.putSync(chap);
}); });
} }
@ -342,9 +330,6 @@ class ReaderController extends _$ReaderController {
getIsarSetting()..chapterPageIndexList = chapterPageIndexs); getIsarSetting()..chapterPageIndexList = chapterPageIndexs);
chap.isRead = isRead; chap.isRead = isRead;
chap.lastPageRead = isRead ? '1' : (newIndex + 1).toString(); chap.lastPageRead = isRead ? '1' : (newIndex + 1).toString();
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(chap, false, false);
isar.chapters.putSync(chap); isar.chapters.putSync(chap);
}); });
if (isRead) { if (isRead) {

View file

@ -171,7 +171,7 @@ class _CurrentIndexProviderElement
Chapter get chapter => (origin as CurrentIndexProvider).chapter; Chapter get chapter => (origin as CurrentIndexProvider).chapter;
} }
String _$readerControllerHash() => r'6576f3506dc5ef309f870de3e5c6e92efe03eefd'; String _$readerControllerHash() => r'471617bf6fa730d837c8e0d9504bde17cfb635a8';
abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> { abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> {
late final Chapter chapter; late final Chapter chapter;

View file

@ -143,7 +143,6 @@ class _MangaChapterPageGalleryState
@override @override
void dispose() { void dispose() {
_readerController.setMangaHistoryUpdate(); _readerController.setMangaHistoryUpdate();
_readerController.checkAndSyncProgress();
_readerController.setPageIndex( _readerController.setPageIndex(
_geCurrentIndex(_uChapDataPreload[_currentIndex!].index!), true); _geCurrentIndex(_uChapDataPreload[_currentIndex!].index!), true);
_rebuildDetail.close(); _rebuildDetail.close();

View file

@ -4,7 +4,6 @@ import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart'; import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart'; import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart'; import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/utils/date.dart'; import 'package:mangayomi/utils/date.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart'; import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
import 'package:super_sliver_list/super_sliver_list.dart'; import 'package:super_sliver_list/super_sliver_list.dart';
@ -160,8 +159,6 @@ class _ChapterListTileState extends State<ChapterListTile> {
isBookmarked = !isBookmarked; isBookmarked = !isBookmarked;
}); });
isar.writeTxnSync(() => { isar.writeTxnSync(() => {
addUpdatedChapterIndependentProvider.call(
chapter, false, false),
isar.chapters.putSync(chapter..isBookmarked = isBookmarked), isar.chapters.putSync(chapter..isBookmarked = isBookmarked),
}); });
}, },

View file

@ -5,7 +5,6 @@ import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/manga.dart'; import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/modules/more/categories/providers/isar_providers.dart'; import 'package:mangayomi/modules/more/categories/providers/isar_providers.dart';
import 'package:mangayomi/modules/more/categories/widgets/custom_textfield.dart'; import 'package:mangayomi/modules/more/categories/widgets/custom_textfield.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/widgets/progress_center.dart'; import 'package:mangayomi/modules/widgets/progress_center.dart';
import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/providers/l10n_providers.dart';
@ -183,15 +182,6 @@ class _CategoriesTabState extends ConsumerState<CategoriesTab> {
onPressed: () async { onPressed: () async {
await isar.writeTxn( await isar.writeTxn(
() async { () async {
await ref
.read(changedItemsManagerProvider(
managerId:
1)
.notifier)
.addDeletedCategoryAsync(
_entries[
index],
false);
await isar await isar
.categorys .categorys
.delete(_entries[ .delete(_entries[

View file

@ -1,210 +1,8 @@
import 'dart:convert';
import 'dart:developer';
import 'package:mangayomi/main.dart'; import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/changed_items.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/sync_preference.dart'; import 'package:mangayomi/models/sync_preference.dart';
import 'package:mangayomi/services/sync_server.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
part 'sync_providers.g.dart'; part 'sync_providers.g.dart';
@riverpod
void addUpdatedChapterIndependent(
Ref ref, Chapter chapter, bool deleted, bool txn) {
final changedItems = isar.changedItems.getSync(1) ?? ChangedItems();
bool updated = false;
changedItems.updatedChapters = changedItems.updatedChapters?.map((e) {
if (e.chapterId == chapter.id) {
e.isBookmarked = chapter.isBookmarked;
e.isRead = chapter.isRead;
e.lastPageRead = chapter.lastPageRead;
e.deleted = deleted;
updated = true;
}
return e;
}).toList();
if (!updated) {
final updatedChapter = UpdatedChapter(
chapterId: chapter.id,
isBookmarked: chapter.isBookmarked,
isRead: chapter.isRead,
lastPageRead: chapter.lastPageRead,
deleted: deleted);
changedItems.updatedChapters = changedItems.updatedChapters?.toList()
?..add(updatedChapter);
}
if (!txn) {
isar.changedItems.putSync(changedItems);
} else {
isar.writeTxnSync(() {
isar.changedItems.putSync(changedItems);
});
}
}
@riverpod
void checkForSyncIndependent(Ref ref, bool silent) {
ref.read(SyncServerProvider(syncId: 1).notifier).checkForSync(silent);
}
@riverpod
class ChangedItemsManager extends _$ChangedItemsManager {
@override
ChangedItems? build({required int? managerId}) {
return isar.changedItems.getSync(managerId!);
}
void cleanChangedItems(bool txn) {
final changedItems =
isar.changedItems.getSync(managerId!) ?? ChangedItems(id: managerId);
changedItems.deletedMangas = [];
changedItems.updatedChapters = [];
changedItems.deletedCategories = [];
if (!txn) {
isar.changedItems.putSync(changedItems);
} else {
isar.writeTxnSync(() {
isar.changedItems.putSync(changedItems);
});
}
}
void addDeletedManga(Manga manga, bool txn) {
final changedItems =
isar.changedItems.getSync(managerId!) ?? ChangedItems(id: managerId);
log("DEBUG");
log(jsonEncode(changedItems));
final deletedManga = DeletedManga(mangaId: manga.id);
changedItems.deletedMangas = changedItems.deletedMangas?.toList()
?..add(deletedManga);
if (!txn) {
isar.changedItems.putSync(changedItems);
} else {
isar.writeTxnSync(() {
isar.changedItems.putSync(changedItems);
});
}
}
Future addDeletedMangaAsync(Manga manga, bool txn) async {
final changedItems =
await isar.changedItems.get(managerId!) ?? ChangedItems(id: managerId);
final deletedManga = DeletedManga(mangaId: manga.id);
changedItems.deletedMangas = changedItems.deletedMangas?.toList()
?..add(deletedManga);
if (!txn) {
await isar.changedItems.put(changedItems);
} else {
await isar.writeTxn(() async {
await isar.changedItems.put(changedItems);
});
}
}
void addUpdatedChapter(Chapter chapter, bool deleted, bool txn) {
final changedItems =
isar.changedItems.getSync(managerId!) ?? ChangedItems(id: managerId);
bool updated = false;
changedItems.updatedChapters = changedItems.updatedChapters?.map((e) {
if (e.chapterId == chapter.id && e.mangaId == chapter.mangaId) {
e.isBookmarked = chapter.isBookmarked;
e.isRead = chapter.isRead;
e.lastPageRead = chapter.lastPageRead;
e.deleted = deleted;
updated = true;
}
return e;
}).toList();
if (!updated) {
final updatedChapter = UpdatedChapter(
chapterId: chapter.id,
mangaId: chapter.mangaId,
isBookmarked: chapter.isBookmarked,
isRead: chapter.isRead,
lastPageRead: chapter.lastPageRead,
deleted: deleted);
changedItems.updatedChapters = changedItems.updatedChapters?.toList()
?..add(updatedChapter);
}
if (!txn) {
isar.changedItems.putSync(changedItems);
} else {
isar.writeTxnSync(() {
isar.changedItems.putSync(changedItems);
});
}
}
Future addUpdatedChapterAsync(Chapter chapter, bool deleted, bool txn) async {
final changedItems =
await isar.changedItems.get(managerId!) ?? ChangedItems(id: managerId);
bool updated = false;
changedItems.updatedChapters = changedItems.updatedChapters?.map((e) {
if (e.chapterId == chapter.id && e.mangaId == chapter.mangaId) {
e.isBookmarked = chapter.isBookmarked;
e.isRead = chapter.isRead;
e.lastPageRead = chapter.lastPageRead;
e.deleted = deleted;
updated = true;
}
return e;
}).toList();
if (!updated) {
final updatedChapter = UpdatedChapter(
chapterId: chapter.id,
mangaId: chapter.mangaId,
isBookmarked: chapter.isBookmarked,
isRead: chapter.isRead,
lastPageRead: chapter.lastPageRead,
deleted: deleted);
changedItems.updatedChapters = changedItems.updatedChapters?.toList()
?..add(updatedChapter);
}
if (!txn) {
await isar.changedItems.put(changedItems);
} else {
await isar.writeTxn(() async {
await isar.changedItems.put(changedItems);
});
}
}
void addDeletedCategory(Category category, bool txn) {
final changedItems =
isar.changedItems.getSync(managerId!) ?? ChangedItems(id: managerId);
final deletedCategory = DeletedCategory(categoryId: category.id);
changedItems.deletedCategories = changedItems.deletedCategories?.toList()
?..add(deletedCategory);
if (!txn) {
isar.changedItems.putSync(changedItems);
} else {
isar.writeTxnSync(() {
isar.changedItems.putSync(changedItems);
});
}
}
Future addDeletedCategoryAsync(Category category, bool txn) async {
final changedItems =
await isar.changedItems.get(managerId!) ?? ChangedItems(id: managerId);
final deletedCategory = DeletedCategory(categoryId: category.id);
changedItems.deletedCategories = changedItems.deletedCategories?.toList()
?..add(deletedCategory);
if (!txn) {
await isar.changedItems.put(changedItems);
} else {
await isar.writeTxn(() async {
await isar.changedItems.put(changedItems);
});
}
}
}
@riverpod @riverpod
class Synching extends _$Synching { class Synching extends _$Synching {
@override @override
@ -224,13 +22,6 @@ class Synching extends _$Synching {
}); });
} }
void setLastSync(int timestamp) {
isar.writeTxnSync(() {
isar.syncPreferences.putSync(
isar.syncPreferences.getSync(syncId!)!..lastSync = timestamp);
});
}
void setLastUpload(int timestamp) { void setLastUpload(int timestamp) {
isar.writeTxnSync(() { isar.writeTxnSync(() {
isar.syncPreferences.putSync( isar.syncPreferences.putSync(
@ -252,33 +43,3 @@ class Synching extends _$Synching {
}); });
} }
} }
@riverpod
class SyncOnAppLaunchState extends _$SyncOnAppLaunchState {
@override
bool build() {
return isar.settings.getSync(227)!.syncOnAppLaunch ?? false;
}
void set(bool value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(
() => isar.settings.putSync(settings!..syncOnAppLaunch = value));
}
}
@riverpod
class SyncAfterReadingState extends _$SyncAfterReadingState {
@override
bool build() {
return isar.settings.getSync(227)!.syncAfterReading ?? false;
}
void set(bool value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(
() => isar.settings.putSync(settings!..syncAfterReading = value));
}
}

View file

@ -6,8 +6,7 @@ part of 'sync_providers.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$addUpdatedChapterIndependentHash() => String _$synchingHash() => r'3ab44d9e753f2d4b51fd10af6c98ffac78cbf201';
r'7abb8f085a229ec0573c730234fa4fc4ff86d794';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {
@ -30,450 +29,6 @@ class _SystemHash {
} }
} }
/// See also [addUpdatedChapterIndependent].
@ProviderFor(addUpdatedChapterIndependent)
const addUpdatedChapterIndependentProvider =
AddUpdatedChapterIndependentFamily();
/// See also [addUpdatedChapterIndependent].
class AddUpdatedChapterIndependentFamily extends Family<void> {
/// See also [addUpdatedChapterIndependent].
const AddUpdatedChapterIndependentFamily();
/// See also [addUpdatedChapterIndependent].
AddUpdatedChapterIndependentProvider call(
Chapter chapter,
bool deleted,
bool txn,
) {
return AddUpdatedChapterIndependentProvider(
chapter,
deleted,
txn,
);
}
@override
AddUpdatedChapterIndependentProvider getProviderOverride(
covariant AddUpdatedChapterIndependentProvider provider,
) {
return call(
provider.chapter,
provider.deleted,
provider.txn,
);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'addUpdatedChapterIndependentProvider';
}
/// See also [addUpdatedChapterIndependent].
class AddUpdatedChapterIndependentProvider extends AutoDisposeProvider<void> {
/// See also [addUpdatedChapterIndependent].
AddUpdatedChapterIndependentProvider(
Chapter chapter,
bool deleted,
bool txn,
) : this._internal(
(ref) => addUpdatedChapterIndependent(
ref as AddUpdatedChapterIndependentRef,
chapter,
deleted,
txn,
),
from: addUpdatedChapterIndependentProvider,
name: r'addUpdatedChapterIndependentProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$addUpdatedChapterIndependentHash,
dependencies: AddUpdatedChapterIndependentFamily._dependencies,
allTransitiveDependencies:
AddUpdatedChapterIndependentFamily._allTransitiveDependencies,
chapter: chapter,
deleted: deleted,
txn: txn,
);
AddUpdatedChapterIndependentProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.chapter,
required this.deleted,
required this.txn,
}) : super.internal();
final Chapter chapter;
final bool deleted;
final bool txn;
@override
Override overrideWith(
void Function(AddUpdatedChapterIndependentRef provider) create,
) {
return ProviderOverride(
origin: this,
override: AddUpdatedChapterIndependentProvider._internal(
(ref) => create(ref as AddUpdatedChapterIndependentRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
chapter: chapter,
deleted: deleted,
txn: txn,
),
);
}
@override
AutoDisposeProviderElement<void> createElement() {
return _AddUpdatedChapterIndependentProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is AddUpdatedChapterIndependentProvider &&
other.chapter == chapter &&
other.deleted == deleted &&
other.txn == txn;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, chapter.hashCode);
hash = _SystemHash.combine(hash, deleted.hashCode);
hash = _SystemHash.combine(hash, txn.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin AddUpdatedChapterIndependentRef on AutoDisposeProviderRef<void> {
/// The parameter `chapter` of this provider.
Chapter get chapter;
/// The parameter `deleted` of this provider.
bool get deleted;
/// The parameter `txn` of this provider.
bool get txn;
}
class _AddUpdatedChapterIndependentProviderElement
extends AutoDisposeProviderElement<void>
with AddUpdatedChapterIndependentRef {
_AddUpdatedChapterIndependentProviderElement(super.provider);
@override
Chapter get chapter =>
(origin as AddUpdatedChapterIndependentProvider).chapter;
@override
bool get deleted => (origin as AddUpdatedChapterIndependentProvider).deleted;
@override
bool get txn => (origin as AddUpdatedChapterIndependentProvider).txn;
}
String _$checkForSyncIndependentHash() =>
r'3a3658a67cd6cb210e76126b33592bd1ea67e3f0';
/// See also [checkForSyncIndependent].
@ProviderFor(checkForSyncIndependent)
const checkForSyncIndependentProvider = CheckForSyncIndependentFamily();
/// See also [checkForSyncIndependent].
class CheckForSyncIndependentFamily extends Family<void> {
/// See also [checkForSyncIndependent].
const CheckForSyncIndependentFamily();
/// See also [checkForSyncIndependent].
CheckForSyncIndependentProvider call(
bool silent,
) {
return CheckForSyncIndependentProvider(
silent,
);
}
@override
CheckForSyncIndependentProvider getProviderOverride(
covariant CheckForSyncIndependentProvider provider,
) {
return call(
provider.silent,
);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'checkForSyncIndependentProvider';
}
/// See also [checkForSyncIndependent].
class CheckForSyncIndependentProvider extends AutoDisposeProvider<void> {
/// See also [checkForSyncIndependent].
CheckForSyncIndependentProvider(
bool silent,
) : this._internal(
(ref) => checkForSyncIndependent(
ref as CheckForSyncIndependentRef,
silent,
),
from: checkForSyncIndependentProvider,
name: r'checkForSyncIndependentProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$checkForSyncIndependentHash,
dependencies: CheckForSyncIndependentFamily._dependencies,
allTransitiveDependencies:
CheckForSyncIndependentFamily._allTransitiveDependencies,
silent: silent,
);
CheckForSyncIndependentProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.silent,
}) : super.internal();
final bool silent;
@override
Override overrideWith(
void Function(CheckForSyncIndependentRef provider) create,
) {
return ProviderOverride(
origin: this,
override: CheckForSyncIndependentProvider._internal(
(ref) => create(ref as CheckForSyncIndependentRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
silent: silent,
),
);
}
@override
AutoDisposeProviderElement<void> createElement() {
return _CheckForSyncIndependentProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is CheckForSyncIndependentProvider && other.silent == silent;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, silent.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin CheckForSyncIndependentRef on AutoDisposeProviderRef<void> {
/// The parameter `silent` of this provider.
bool get silent;
}
class _CheckForSyncIndependentProviderElement
extends AutoDisposeProviderElement<void> with CheckForSyncIndependentRef {
_CheckForSyncIndependentProviderElement(super.provider);
@override
bool get silent => (origin as CheckForSyncIndependentProvider).silent;
}
String _$changedItemsManagerHash() =>
r'a4f0363ab430ddb6c2a23fde6f5671ba8ec252cf';
abstract class _$ChangedItemsManager
extends BuildlessAutoDisposeNotifier<ChangedItems?> {
late final int? managerId;
ChangedItems? build({
required int? managerId,
});
}
/// See also [ChangedItemsManager].
@ProviderFor(ChangedItemsManager)
const changedItemsManagerProvider = ChangedItemsManagerFamily();
/// See also [ChangedItemsManager].
class ChangedItemsManagerFamily extends Family<ChangedItems?> {
/// See also [ChangedItemsManager].
const ChangedItemsManagerFamily();
/// See also [ChangedItemsManager].
ChangedItemsManagerProvider call({
required int? managerId,
}) {
return ChangedItemsManagerProvider(
managerId: managerId,
);
}
@override
ChangedItemsManagerProvider getProviderOverride(
covariant ChangedItemsManagerProvider provider,
) {
return call(
managerId: provider.managerId,
);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'changedItemsManagerProvider';
}
/// See also [ChangedItemsManager].
class ChangedItemsManagerProvider extends AutoDisposeNotifierProviderImpl<
ChangedItemsManager, ChangedItems?> {
/// See also [ChangedItemsManager].
ChangedItemsManagerProvider({
required int? managerId,
}) : this._internal(
() => ChangedItemsManager()..managerId = managerId,
from: changedItemsManagerProvider,
name: r'changedItemsManagerProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$changedItemsManagerHash,
dependencies: ChangedItemsManagerFamily._dependencies,
allTransitiveDependencies:
ChangedItemsManagerFamily._allTransitiveDependencies,
managerId: managerId,
);
ChangedItemsManagerProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.managerId,
}) : super.internal();
final int? managerId;
@override
ChangedItems? runNotifierBuild(
covariant ChangedItemsManager notifier,
) {
return notifier.build(
managerId: managerId,
);
}
@override
Override overrideWith(ChangedItemsManager Function() create) {
return ProviderOverride(
origin: this,
override: ChangedItemsManagerProvider._internal(
() => create()..managerId = managerId,
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
managerId: managerId,
),
);
}
@override
AutoDisposeNotifierProviderElement<ChangedItemsManager, ChangedItems?>
createElement() {
return _ChangedItemsManagerProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is ChangedItemsManagerProvider && other.managerId == managerId;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, managerId.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin ChangedItemsManagerRef on AutoDisposeNotifierProviderRef<ChangedItems?> {
/// The parameter `managerId` of this provider.
int? get managerId;
}
class _ChangedItemsManagerProviderElement
extends AutoDisposeNotifierProviderElement<ChangedItemsManager,
ChangedItems?> with ChangedItemsManagerRef {
_ChangedItemsManagerProviderElement(super.provider);
@override
int? get managerId => (origin as ChangedItemsManagerProvider).managerId;
}
String _$synchingHash() => r'2ef7fd99da4292ed236252d2b727cff9a69f43a9';
abstract class _$Synching abstract class _$Synching
extends BuildlessAutoDisposeNotifier<SyncPreference?> { extends BuildlessAutoDisposeNotifier<SyncPreference?> {
late final int? syncId; late final int? syncId;
@ -616,40 +171,5 @@ class _SynchingProviderElement
@override @override
int? get syncId => (origin as SynchingProvider).syncId; int? get syncId => (origin as SynchingProvider).syncId;
} }
String _$syncOnAppLaunchStateHash() =>
r'dc7f3243e38a748462628229066c8fc0653c908b';
/// See also [SyncOnAppLaunchState].
@ProviderFor(SyncOnAppLaunchState)
final syncOnAppLaunchStateProvider =
AutoDisposeNotifierProvider<SyncOnAppLaunchState, bool>.internal(
SyncOnAppLaunchState.new,
name: r'syncOnAppLaunchStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$syncOnAppLaunchStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$SyncOnAppLaunchState = AutoDisposeNotifier<bool>;
String _$syncAfterReadingStateHash() =>
r'e507acd490b5aea7fc1a8fd7a369ec01f4c47192';
/// See also [SyncAfterReadingState].
@ProviderFor(SyncAfterReadingState)
final syncAfterReadingStateProvider =
AutoDisposeNotifierProvider<SyncAfterReadingState, bool>.internal(
SyncAfterReadingState.new,
name: r'syncAfterReadingStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$syncAfterReadingStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$SyncAfterReadingState = AutoDisposeNotifier<bool>;
// ignore_for_file: type=lint // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

View file

@ -4,7 +4,6 @@ import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart'; import 'package:mangayomi/main.dart';
import 'package:mangayomi/utils/date.dart'; import 'package:mangayomi/utils/date.dart';
import 'package:mangayomi/models/sync_preference.dart'; import 'package:mangayomi/models/sync_preference.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/more/settings/sync/widgets/sync_listile.dart'; import 'package:mangayomi/modules/more/settings/sync/widgets/sync_listile.dart';
import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/services/sync_server.dart'; import 'package:mangayomi/services/sync_server.dart';
@ -15,8 +14,6 @@ class SyncScreen extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final syncAfterReading = ref.watch(syncAfterReadingStateProvider);
final syncOnAppLaunch = ref.watch(syncOnAppLaunchStateProvider);
final l10n = l10nLocalizations(context)!; final l10n = l10nLocalizations(context)!;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@ -36,26 +33,6 @@ class SyncScreen extends ConsumerWidget {
syncPreference.authToken?.isNotEmpty ?? false; syncPreference.authToken?.isNotEmpty ?? false;
return Column( return Column(
children: [ children: [
SwitchListTile(
value: syncAfterReading,
title: Text(context.l10n.syncAfterReading),
onChanged: !isLogged
? null
: (value) {
ref
.read(syncAfterReadingStateProvider.notifier)
.set(value);
}),
SwitchListTile(
value: syncOnAppLaunch,
title: Text(context.l10n.syncOnAppLaunch),
onChanged: !isLogged
? null
: (value) {
ref
.read(syncOnAppLaunchStateProvider.notifier)
.set(value);
}),
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 15, right: 15, bottom: 10, top: 5), left: 15, right: 15, bottom: 10, top: 5),
@ -103,12 +80,6 @@ class SyncScreen extends ConsumerWidget {
const SizedBox(width: 10), const SizedBox(width: 10),
Column(children: [ Column(children: [
const SizedBox(width: 20), const SizedBox(width: 20),
Text(
"${l10n.last_sync}: ${dateFormat((syncPreference.lastSync ?? 0).toString(), ref: ref, context: context)} ${dateFormatHour((syncPreference.lastSync ?? 0).toString(), context)}",
style: TextStyle(
fontSize: 11,
color: context.secondaryColor)),
const SizedBox(width: 20),
Text( Text(
"${l10n.last_upload}: ${dateFormat((syncPreference.lastUpload ?? 0).toString(), ref: ref, context: context)} ${dateFormatHour((syncPreference.lastUpload ?? 0).toString(), context)}", "${l10n.last_upload}: ${dateFormat((syncPreference.lastUpload ?? 0).toString(), ref: ref, context: context)} ${dateFormatHour((syncPreference.lastUpload ?? 0).toString(), context)}",
style: TextStyle( style: TextStyle(
@ -127,27 +98,6 @@ class SyncScreen extends ConsumerWidget {
), ),
Row( Row(
children: [ children: [
const SizedBox(width: 20),
Column(
children: [
IconButton(
onPressed: !isLogged
? null
: () {
ref
.read(syncServerProvider(syncId: 1)
.notifier)
.checkForSync(false);
},
icon: Icon(
Icons.sync,
color: !isLogged
? context.secondaryColor
: context.primaryColor,
)),
Text(l10n.sync_button_sync),
],
),
const SizedBox(width: 20), const SizedBox(width: 20),
Column( Column(
children: [ children: [

View file

@ -10,9 +10,7 @@ import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/track.dart'; import 'package:mangayomi/models/track.dart';
import 'package:mangayomi/models/track_preference.dart'; import 'package:mangayomi/models/track_preference.dart';
import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart'; import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/more/settings/track/providers/track_providers.dart'; import 'package:mangayomi/modules/more/settings/track/providers/track_providers.dart';
import 'package:mangayomi/services/sync_server.dart';
import 'package:mangayomi/utils/chapter_recognition.dart'; import 'package:mangayomi/utils/chapter_recognition.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'novel_reader_controller_provider.g.dart'; part 'novel_reader_controller_provider.g.dart';
@ -81,10 +79,16 @@ class NovelReaderController extends _$NovelReaderController {
}); });
} }
void checkAndSyncProgress() { void setChapterOffset(double newOffset, double maxOffset, bool save) {
final syncAfterReading = ref.watch(syncAfterReadingStateProvider); if (incognitoMode) return;
if (syncAfterReading) { final isRead = (newOffset / (maxOffset != 0 ? maxOffset : 1)) >= 0.9;
ref.read(syncServerProvider(syncId: 1).notifier).checkForSync(true); if (isRead || save) {
final ch = chapter;
isar.writeTxnSync(() {
ch.isRead = isRead;
ch.lastPageRead = (maxOffset != 0 ? newOffset / maxOffset : 0).toString();
isar.chapters.putSync(ch);
});
} }
} }
@ -94,9 +98,6 @@ class NovelReaderController extends _$NovelReaderController {
final chap = chapter; final chap = chapter;
isar.writeTxnSync(() { isar.writeTxnSync(() {
chap.isBookmarked = !isBookmarked; chap.isBookmarked = !isBookmarked;
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.addUpdatedChapter(chap, false, false);
isar.chapters.putSync(chap); isar.chapters.putSync(chap);
}); });
} }

View file

@ -7,7 +7,7 @@ part of 'novel_reader_controller_provider.dart';
// ************************************************************************** // **************************************************************************
String _$novelReaderControllerHash() => String _$novelReaderControllerHash() =>
r'74ebbf38d60283d308646b59cfd5cfee07c85535'; r'9ac937ab7fcc82a99088128f0f12f1aaad7fa1e8';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -64,12 +64,28 @@ class _NovelWebViewState extends ConsumerState<NovelWebView>
with TickerProviderStateMixin { with TickerProviderStateMixin {
late final NovelReaderController _readerController = late final NovelReaderController _readerController =
ref.read(novelReaderControllerProvider(chapter: chapter).notifier); ref.read(novelReaderControllerProvider(chapter: chapter).notifier);
final _scrollController = ScrollController(
initialScrollOffset: 0,
keepScrollOffset: true,
);
bool scrolled = false;
double offset = 0;
double maxOffset = 0;
bool isDesktop = Platform.isMacOS || Platform.isLinux || Platform.isWindows; bool isDesktop = Platform.isMacOS || Platform.isLinux || Platform.isWindows;
void onScroll() {
if (_scrollController.hasClients) {
offset = _scrollController.offset;
maxOffset = _scrollController.position.maxScrollExtent;
}
}
@override @override
void dispose() { void dispose() {
_readerController.setChapterOffset(offset, maxOffset, true);
_readerController.setMangaHistoryUpdate(); _readerController.setMangaHistoryUpdate();
_readerController.checkAndSyncProgress(); _scrollController.removeListener(onScroll);
_scrollController.dispose();
_rebuildDetail.close(); _rebuildDetail.close();
clearGestureDetailsCache(); clearGestureDetailsCache();
if (isDesktop) { if (isDesktop) {
@ -88,6 +104,9 @@ class _NovelWebViewState extends ConsumerState<NovelWebView>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollController.addListener(onScroll);
});
} }
late bool _isBookmarked = _readerController.getChapterBookmarked(); late bool _isBookmarked = _readerController.getChapterBookmarked();
@ -113,7 +132,6 @@ class _NovelWebViewState extends ConsumerState<NovelWebView>
Widget build(BuildContext context) { Widget build(BuildContext context) {
final backgroundColor = ref.watch(backgroundColorStateProvider); final backgroundColor = ref.watch(backgroundColorStateProvider);
final fullScreenReader = ref.watch(fullScreenReaderStateProvider); final fullScreenReader = ref.watch(fullScreenReaderStateProvider);
final l10n = l10nLocalizations(context)!;
return KeyboardListener( return KeyboardListener(
autofocus: true, autofocus: true,
focusNode: FocusNode(), focusNode: FocusNode(),
@ -183,39 +201,92 @@ class _NovelWebViewState extends ConsumerState<NovelWebView>
children: [ children: [
widget.htmlContent.when( widget.htmlContent.when(
data: (htmlContent) { data: (htmlContent) {
Future.delayed(const Duration(milliseconds: 1000),
() {
if (!scrolled && _scrollController.hasClients) {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent *
(double.tryParse(chapter.lastPageRead!) ??
0),
duration: Duration(seconds: 2),
curve: Curves.fastOutSlowIn);
scrolled = true;
}
});
return Expanded( return Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
physics: const BouncingScrollPhysics(), controller: _scrollController,
child: HtmlWidget( physics: const BouncingScrollPhysics(),
htmlContent, child: Column(
customStylesBuilder: (element) { children: [
switch (backgroundColor) { HtmlWidget(
case BackgroundColor.black: htmlContent,
return { customStylesBuilder: (element) {
'background-color': 'black', switch (backgroundColor) {
}; case BackgroundColor.black:
default: return {
return { 'background-color': 'black',
'background-color': '#F0F0F0', };
}; default:
} return {
}, 'background-color': '#F0F0F0',
onTapUrl: (url) { };
print('tapped $url'); }
return true; },
}, onTapUrl: (url) {
renderMode: RenderMode.column, context.push("/mangawebview",
textStyle: TextStyle( extra: {'url': url, 'title': url});
color: backgroundColor == return true;
BackgroundColor.white },
? Colors.black renderMode: RenderMode.column,
: Colors.white, textStyle: TextStyle(
//fontFamily: "Times New Roman", color: backgroundColor ==
//fontFamilyFallback: ["Times", "serif"], BackgroundColor.white
fontSize: 14), ? Colors.black
), : Colors.white,
fontSize: 14),
),
Center(
child: IconButton(
padding: const EdgeInsets.all(5),
onPressed: () =>
pushReplacementMangaReaderView(
context: context,
chapter:
_readerController.getPrevChapter(),
),
icon: Icon(
Icons.arrow_back,
color: backgroundColor ==
BackgroundColor.white
? Colors.black
: Colors.white,
),
),
),
Center(
child: IconButton(
padding: const EdgeInsets.all(5),
onPressed: () =>
pushReplacementMangaReaderView(
context: context,
chapter:
_readerController.getNextChapter(),
),
icon: Icon(
Icons.arrow_forward,
color: backgroundColor ==
BackgroundColor.white
? Colors.black
: Colors.white,
),
),
),
],
), ),
);}, ),
);
},
loading: () => const Expanded( loading: () => const Expanded(
child: Center( child: Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),

View file

@ -4,7 +4,6 @@ import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/source_preference.dart'; import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/main.dart'; import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart'; import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/changed_items.dart';
import 'package:mangayomi/models/chapter.dart'; import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart'; import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/update.dart'; import 'package:mangayomi/models/update.dart';
@ -147,7 +146,6 @@ class StorageProvider {
final isar = Isar.openSync([ final isar = Isar.openSync([
MangaSchema, MangaSchema,
ChangedItemsSchema,
ChapterSchema, ChapterSchema,
CategorySchema, CategorySchema,
UpdateSchema, UpdateSchema,

View file

@ -23,5 +23,5 @@ Future<String> getHtmlContent(Ref ref, {required Chapter chapter}) async {
return '''<div id="readerViewContent"><div style="padding: 2em;">${html.substring(1, html.length - 1)}</div></div>''' return '''<div id="readerViewContent"><div style="padding: 2em;">${html.substring(1, html.length - 1)}</div></div>'''
.replaceAll("\\n", "") .replaceAll("\\n", "")
.replaceAll("\\t", "") .replaceAll("\\t", "")
.replaceAll("\\", ""); .replaceAll("\\\"", "\"");
} }

View file

@ -6,7 +6,7 @@ part of 'get_html_content.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$getHtmlContentHash() => r'5369236d1d8058cd42a832d1d641a37777da653b'; String _$getHtmlContentHash() => r'0c964239912b7f93bfb4c80a47f7266ff1ae3f5e';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -1,9 +1,7 @@
import 'package:crypto/crypto.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_bridge.dart'; import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/model/source_preference.dart'; import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/main.dart'; import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed_items.dart';
import 'package:mangayomi/models/update.dart'; import 'package:mangayomi/models/update.dart';
import 'package:mangayomi/models/sync_preference.dart'; import 'package:mangayomi/models/sync_preference.dart';
import 'package:mangayomi/models/track.dart'; import 'package:mangayomi/models/track.dart';
@ -30,8 +28,6 @@ part 'sync_server.g.dart';
class SyncServer extends _$SyncServer { class SyncServer extends _$SyncServer {
final http = MClient.init(reqcopyWith: {'useDartHttpClient': true}); final http = MClient.init(reqcopyWith: {'useDartHttpClient': true});
final String _loginUrl = '/login'; final String _loginUrl = '/login';
final String _checkUrl = '/check';
final String _syncUrl = '/sync';
final String _uploadUrl = '/upload/full'; final String _uploadUrl = '/upload/full';
final String _downloadUrl = '/download'; final String _downloadUrl = '/download';
@ -67,78 +63,6 @@ class SyncServer extends _$SyncServer {
} }
} }
Future<void> checkForSync(bool silent) async {
if (!silent) {
botToast("Checking for sync...", second: 2);
}
try {
final datas = _getData();
final accessToken = _getAccessToken();
final localHash = _getDataHash(datas);
var response = await http.get(
Uri.parse('${_getServer()}$_checkUrl'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken'
},
);
if (response.statusCode != 200) {
botToast("Check failed", second: 5);
return;
}
var jsonData = jsonDecode(response.body) as Map<String, dynamic>;
final remoteHash = jsonData["hash"];
if (localHash != remoteHash) {
syncToServer(silent);
} else if (!silent) {
botToast("Sync up to date", second: 2);
}
} catch (error) {
botToast(error.toString(), second: 5);
}
}
Future<void> syncToServer(bool silent) async {
if (!silent) {
botToast("Sync started...", second: 2);
}
try {
final datas = _getData();
final accessToken = _getAccessToken();
var response = await http.post(
Uri.parse('${_getServer()}$_syncUrl'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken'
},
body: jsonEncode(
{'backupData': datas, 'changedItems': _getChangedData()}),
);
if (response.statusCode != 200) {
botToast("Sync failed", second: 5);
return;
}
var jsonData = jsonDecode(response.body) as Map<String, dynamic>;
final decodedBackupData = jsonData["backupData"] is String
? jsonDecode(jsonData["backupData"])
: jsonData["backupData"];
_restoreMerge(decodedBackupData);
ref
.read(synchingProvider(syncId: syncId).notifier)
.setLastSync(DateTime.now().millisecondsSinceEpoch);
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.cleanChangedItems(true);
if (!silent) {
botToast("Sync finished", second: 2);
}
} catch (error) {
botToast(error.toString(), second: 5);
}
}
Future<void> uploadToServer(AppLocalizations l10n) async { Future<void> uploadToServer(AppLocalizations l10n) async {
botToast(l10n.sync_uploading, second: 2); botToast(l10n.sync_uploading, second: 2);
try { try {
@ -160,9 +84,6 @@ class SyncServer extends _$SyncServer {
ref ref
.read(synchingProvider(syncId: syncId).notifier) .read(synchingProvider(syncId: syncId).notifier)
.setLastUpload(DateTime.now().millisecondsSinceEpoch); .setLastUpload(DateTime.now().millisecondsSinceEpoch);
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.cleanChangedItems(true);
botToast(l10n.sync_upload_finished, second: 2); botToast(l10n.sync_upload_finished, second: 2);
} catch (error) { } catch (error) {
botToast(error.toString(), second: 5); botToast(error.toString(), second: 5);
@ -192,49 +113,12 @@ class SyncServer extends _$SyncServer {
ref ref
.read(synchingProvider(syncId: syncId).notifier) .read(synchingProvider(syncId: syncId).notifier)
.setLastDownload(DateTime.now().millisecondsSinceEpoch); .setLastDownload(DateTime.now().millisecondsSinceEpoch);
ref
.read(changedItemsManagerProvider(managerId: 1).notifier)
.cleanChangedItems(true);
botToast(l10n.sync_download_finished, second: 2); botToast(l10n.sync_download_finished, second: 2);
} catch (error) { } catch (error) {
botToast(error.toString(), second: 5); botToast(error.toString(), second: 5);
} }
} }
String _getDataHash(Map<String, dynamic> data) {
Map<String, dynamic> datas = {};
datas["version"] = data["version"];
datas["manga"] = data["manga"];
datas["categories"] = data["categories"];
datas["chapters"] = data["chapters"];
datas["tracks"] = data["tracks"];
datas["history"] = data["history"];
datas["updates"] = data["updates"];
var encodedJson = jsonEncode(datas);
return sha256.convert(utf8.encode(encodedJson)).toString();
}
Map<String, dynamic> _getChangedData() {
Map<String, dynamic> data = {};
final changedItems = isar.changedItems.getSync(1);
if (changedItems != null) {
data.addAll({
"deletedMangas":
changedItems.deletedMangas?.map((e) => e.toJson()).toList() ?? []
});
data.addAll({
"updatedChapters":
changedItems.updatedChapters?.map((e) => e.toJson()).toList() ?? []
});
data.addAll({
"deletedCategories":
changedItems.deletedCategories?.map((e) => e.toJson()).toList() ??
[]
});
}
return data;
}
Map<String, dynamic> _getData() { Map<String, dynamic> _getData() {
Map<String, dynamic> datas = {}; Map<String, dynamic> datas = {};
datas.addAll({"version": "1"}); datas.addAll({"version": "1"});
@ -309,93 +193,6 @@ class SyncServer extends _$SyncServer {
return datas; return datas;
} }
void _restoreMerge(Map<String, dynamic> backup) {
if (backup['version'] == "1") {
try {
final manga =
(backup["manga"] as List?)?.map((e) => Manga.fromJson(e)).toList();
final chapters = (backup["chapters"] as List?)
?.map((e) => Chapter.fromJson(e))
.toList();
final categories = (backup["categories"] as List?)
?.map((e) => Category.fromJson(e))
.toList();
final track =
(backup["tracks"] as List?)?.map((e) => Track.fromJson(e)).toList();
final history = (backup["history"] as List?)
?.map((e) => History.fromJson(e))
.toList();
final updates = (backup["updates"] as List?)
?.map((e) => Update.fromJson(e))
.toList();
isar.writeTxnSync(() {
isar.mangas.clearSync();
if (manga != null) {
isar.mangas.putAllSync(manga);
if (chapters != null) {
isar.chapters.clearSync();
for (var chapter in chapters) {
final manga = isar.mangas.getSync(chapter.mangaId!);
if (manga != null) {
isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync();
}
}
isar.historys.clearSync();
if (history != null) {
for (var element in history) {
final chapter = isar.chapters.getSync(element.chapterId!);
if (chapter != null) {
isar.historys.putSync(element..chapter.value = chapter);
element.chapter.saveSync();
}
}
}
isar.updates.clearSync();
if (updates != null) {
final tempChapters =
isar.chapters.filter().idIsNotNull().findAllSync().toList();
for (var update in updates) {
final matchingChapter = tempChapters
.where((chapter) =>
chapter.mangaId == update.mangaId &&
chapter.name == update.chapterName)
.firstOrNull;
if (matchingChapter != null) {
isar.updates
.putSync(update..chapter.value = matchingChapter);
update.chapter.saveSync();
}
}
}
}
isar.categorys.clearSync();
if (categories != null) {
isar.categorys.putAllSync(categories);
}
}
isar.tracks.clearSync();
if (track != null) {
isar.tracks.putAllSync(track);
}
ref.invalidate(themeModeStateProvider);
ref.invalidate(blendLevelStateProvider);
ref.invalidate(flexSchemeColorStateProvider);
ref.invalidate(pureBlackDarkModeStateProvider);
ref.invalidate(l10nLocaleStateProvider);
});
} catch (e) {
botToast(e.toString());
}
}
}
void _restore(Map<String, dynamic> backup) { void _restore(Map<String, dynamic> backup) {
if (backup['version'] == "1") { if (backup['version'] == "1") {
try { try {
@ -489,8 +286,6 @@ class SyncServer extends _$SyncServer {
if (extensionsPref != null) { if (extensionsPref != null) {
isar.sourcePreferences.putAllSync(extensionsPref); isar.sourcePreferences.putAllSync(extensionsPref);
} }
final syncAfterReading = isar.settings.getSync(227)!.syncAfterReading;
final syncOnAppLaunch = isar.settings.getSync(227)!.syncOnAppLaunch;
isar.settings.clearSync(); isar.settings.clearSync();
if (settings != null) { if (settings != null) {
isar.settings.putAllSync(settings); isar.settings.putAllSync(settings);
@ -498,10 +293,6 @@ class SyncServer extends _$SyncServer {
if (isar.settings.getSync(227) == null) { if (isar.settings.getSync(227) == null) {
isar.settings.putSync(Settings(id: 227)); isar.settings.putSync(Settings(id: 227));
} }
isar.settings.putSync(
isar.settings.getSync(227)!..syncAfterReading = syncAfterReading);
isar.settings.putSync(
isar.settings.getSync(227)!..syncOnAppLaunch = syncOnAppLaunch);
ref.invalidate(themeModeStateProvider); ref.invalidate(themeModeStateProvider);
ref.invalidate(blendLevelStateProvider); ref.invalidate(blendLevelStateProvider);
ref.invalidate(flexSchemeColorStateProvider); ref.invalidate(flexSchemeColorStateProvider);

View file

@ -6,7 +6,7 @@ part of 'sync_server.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$syncServerHash() => r'99e16d503937f2973f00c0cf2e834a03cf4aa245'; String _$syncServerHash() => r'db0f27093c2e76d4158b7af7960359c54c9a00b2';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {