From 3f4d427babd4f608e156b084be4a864ce356b771 Mon Sep 17 00:00:00 2001 From: kodjomoustapha <107993382+kodjodevf@users.noreply.github.com> Date: Wed, 6 Dec 2023 15:12:15 +0100 Subject: [PATCH] fix --- lib/models/settings.dart | 4 +- lib/models/settings.g.dart | 12 +- .../browse/extension/extension_detail.dart | 300 ++++----- .../browse/extension/extension_screen.dart | 271 ++++---- .../providers/extensions_provider.dart | 26 + .../providers/extensions_provider.g.dart | 178 +++++ .../widgets/source_preference_widget.dart | 386 +++++------ .../providers/library_state_provider.dart | 8 +- .../backup_and_restore.dart | 632 +++++++++--------- 9 files changed, 1007 insertions(+), 810 deletions(-) create mode 100644 lib/modules/browse/extension/providers/extensions_provider.dart create mode 100644 lib/modules/browse/extension/providers/extensions_provider.g.dart diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 9fa3caac..b42573c2 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -310,7 +310,7 @@ class Settings { sortLibraryManga = json['sortLibraryManga'] != null ? SortLibraryManga.fromJson(json['sortLibraryManga']) : null; - if (json['sortChapterList'] != null) { + if (json['autoScrollPages'] != null) { autoScrollPages = (json['autoScrollPages'] as List) .map((e) => AutoScrollPages.fromJson(e)) .toList(); @@ -396,7 +396,7 @@ class Settings { 'showPagesNumber': showPagesNumber, if (sortChapterList != null) 'sortChapterList': sortChapterList!.map((v) => v.toJson()).toList(), - if (sortChapterList != null) + if (autoScrollPages != null) 'autoScrollPages': autoScrollPages!.map((v) => v.toJson()).toList(), 'sortLibraryAnime': sortLibraryAnime, if (sortLibraryManga != null) diff --git a/lib/models/settings.g.dart b/lib/models/settings.g.dart index 046137ef..8f6e935b 100644 --- a/lib/models/settings.g.dart +++ b/lib/models/settings.g.dart @@ -769,6 +769,12 @@ Settings _settingsDeserialize( animeLibraryShowNumbersOfItems: reader.readBoolOrNull(offsets[7]), autoBackupLocation: reader.readStringOrNull(offsets[8]), autoExtensionsUpdates: reader.readBoolOrNull(offsets[9]), + autoScrollPages: reader.readObjectList( + offsets[10], + AutoScrollPagesSchema.deserialize, + allOffsets, + AutoScrollPages(), + ), backgroundColor: _SettingsbackgroundColorValueEnumMap[ reader.readByteOrNull(offsets[11])] ?? BackgroundColor.black, @@ -871,12 +877,6 @@ Settings _settingsDeserialize( usePageTapZones: reader.readBoolOrNull(offsets[62]), userAgent: reader.readStringOrNull(offsets[63]), ); - object.autoScrollPages = reader.readObjectList( - offsets[10], - AutoScrollPagesSchema.deserialize, - allOffsets, - AutoScrollPages(), - ); object.chapterFilterBookmarkedList = reader.readObjectList( offsets[14], diff --git a/lib/modules/browse/extension/extension_detail.dart b/lib/modules/browse/extension/extension_detail.dart index a5516f41..6d90229c 100644 --- a/lib/modules/browse/extension/extension_detail.dart +++ b/lib/modules/browse/extension/extension_detail.dart @@ -34,161 +34,163 @@ class _ExtensionDetailState extends ConsumerState { appBar: AppBar( title: Text(l10n.extension_detail), ), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.only(top: 20), - child: Container( - decoration: BoxDecoration( - color: - Theme.of(context).secondaryHeaderColor.withOpacity(0.5), - borderRadius: BorderRadius.circular(10)), - child: widget.source.iconUrl!.isEmpty - ? const Icon(Icons.source_outlined, size: 140) - : CachedNetworkImage( - imageUrl: widget.source.iconUrl!, - fit: BoxFit.contain, - width: 140, - height: 140, - errorWidget: (context, url, error) { - return const SizedBox( - width: 140, - height: 140, - child: Center( - child: Icon(Icons.source_outlined, size: 140), - ), - ); - }, - ), + body: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 20), + child: Container( + decoration: BoxDecoration( + color: + Theme.of(context).secondaryHeaderColor.withOpacity(0.5), + borderRadius: BorderRadius.circular(10)), + child: widget.source.iconUrl!.isEmpty + ? const Icon(Icons.source_outlined, size: 140) + : CachedNetworkImage( + imageUrl: widget.source.iconUrl!, + fit: BoxFit.contain, + width: 140, + height: 140, + errorWidget: (context, url, error) { + return const SizedBox( + width: 140, + height: 140, + child: Center( + child: Icon(Icons.source_outlined, size: 140), + ), + ); + }, + ), + ), ), - ), - Padding( - padding: const EdgeInsets.all(12), - child: Text( - widget.source.name!, - style: const TextStyle(fontSize: 23, fontWeight: FontWeight.bold), - textAlign: TextAlign.center, + Padding( + padding: const EdgeInsets.all(12), + child: Text( + widget.source.name!, + style: const TextStyle(fontSize: 23, fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + ), ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Container( - decoration: BoxDecoration( - color: primaryColor(context).withOpacity(0.2), - borderRadius: BorderRadius.circular(10)), - child: Padding( - padding: const EdgeInsets.all(20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - children: [ - Text( - widget.source.version!, - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold), - ), - Text( - l10n.version, - style: const TextStyle(fontSize: 11), - ), - ], - ), - if (widget.source.isNsfw!) - Container( - decoration: BoxDecoration( - color: Colors.red.withOpacity(0.7), - borderRadius: BorderRadius.circular(5)), - child: const Padding( - padding: EdgeInsets.all(8.0), - child: Text( - "NSFW (18+)", - style: TextStyle( - fontWeight: FontWeight.bold, - color: Colors.white), - ), - )), - Column( - children: [ - Text( - completeLanguageName(widget.source.lang!), - style: const TextStyle( - fontSize: 16, fontWeight: FontWeight.bold), - ), - Text( - l10n.language, - style: const TextStyle(fontSize: 11), - ), - ], - ), - ], + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + decoration: BoxDecoration( + color: primaryColor(context).withOpacity(0.2), + borderRadius: BorderRadius.circular(10)), + child: Padding( + padding: const EdgeInsets.all(20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + children: [ + Text( + widget.source.version!, + style: const TextStyle( + fontSize: 16, fontWeight: FontWeight.bold), + ), + Text( + l10n.version, + style: const TextStyle(fontSize: 11), + ), + ], + ), + if (widget.source.isNsfw!) + Container( + decoration: BoxDecoration( + color: Colors.red.withOpacity(0.7), + borderRadius: BorderRadius.circular(5)), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Text( + "NSFW (18+)", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white), + ), + )), + Column( + children: [ + Text( + completeLanguageName(widget.source.lang!), + style: const TextStyle( + fontSize: 16, fontWeight: FontWeight.bold), + ), + Text( + l10n.language, + style: const TextStyle(fontSize: 11), + ), + ], + ), + ], + ), ), ), ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: SizedBox( - width: mediaWidth(context, 1), - child: ElevatedButton( - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.all(0), - side: - BorderSide(color: primaryColor(context), width: 0.3), - backgroundColor: Colors.transparent, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5)), - elevation: 0, - shadowColor: Colors.transparent), - onPressed: () { - showDialog( - context: context, - builder: (ctx) { - return AlertDialog( - title: Text( - widget.source.name!, - ), - content: Text( - l10n.uninstall_extension(widget.source.name!)), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () { - Navigator.pop(ctx); - }, - child: Text(l10n.cancel)), - const SizedBox( - width: 15, - ), - TextButton( - onPressed: () { - isar.writeTxnSync(() => - isar.sources.putSync(widget.source - ..sourceCode = "" - ..isAdded = false - ..isPinned = false)); - Navigator.pop(ctx); - Navigator.pop(context); - }, - child: Text(l10n.ok)), - ], - ) - ], - ); - }); - }, - child: Text( - l10n.uninstall, - style: const TextStyle( - fontSize: 20, fontWeight: FontWeight.bold), - )), + Padding( + padding: const EdgeInsets.all(8.0), + child: SizedBox( + width: mediaWidth(context, 1), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.all(0), + side: + BorderSide(color: primaryColor(context), width: 0.3), + backgroundColor: Colors.transparent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5)), + elevation: 0, + shadowColor: Colors.transparent), + onPressed: () { + showDialog( + context: context, + builder: (ctx) { + return AlertDialog( + title: Text( + widget.source.name!, + ), + content: Text( + l10n.uninstall_extension(widget.source.name!)), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () { + Navigator.pop(ctx); + }, + child: Text(l10n.cancel)), + const SizedBox( + width: 15, + ), + TextButton( + onPressed: () { + isar.writeTxnSync(() => + isar.sources.putSync(widget.source + ..sourceCode = "" + ..isAdded = false + ..isPinned = false)); + Navigator.pop(ctx); + Navigator.pop(context); + }, + child: Text(l10n.ok)), + ], + ) + ], + ); + }); + }, + child: Text( + l10n.uninstall, + style: const TextStyle( + fontSize: 20, fontWeight: FontWeight.bold), + )), + ), ), - ), - SourcePreferenceWidget( - sourcePreference: sourcePreference, source: source) - ], + SourcePreferenceWidget( + sourcePreference: sourcePreference, source: source) + ], + ), ), ); } diff --git a/lib/modules/browse/extension/extension_screen.dart b/lib/modules/browse/extension/extension_screen.dart index 94f0deea..87d5d4d8 100644 --- a/lib/modules/browse/extension/extension_screen.dart +++ b/lib/modules/browse/extension/extension_screen.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:grouped_list/grouped_list.dart'; -import 'package:isar/isar.dart'; -import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/source.dart'; +import 'package:mangayomi/modules/browse/extension/providers/extensions_provider.dart'; import 'package:mangayomi/modules/browse/extension/providers/fetch_anime_sources.dart'; import 'package:mangayomi/modules/browse/extension/providers/fetch_manga_sources.dart'; +import 'package:mangayomi/modules/widgets/error_text.dart'; +import 'package:mangayomi/modules/widgets/progress_center.dart'; import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/sources/source_test.dart'; import 'package:mangayomi/utils/language.dart'; @@ -20,6 +21,8 @@ class ExtensionScreen extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final streamExtensions = + ref.watch(getExtensionsStreamProvider(isManga: isManga, query: query)); if (isManga) { ref.watch(fetchMangaSourcesListProvider(id: null, reFresh: false)); } else { @@ -34,155 +37,135 @@ class ExtensionScreen extends ConsumerWidget { fetchAnimeSourcesListProvider(id: null, reFresh: true).future), child: Padding( padding: const EdgeInsets.only(top: 10), - child: StreamBuilder( - stream: query.isNotEmpty - ? isar.sources - .filter() - .nameContains(query.toLowerCase(), caseSensitive: false) - .idIsNotNull() - .and() - .isActiveEqualTo(true) - .isMangaEqualTo(isManga) - .watch(fireImmediately: true) - : isar.sources - .filter() - .idIsNotNull() - .and() - .isActiveEqualTo(true) - .isMangaEqualTo(isManga) - .watch(fireImmediately: true), - builder: (context, snapshot) { - if (snapshot.hasData && snapshot.data!.isNotEmpty) { - final entries1 = snapshot.data! - .where((element) => ref.watch(showNSFWStateProvider) - ? true - : element.isNsfw == false) - .where((element) => element.version == element.versionLast!) - .where((element) => !element.isAdded!) - .toList(); - final entries2 = snapshot.data! - .where((element) => ref.watch(showNSFWStateProvider) - ? true - : element.isNsfw == false) - .where((element) => element.version == element.versionLast!) - .where((element) => element.isAdded!) - .toList(); - final entries = snapshot.data! - .where((element) => ref.watch(showNSFWStateProvider) - ? true - : element.isNsfw == false) - .where((element) => - compareVersions( - element.version!, element.versionLast!) < - 0) - .toList(); - return SingleChildScrollView( - child: Column( - children: [ - if (useTestSourceCode) - ExtensionListTileWidget( - source: testSourceModel, - isTestSource: useTestSourceCode), - GroupedListView( - elements: entries, - groupBy: (element) => "", - groupSeparatorBuilder: (_) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - l10n.update_pending, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 13), - ), - ElevatedButton( - onPressed: () async { - for (var source in entries) { - source.isManga! - ? await ref.watch( - fetchMangaSourcesListProvider( - id: source.id, - reFresh: true) - .future) - : await ref.watch( - fetchAnimeSourcesListProvider( - id: source.id, - reFresh: true) - .future); - } - }, - child: Text(l10n.update_all)) - ], - ), - ), - itemBuilder: (context, Source element) { - return ExtensionListTileWidget( - source: element, - ); - }, - groupComparator: (group1, group2) => - group1.compareTo(group2), - shrinkWrap: true, - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - order: GroupedListOrder.ASC, - ), - GroupedListView( - elements: entries2, - groupBy: (element) => "", - groupSeparatorBuilder: (_) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Text( - l10n.installed, + child: streamExtensions.when( + data: (data) { + final entries1 = data + .where((element) => ref.watch(showNSFWStateProvider) + ? true + : element.isNsfw == false) + .where((element) => element.version == element.versionLast!) + .where((element) => !element.isAdded!) + .toList(); + final entries2 = data + .where((element) => ref.watch(showNSFWStateProvider) + ? true + : element.isNsfw == false) + .where((element) => element.version == element.versionLast!) + .where((element) => element.isAdded!) + .toList(); + final entries = data + .where((element) => ref.watch(showNSFWStateProvider) + ? true + : element.isNsfw == false) + .where((element) => + compareVersions(element.version!, element.versionLast!) < 0) + .toList(); + return SingleChildScrollView( + child: Column( + children: [ + if (useTestSourceCode) + ExtensionListTileWidget( + source: testSourceModel, + isTestSource: useTestSourceCode), + GroupedListView( + elements: entries, + groupBy: (element) => "", + groupSeparatorBuilder: (_) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + l10n.update_pending, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 13), ), - ), - itemBuilder: (context, Source element) { - return ExtensionListTileWidget(source: element); - }, - groupComparator: (group1, group2) => - group1.compareTo(group2), - shrinkWrap: true, - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - order: GroupedListOrder.ASC, + ElevatedButton( + onPressed: () async { + for (var source in entries) { + source.isManga! + ? await ref.watch( + fetchMangaSourcesListProvider( + id: source.id, reFresh: true) + .future) + : await ref.watch( + fetchAnimeSourcesListProvider( + id: source.id, reFresh: true) + .future); + } + }, + child: Text(l10n.update_all)) + ], + ), + ), + itemBuilder: (context, Source element) { + return ExtensionListTileWidget( + source: element, + ); + }, + groupComparator: (group1, group2) => + group1.compareTo(group2), + shrinkWrap: true, + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + order: GroupedListOrder.ASC, + ), + GroupedListView( + elements: entries2, + groupBy: (element) => "", + groupSeparatorBuilder: (_) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Text( + l10n.installed, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 13), ), - GroupedListView( - elements: entries1, - groupBy: (element) => - completeLanguageName(element.lang!.toLowerCase()), - groupSeparatorBuilder: (String groupByValue) => Padding( - padding: const EdgeInsets.only(left: 12), - child: Row( - children: [ - Text( - groupByValue, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 13), - ), - ], + ), + itemBuilder: (context, Source element) { + return ExtensionListTileWidget(source: element); + }, + groupComparator: (group1, group2) => + group1.compareTo(group2), + shrinkWrap: true, + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + order: GroupedListOrder.ASC, + ), + GroupedListView( + elements: entries1, + groupBy: (element) => + completeLanguageName(element.lang!.toLowerCase()), + groupSeparatorBuilder: (String groupByValue) => Padding( + padding: const EdgeInsets.only(left: 12), + child: Row( + children: [ + Text( + groupByValue, + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 13), ), - ), - itemBuilder: (context, Source element) { - return ExtensionListTileWidget( - source: element, - ); - }, - groupComparator: (group1, group2) => - group1.compareTo(group2), - itemComparator: (item1, item2) => - item1.name!.compareTo(item2.name!), - shrinkWrap: true, - order: GroupedListOrder.ASC, + ], ), - ], + ), + itemBuilder: (context, Source element) { + return ExtensionListTileWidget( + source: element, + ); + }, + groupComparator: (group1, group2) => + group1.compareTo(group2), + itemComparator: (item1, item2) => + item1.name!.compareTo(item2.name!), + shrinkWrap: true, + order: GroupedListOrder.ASC, ), - ); - } - return Container(); - }), + ], + ), + ); + }, + error: (error, stackTrace) => ErrorText(error), + loading: () => const ProgressCenter(), + ), ), ); } diff --git a/lib/modules/browse/extension/providers/extensions_provider.dart b/lib/modules/browse/extension/providers/extensions_provider.dart new file mode 100644 index 00000000..efaab544 --- /dev/null +++ b/lib/modules/browse/extension/providers/extensions_provider.dart @@ -0,0 +1,26 @@ +import 'package:isar/isar.dart'; +import 'package:mangayomi/main.dart'; +import 'package:mangayomi/models/source.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +part 'extensions_provider.g.dart'; + +@riverpod +Stream> getExtensionsStream(GetExtensionsStreamRef ref, + {required String query, required bool? isManga}) async* { + yield* query.isNotEmpty + ? isar.sources + .filter() + .nameContains(query.toLowerCase(), caseSensitive: false) + .idIsNotNull() + .and() + .isActiveEqualTo(true) + .isMangaEqualTo(isManga) + .watch(fireImmediately: true) + : isar.sources + .filter() + .idIsNotNull() + .and() + .isActiveEqualTo(true) + .isMangaEqualTo(isManga) + .watch(fireImmediately: true); +} diff --git a/lib/modules/browse/extension/providers/extensions_provider.g.dart b/lib/modules/browse/extension/providers/extensions_provider.g.dart new file mode 100644 index 00000000..c3eebc8e --- /dev/null +++ b/lib/modules/browse/extension/providers/extensions_provider.g.dart @@ -0,0 +1,178 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'extensions_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$getExtensionsStreamHash() => + r'2f3ed044cd49c1b08587196c27d727ed9d815468'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +/// See also [getExtensionsStream]. +@ProviderFor(getExtensionsStream) +const getExtensionsStreamProvider = GetExtensionsStreamFamily(); + +/// See also [getExtensionsStream]. +class GetExtensionsStreamFamily extends Family>> { + /// See also [getExtensionsStream]. + const GetExtensionsStreamFamily(); + + /// See also [getExtensionsStream]. + GetExtensionsStreamProvider call({ + required String query, + required bool? isManga, + }) { + return GetExtensionsStreamProvider( + query: query, + isManga: isManga, + ); + } + + @override + GetExtensionsStreamProvider getProviderOverride( + covariant GetExtensionsStreamProvider provider, + ) { + return call( + query: provider.query, + isManga: provider.isManga, + ); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'getExtensionsStreamProvider'; +} + +/// See also [getExtensionsStream]. +class GetExtensionsStreamProvider + extends AutoDisposeStreamProvider> { + /// See also [getExtensionsStream]. + GetExtensionsStreamProvider({ + required String query, + required bool? isManga, + }) : this._internal( + (ref) => getExtensionsStream( + ref as GetExtensionsStreamRef, + query: query, + isManga: isManga, + ), + from: getExtensionsStreamProvider, + name: r'getExtensionsStreamProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') + ? null + : _$getExtensionsStreamHash, + dependencies: GetExtensionsStreamFamily._dependencies, + allTransitiveDependencies: + GetExtensionsStreamFamily._allTransitiveDependencies, + query: query, + isManga: isManga, + ); + + GetExtensionsStreamProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.query, + required this.isManga, + }) : super.internal(); + + final String query; + final bool? isManga; + + @override + Override overrideWith( + Stream> Function(GetExtensionsStreamRef provider) create, + ) { + return ProviderOverride( + origin: this, + override: GetExtensionsStreamProvider._internal( + (ref) => create(ref as GetExtensionsStreamRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + query: query, + isManga: isManga, + ), + ); + } + + @override + AutoDisposeStreamProviderElement> createElement() { + return _GetExtensionsStreamProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is GetExtensionsStreamProvider && + other.query == query && + other.isManga == isManga; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, query.hashCode); + hash = _SystemHash.combine(hash, isManga.hashCode); + + return _SystemHash.finish(hash); + } +} + +mixin GetExtensionsStreamRef on AutoDisposeStreamProviderRef> { + /// The parameter `query` of this provider. + String get query; + + /// The parameter `isManga` of this provider. + bool? get isManga; +} + +class _GetExtensionsStreamProviderElement + extends AutoDisposeStreamProviderElement> + with GetExtensionsStreamRef { + _GetExtensionsStreamProviderElement(super.provider); + + @override + String get query => (origin as GetExtensionsStreamProvider).query; + @override + bool? get isManga => (origin as GetExtensionsStreamProvider).isManga; +} +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/lib/modules/browse/extension/widgets/source_preference_widget.dart b/lib/modules/browse/extension/widgets/source_preference_widget.dart index 36a1915e..1721fa35 100644 --- a/lib/modules/browse/extension/widgets/source_preference_widget.dart +++ b/lib/modules/browse/extension/widgets/source_preference_widget.dart @@ -20,205 +20,209 @@ class SourcePreferenceWidget extends StatefulWidget { class _SourcePreferenceWidgetState extends State { @override Widget build(BuildContext context) { - return ListView.builder( - shrinkWrap: true, - itemCount: widget.sourcePreference.length, - itemBuilder: (context, index) { - final preference = widget.sourcePreference[index]; - Widget? w; - if (preference.editTextPreference != null) { - final pref = preference.editTextPreference!; - w = ListTile( - title: Text(pref.title!), - subtitle: Text(pref.summary!, - style: - TextStyle(fontSize: 11, color: secondaryColor(context))), - onTap: () { - showDialog( - context: context, - builder: (context) => EditTextDialogWidget( - text: pref.value!, - onChanged: (value) { - setState(() { - pref.value = value; - }); - setPreferenceSetting(preference, widget.source); - }, - dialogTitle: pref.dialogTitle!, - dialogMessage: pref.dialogMessage!)); - }, - ); - } else if (preference.checkBoxPreference != null) { - final pref = preference.checkBoxPreference!; - w = CheckboxListTile( - title: Text(pref.title!), - subtitle: Text(pref.summary!, - style: - TextStyle(fontSize: 11, color: secondaryColor(context))), - value: pref.value, - onChanged: (value) { - setState(() { - pref.value = value; - }); - setPreferenceSetting(preference, widget.source); - }, - controlAffinity: ListTileControlAffinity.trailing, - ); - } else if (preference.switchPreferenceCompat != null) { - final pref = preference.switchPreferenceCompat!; - w = SwitchListTile( - title: Text(pref.title!), - subtitle: Text(pref.summary!, - style: - TextStyle(fontSize: 11, color: secondaryColor(context))), - value: pref.value!, - onChanged: (value) { - setState(() { - pref.value = value; - }); - setPreferenceSetting(preference, widget.source); - }, - controlAffinity: ListTileControlAffinity.trailing, - ); - } else if (preference.listPreference != null) { - final pref = preference.listPreference!; - w = ListTile( - title: Text(pref.title!), - subtitle: Text(pref.entries![pref.valueIndex!], - style: TextStyle( - fontSize: 11, color: secondaryColor(context))), - onTap: () async { - final res = await showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(pref.title!), - content: SizedBox( - width: mediaWidth(context, 0.8), - child: ListView.builder( - shrinkWrap: true, - itemCount: pref.entries!.length, - itemBuilder: (context, index) { - return RadioListTile( - dense: true, - contentPadding: const EdgeInsets.all(0), - value: index, - groupValue: pref.valueIndex, - onChanged: (value) { - Navigator.pop(context, index); - }, - title: Row( - children: [Text(pref.entries![index])], - ), - ); + return Column( + children: [ + for (var index = 0; index < widget.sourcePreference.length; index++) + Builder( + builder: (context) { + final preference = widget.sourcePreference[index]; + Widget? w; + if (preference.editTextPreference != null) { + final pref = preference.editTextPreference!; + w = ListTile( + title: Text(pref.title!), + subtitle: Text(pref.summary!, + style: TextStyle( + fontSize: 11, color: secondaryColor(context))), + onTap: () { + showDialog( + context: context, + builder: (context) => EditTextDialogWidget( + text: pref.value!, + onChanged: (value) { + setState(() { + pref.value = value; + }); + setPreferenceSetting(preference, widget.source); }, - )), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () async { - Navigator.pop(context); + dialogTitle: pref.dialogTitle!, + dialogMessage: pref.dialogMessage!)); + }, + ); + } else if (preference.checkBoxPreference != null) { + final pref = preference.checkBoxPreference!; + w = CheckboxListTile( + title: Text(pref.title!), + subtitle: Text(pref.summary!, + style: TextStyle( + fontSize: 11, color: secondaryColor(context))), + value: pref.value, + onChanged: (value) { + setState(() { + pref.value = value; + }); + setPreferenceSetting(preference, widget.source); + }, + controlAffinity: ListTileControlAffinity.trailing, + ); + } else if (preference.switchPreferenceCompat != null) { + final pref = preference.switchPreferenceCompat!; + w = SwitchListTile( + title: Text(pref.title!), + subtitle: Text(pref.summary!, + style: TextStyle( + fontSize: 11, color: secondaryColor(context))), + value: pref.value!, + onChanged: (value) { + setState(() { + pref.value = value; + }); + setPreferenceSetting(preference, widget.source); + }, + controlAffinity: ListTileControlAffinity.trailing, + ); + } else if (preference.listPreference != null) { + final pref = preference.listPreference!; + w = ListTile( + title: Text(pref.title!), + subtitle: Text(pref.entries![pref.valueIndex!], + style: TextStyle( + fontSize: 11, color: secondaryColor(context))), + onTap: () async { + final res = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(pref.title!), + content: SizedBox( + width: mediaWidth(context, 0.8), + child: ListView.builder( + shrinkWrap: true, + itemCount: pref.entries!.length, + itemBuilder: (context, index) { + return RadioListTile( + dense: true, + contentPadding: const EdgeInsets.all(0), + value: index, + groupValue: pref.valueIndex, + onChanged: (value) { + Navigator.pop(context, index); + }, + title: Row( + children: [Text(pref.entries![index])], + ), + ); }, - child: Text( - context.l10n.cancel, - style: - TextStyle(color: primaryColor(context)), - )), + )), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () async { + Navigator.pop(context); + }, + child: Text( + context.l10n.cancel, + style: TextStyle( + color: primaryColor(context)), + )), + ], + ) ], - ) - ], - ), - ); - if (res != null) { - setState(() { - pref.valueIndex = res; + ), + ); + if (res != null) { + setState(() { + pref.valueIndex = res; + }); + } + setPreferenceSetting(preference, widget.source); }); - } - setPreferenceSetting(preference, widget.source); - }); - } else if (preference.multiSelectListPreference != null) { - final pref = preference.multiSelectListPreference!; - w = ListTile( - title: Text(pref.title!), - subtitle: Text(pref.summary!, - style: TextStyle( - fontSize: 11, color: secondaryColor(context))), - onTap: () { - List indexList = []; - indexList.addAll(pref.values!); - showDialog( - context: context, - builder: (context) { - return StatefulBuilder( - builder: (context, setState) { - return AlertDialog( - title: Text(pref.title!), - content: SizedBox( - width: mediaWidth(context, 0.8), - child: ListView.builder( - shrinkWrap: true, - itemCount: pref.entries!.length, - itemBuilder: (context, index) { - return ListTileChapterFilter( - label: pref.entries![index], - type: indexList.contains( - pref.entryValues![index]) - ? 1 - : 0, - onTap: () { - if (indexList.contains( - pref.entryValues![index])) { - setState(() { - indexList.remove( - pref.entryValues![index]); - pref.values = indexList; - }); - } else { - setState(() { - indexList.add( - pref.entryValues![index]); - pref.values = indexList; + } else if (preference.multiSelectListPreference != null) { + final pref = preference.multiSelectListPreference!; + w = ListTile( + title: Text(pref.title!), + subtitle: Text(pref.summary!, + style: TextStyle( + fontSize: 11, color: secondaryColor(context))), + onTap: () { + List indexList = []; + indexList.addAll(pref.values!); + showDialog( + context: context, + builder: (context) { + return StatefulBuilder( + builder: (context, setState) { + return AlertDialog( + title: Text(pref.title!), + content: SizedBox( + width: mediaWidth(context, 0.8), + child: ListView.builder( + shrinkWrap: true, + itemCount: pref.entries!.length, + itemBuilder: (context, index) { + return ListTileChapterFilter( + label: pref.entries![index], + type: indexList.contains( + pref.entryValues![index]) + ? 1 + : 0, + onTap: () { + if (indexList.contains( + pref.entryValues![index])) { + setState(() { + indexList.remove(pref + .entryValues![index]); + pref.values = indexList; + }); + } else { + setState(() { + indexList.add(pref + .entryValues![index]); + pref.values = indexList; + }); + } + setPreferenceSetting( + preference, widget.source); }); - } - setPreferenceSetting( - preference, widget.source); - }); - }, - )), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () async { - Navigator.pop(context); }, - child: Text( - context.l10n.cancel, - style: TextStyle( - color: primaryColor(context)), - )), - TextButton( - onPressed: () async { - Navigator.pop(context); - }, - child: Text( - context.l10n.ok, - style: TextStyle( - color: primaryColor(context)), - )), + )), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () async { + Navigator.pop(context); + }, + child: Text( + context.l10n.cancel, + style: TextStyle( + color: primaryColor(context)), + )), + TextButton( + onPressed: () async { + Navigator.pop(context); + }, + child: Text( + context.l10n.ok, + style: TextStyle( + color: primaryColor(context)), + )), + ], + ) ], - ) - ], + ); + }, ); - }, - ); - }); - }); - } - return w ?? Container(); - }); + }); + }); + } + return w ?? Container(); + }, + ) + ], + ); } } diff --git a/lib/modules/library/providers/library_state_provider.dart b/lib/modules/library/providers/library_state_provider.dart index 35182392..a23ee1f2 100644 --- a/lib/modules/library/providers/library_state_provider.dart +++ b/lib/modules/library/providers/library_state_provider.dart @@ -36,15 +36,17 @@ class LibraryDisplayTypeState extends _$LibraryDisplayTypeState { } void setLibraryDisplayType(DisplayType displayType) { + Settings appSettings = Settings(); + state = displayType.name; if (isManga) { - settings = settings..displayType = displayType; + appSettings = settings..displayType = displayType; } else { - settings = settings..animeDisplayType = displayType; + appSettings = settings..animeDisplayType = displayType; } isar.writeTxnSync(() { - isar.settings.putSync(settings); + isar.settings.putSync(appSettings); }); } } diff --git a/lib/modules/more/backup_and_restore/backup_and_restore.dart b/lib/modules/more/backup_and_restore/backup_and_restore.dart index dcb85278..2edabeaa 100644 --- a/lib/modules/more/backup_and_restore/backup_and_restore.dart +++ b/lib/modules/more/backup_and_restore/backup_and_restore.dart @@ -26,335 +26,337 @@ class BackupAndRestore extends ConsumerWidget { appBar: AppBar( title: Text(l10n.backup_and_restore), ), - body: Column( - children: [ - ListTile( - onTap: () { - final list = _getList(context); - List indexList = []; - indexList.addAll(backupFrequencyOptions); - showDialog( - context: context, - builder: (context) { - return StatefulBuilder( - builder: (context, setState) { - return AlertDialog( - title: Text(l10n.create_backup_dialog_title), - content: SizedBox( - width: mediaWidth(context, 0.8), - child: ListView.builder( - shrinkWrap: true, - itemCount: list.length, - itemBuilder: (context, index) { - return ListTileChapterFilter( - label: list[index], - type: indexList.contains(index) ? 1 : 0, - onTap: () { - if (indexList.contains(index)) { - setState(() { - indexList.remove(index); - }); - } else { - setState(() { - indexList.add(index); - }); - } - }); - }, - )), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () async { - Navigator.pop(context); - }, - child: Text( - l10n.cancel, - style: TextStyle( - color: primaryColor(context)), - )), - TextButton( - onPressed: () async { - final result = await FilePicker.platform - .getDirectoryPath(); - - if (result != null && context.mounted) { - ref.watch(doBackUpProvider( - list: indexList, - path: result, - context: context)); - } - }, - child: Text( - l10n.ok, - style: TextStyle( - color: primaryColor(context)), - )), - ], - ) - ], - ); - }, - ); - }); - }, - title: Text(l10n.create_backup), - subtitle: Text( - l10n.create_backup_subtitle, - style: TextStyle(fontSize: 11, color: secondaryColor(context)), - ), - ), - ListTile( - onTap: () { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(l10n.restore_backup), - content: SizedBox( - width: mediaWidth(context, 0.8), - child: ListView( - shrinkWrap: true, - children: [ + body: SingleChildScrollView( + child: Column( + children: [ + ListTile( + onTap: () { + final list = _getList(context); + List indexList = []; + indexList.addAll(backupFrequencyOptions); + showDialog( + context: context, + builder: (context) { + return StatefulBuilder( + builder: (context, setState) { + return AlertDialog( + title: Text(l10n.create_backup_dialog_title), + content: SizedBox( + width: mediaWidth(context, 0.8), + child: ListView.builder( + shrinkWrap: true, + itemCount: list.length, + itemBuilder: (context, index) { + return ListTileChapterFilter( + label: list[index], + type: indexList.contains(index) ? 1 : 0, + onTap: () { + if (indexList.contains(index)) { + setState(() { + indexList.remove(index); + }); + } else { + setState(() { + indexList.add(index); + }); + } + }); + }, + )), + actions: [ Row( + mainAxisAlignment: MainAxisAlignment.end, children: [ - Icon(Icons.info_outline_rounded, - color: secondaryColor(context)), + TextButton( + onPressed: () async { + Navigator.pop(context); + }, + child: Text( + l10n.cancel, + style: TextStyle( + color: primaryColor(context)), + )), + TextButton( + onPressed: () async { + final result = await FilePicker.platform + .getDirectoryPath(); + + if (result != null && context.mounted) { + ref.watch(doBackUpProvider( + list: indexList, + path: result, + context: context)); + } + }, + child: Text( + l10n.ok, + style: TextStyle( + color: primaryColor(context)), + )), ], - ), - Padding( - padding: - const EdgeInsets.symmetric(vertical: 5), - child: Text(l10n.restore_backup_warning_title), - ), + ) ], - )), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () async { - Navigator.pop(context); - }, - child: Text( - l10n.cancel, - style: - TextStyle(color: primaryColor(context)), - )), - TextButton( - onPressed: () async { - try { - FilePickerResult? result = await FilePicker - .platform - .pickFiles(allowMultiple: false); - - if (result != null && context.mounted) { - ref.watch(doRestoreProvider( - path: result.files.first.path!, - context: context)); - } - if (!context.mounted) return; - Navigator.pop(context); - } catch (_) { - botToast("Error"); - Navigator.pop(context); - } - }, - child: Text( - l10n.ok, - style: - TextStyle(color: primaryColor(context)), - )), - ], - ) - ], - ); - }); - }, - title: Text(l10n.restore_backup), - subtitle: Text( - l10n.restore_backup_subtitle, - style: TextStyle(fontSize: 11, color: secondaryColor(context)), - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 20), - child: Row( - children: [ - Text(l10n.automatic_backups, - style: - TextStyle(fontSize: 13, color: primaryColor(context))), - ], - ), - ), - ListTile( - onTap: () { - showDialog( - context: context, - builder: (context) { - final list = _getBackupFrequencyList(context); - return AlertDialog( - title: Text(l10n.backup_frequency), - content: SizedBox( - width: mediaWidth(context, 0.8), - child: ListView.builder( - shrinkWrap: true, - itemCount: list.length, - itemBuilder: (context, index) { - return RadioListTile( - dense: true, - contentPadding: const EdgeInsets.all(0), - value: index, - groupValue: backupFrequency, - onChanged: (value) { - ref - .read( - backupFrequencyStateProvider.notifier) - .set(value!); - Navigator.pop(context); - }, - title: Row( - children: [Text(list[index])], - ), - ); - }, - )), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () async { - Navigator.pop(context); - }, - child: Text( - l10n.cancel, - style: - TextStyle(color: primaryColor(context)), - )), - ], - ) - ], - ); - }); - }, - title: Text(l10n.backup_frequency), - subtitle: Text( - _getBackupFrequencyList(context)[backupFrequency], - style: TextStyle(fontSize: 11, color: secondaryColor(context)), - ), - ), - // if (!isIOS) - ListTile( - onTap: () async { - String? result = await FilePicker.platform.getDirectoryPath(); - - if (result != null) { - ref.read(autoBackupLocationStateProvider.notifier).set(result); - } - }, - title: Text(l10n.backup_location), - subtitle: Text( - autoBackupLocation.$2.isEmpty - ? autoBackupLocation.$1 - : autoBackupLocation.$2, - style: TextStyle(fontSize: 11, color: secondaryColor(context)), + ); + }, + ); + }); + }, + title: Text(l10n.create_backup), + subtitle: Text( + l10n.create_backup_subtitle, + style: TextStyle(fontSize: 11, color: secondaryColor(context)), + ), ), - ), - ListTile( - onTap: () { - final list = _getList(context); - List indexList = []; - indexList.addAll(backupFrequencyOptions); - showDialog( - context: context, - builder: (context) { - return StatefulBuilder( - builder: (context, setState) { - return AlertDialog( - title: Text( - l10n.backup_options_subtile, - ), - content: SizedBox( - width: mediaWidth(context, 0.8), - child: ListView.builder( - shrinkWrap: true, - itemCount: list.length, - itemBuilder: (context, index) { - return ListTileChapterFilter( - label: list[index], - type: indexList.contains(index) ? 1 : 0, - onTap: () { - if (indexList.contains(index)) { - setState(() { - indexList.remove(index); - }); - } else { - setState(() { - indexList.add(index); - }); - } - }); - }, - )), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, + ListTile( + onTap: () { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(l10n.restore_backup), + content: SizedBox( + width: mediaWidth(context, 0.8), + child: ListView( + shrinkWrap: true, children: [ - TextButton( - onPressed: () async { + Row( + children: [ + Icon(Icons.info_outline_rounded, + color: secondaryColor(context)), + ], + ), + Padding( + padding: + const EdgeInsets.symmetric(vertical: 5), + child: Text(l10n.restore_backup_warning_title), + ), + ], + )), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () async { + Navigator.pop(context); + }, + child: Text( + l10n.cancel, + style: + TextStyle(color: primaryColor(context)), + )), + TextButton( + onPressed: () async { + try { + FilePickerResult? result = await FilePicker + .platform + .pickFiles(allowMultiple: false); + + if (result != null && context.mounted) { + ref.watch(doRestoreProvider( + path: result.files.first.path!, + context: context)); + } + if (!context.mounted) return; Navigator.pop(context); - }, - child: Text( - l10n.cancel, - style: TextStyle( - color: primaryColor(context)), - )), - TextButton( - onPressed: () async { - ref - .read( - backupFrequencyOptionsStateProvider - .notifier) - .set(indexList); + } catch (_) { + botToast("Error"); Navigator.pop(context); - }, - child: Text( - l10n.ok, - style: TextStyle( - color: primaryColor(context)), - )), - ], - ) - ], - ); - }, - ); - }); - }, - title: Text(l10n.backup_options), - subtitle: Text( - l10n.backup_options_subtile, - style: TextStyle(fontSize: 11, color: secondaryColor(context)), + } + }, + child: Text( + l10n.ok, + style: + TextStyle(color: primaryColor(context)), + )), + ], + ) + ], + ); + }); + }, + title: Text(l10n.restore_backup), + subtitle: Text( + l10n.restore_backup_subtitle, + style: TextStyle(fontSize: 11, color: secondaryColor(context)), + ), ), - ), - ListTile( - title: Padding( - padding: const EdgeInsets.only(bottom: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 20), child: Row( children: [ - Icon(Icons.info_outline_rounded, - color: secondaryColor(context)), + Text(l10n.automatic_backups, + style: + TextStyle(fontSize: 13, color: primaryColor(context))), ], ), ), - subtitle: Text(l10n.backup_and_restore_warning_info, - style: TextStyle(fontSize: 11, color: secondaryColor(context))), - ) - ], + ListTile( + onTap: () { + showDialog( + context: context, + builder: (context) { + final list = _getBackupFrequencyList(context); + return AlertDialog( + title: Text(l10n.backup_frequency), + content: SizedBox( + width: mediaWidth(context, 0.8), + child: ListView.builder( + shrinkWrap: true, + itemCount: list.length, + itemBuilder: (context, index) { + return RadioListTile( + dense: true, + contentPadding: const EdgeInsets.all(0), + value: index, + groupValue: backupFrequency, + onChanged: (value) { + ref + .read( + backupFrequencyStateProvider.notifier) + .set(value!); + Navigator.pop(context); + }, + title: Row( + children: [Text(list[index])], + ), + ); + }, + )), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () async { + Navigator.pop(context); + }, + child: Text( + l10n.cancel, + style: + TextStyle(color: primaryColor(context)), + )), + ], + ) + ], + ); + }); + }, + title: Text(l10n.backup_frequency), + subtitle: Text( + _getBackupFrequencyList(context)[backupFrequency], + style: TextStyle(fontSize: 11, color: secondaryColor(context)), + ), + ), + // if (!isIOS) + ListTile( + onTap: () async { + String? result = await FilePicker.platform.getDirectoryPath(); + + if (result != null) { + ref.read(autoBackupLocationStateProvider.notifier).set(result); + } + }, + title: Text(l10n.backup_location), + subtitle: Text( + autoBackupLocation.$2.isEmpty + ? autoBackupLocation.$1 + : autoBackupLocation.$2, + style: TextStyle(fontSize: 11, color: secondaryColor(context)), + ), + ), + ListTile( + onTap: () { + final list = _getList(context); + List indexList = []; + indexList.addAll(backupFrequencyOptions); + showDialog( + context: context, + builder: (context) { + return StatefulBuilder( + builder: (context, setState) { + return AlertDialog( + title: Text( + l10n.backup_options_subtile, + ), + content: SizedBox( + width: mediaWidth(context, 0.8), + child: ListView.builder( + shrinkWrap: true, + itemCount: list.length, + itemBuilder: (context, index) { + return ListTileChapterFilter( + label: list[index], + type: indexList.contains(index) ? 1 : 0, + onTap: () { + if (indexList.contains(index)) { + setState(() { + indexList.remove(index); + }); + } else { + setState(() { + indexList.add(index); + }); + } + }); + }, + )), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () async { + Navigator.pop(context); + }, + child: Text( + l10n.cancel, + style: TextStyle( + color: primaryColor(context)), + )), + TextButton( + onPressed: () async { + ref + .read( + backupFrequencyOptionsStateProvider + .notifier) + .set(indexList); + Navigator.pop(context); + }, + child: Text( + l10n.ok, + style: TextStyle( + color: primaryColor(context)), + )), + ], + ) + ], + ); + }, + ); + }); + }, + title: Text(l10n.backup_options), + subtitle: Text( + l10n.backup_options_subtile, + style: TextStyle(fontSize: 11, color: secondaryColor(context)), + ), + ), + ListTile( + title: Padding( + padding: const EdgeInsets.only(bottom: 8), + child: Row( + children: [ + Icon(Icons.info_outline_rounded, + color: secondaryColor(context)), + ], + ), + ), + subtitle: Text(l10n.backup_and_restore_warning_info, + style: TextStyle(fontSize: 11, color: secondaryColor(context))), + ) + ], + ), ), ); }