add reader , browse , general setting

This commit is contained in:
kodjomoustapha 2023-05-18 17:06:37 +01:00
parent 8379b1a076
commit 9d4a7e8cb1
31 changed files with 1156 additions and 179 deletions

View file

@ -65,6 +65,14 @@ class Settings {
List<PersonalReaderMode>? personalReaderModeList;
bool? animatePageTransitions;
int? doubleTapAnimationSpeed;
bool? showNSFW;
bool? onlyIncludePinnedSources;
Settings(
{this.id = 227,
this.displayType = DisplayType.compactGrid,
@ -92,7 +100,11 @@ class Settings {
this.userAgent = defaultUserAgent,
this.cookiesList,
this.defaultReaderMode = ReaderMode.vertical,
this.personalReaderModeList});
this.personalReaderModeList,
this.animatePageTransitions = true,
this.doubleTapAnimationSpeed = 1,
this.showNSFW = true,
this.onlyIncludePinnedSources = false});
}
enum DisplayType {

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@ import 'package:mangayomi/services/webviews/webview.dart';
import 'package:mangayomi/views/browse/browse_screen.dart';
import 'package:mangayomi/views/browse/extension/extension_lang.dart';
import 'package:mangayomi/views/browse/global_search_screen.dart';
import 'package:mangayomi/views/general/general_screen.dart';
import 'package:mangayomi/views/main_view/main_screen.dart';
import 'package:mangayomi/views/history/history_screen.dart';
import 'package:mangayomi/views/library/library_screen.dart';
import 'package:mangayomi/views/manga/detail/manga_detail_main.dart';
@ -18,7 +18,10 @@ import 'package:mangayomi/views/more/about_screen.dart';
import 'package:mangayomi/views/more/download_queue/download_queue_screen.dart';
import 'package:mangayomi/views/more/more_screen.dart';
import 'package:mangayomi/views/more/settings/appearance/appearance_screen.dart';
import 'package:mangayomi/views/more/settings/categoties/categories_screen.dart';
import 'package:mangayomi/views/more/categoties/categories_screen.dart';
import 'package:mangayomi/views/more/settings/browse/browse_screen.dart';
import 'package:mangayomi/views/more/settings/general/general_screen.dart';
import 'package:mangayomi/views/more/settings/reader/reader_screen.dart';
import 'package:mangayomi/views/more/settings/settings_screen.dart';
import 'package:mangayomi/views/updates/updates_screen.dart';
@ -36,7 +39,7 @@ final routerProvider = Provider<GoRouter>((ref) {
class AsyncRouterNotifier extends ChangeNotifier {
List<RouteBase> get _routes => [
ShellRoute(
builder: (context, state, child) => GeneralScreen(child: child),
builder: (context, state, child) => MainScreen(child: child),
routes: [
GoRoute(
name: "library",
@ -276,6 +279,45 @@ class AsyncRouterNotifier extends ChangeNotifier {
);
},
),
GoRoute(
path: "/general",
name: "general",
builder: (context, state) {
return const GeneralScreen();
},
pageBuilder: (context, state) {
return CustomTransition(
key: state.pageKey,
child: const GeneralScreen(),
);
},
),
GoRoute(
path: "/readerMode",
name: "readerMode",
builder: (context, state) {
return const ReaderScreen();
},
pageBuilder: (context, state) {
return CustomTransition(
key: state.pageKey,
child: const ReaderScreen(),
);
},
),
GoRoute(
path: "/browseS",
name: "browseS",
builder: (context, state) {
return const BrowseSScreen();
},
pageBuilder: (context, state) {
return CustomTransition(
key: state.pageKey,
child: const BrowseSScreen(),
);
},
),
];
}

View file

@ -15,7 +15,7 @@ import 'package:mangayomi/sources/multisrc/mangathemesia/src/mangathemesia.dart'
import 'package:mangayomi/sources/multisrc/mmrcms/src/mmrcms.dart';
import 'package:mangayomi/sources/utils/utils.dart';
import 'package:mangayomi/utils/reg_exp_matcher.dart';
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/more/providers/incognito_mode_state_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'get_chapter_url.g.dart';

View file

@ -1,5 +1,3 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:grouped_list/grouped_list.dart';
@ -9,6 +7,7 @@ import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/utils/lang.dart';
import 'package:mangayomi/views/browse/extension/refresh_filter_data.dart';
import 'package:mangayomi/views/browse/extension/widgets/extension_list_tile_widget.dart';
import 'package:mangayomi/views/more/settings/browse/providers/browse_state_provider.dart';
class ExtensionScreen extends ConsumerWidget {
final Function(dynamic) entriesData;
@ -30,7 +29,11 @@ class ExtensionScreen extends ConsumerWidget {
.watch(fireImmediately: true),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
final entries = snapshot.data!;
final entries = snapshot.data!
.where((element) => ref.watch(showNSFWStateProvider)
? true
: element.isNsfw == false)
.toList();
entriesData(entries);
return GroupedListView<Source, String>(
elements: entriesFilter.isNotEmpty ? entriesFilter : entries,
@ -48,11 +51,6 @@ class ExtensionScreen extends ConsumerWidget {
),
),
itemBuilder: (context, Source element) {
if (element.isCloudflare! && !Platform.isWindows ||
element.isCloudflare! && !Platform.isLinux) {
return Container();
}
return ExtensionListTileWidget(
lang: element.lang!,
onChanged: (val) {

View file

@ -7,10 +7,12 @@ import 'package:mangayomi/services/get_manga_detail.dart';
import 'package:mangayomi/services/search_manga.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/sources/service.dart';
import 'package:mangayomi/sources/source_list.dart';
import 'package:mangayomi/utils/cached_network.dart';
import 'package:mangayomi/utils/headers.dart';
import 'package:mangayomi/utils/lang.dart';
import 'package:mangayomi/views/library/search_text_form_field.dart';
import 'package:mangayomi/views/more/settings/browse/providers/browse_state_provider.dart';
import 'package:mangayomi/views/widgets/bottom_text_widget.dart';
import 'package:mangayomi/views/widgets/manga_image_card_widget.dart';
@ -28,7 +30,9 @@ class _GlobalSearchScreenState extends ConsumerState<GlobalSearchScreen> {
final _textEditingController = TextEditingController();
@override
Widget build(BuildContext context) {
final sourceList = isar.sources.filter().isAddedEqualTo(true).findAllSync();
final sourceList = ref.watch(onlyIncludePinnedSourceStateProvider)
? isar.sources.filter().isAddedEqualTo(true).findAllSync()
: sourcesList;
return Scaffold(
appBar: AppBar(
leading: Container(),

View file

@ -10,6 +10,7 @@ import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/utils/headers.dart';
import 'package:mangayomi/utils/lang.dart';
import 'package:mangayomi/views/browse/extension/refresh_filter_data.dart';
import 'package:mangayomi/views/more/settings/browse/providers/browse_state_provider.dart';
class SourcesScreen extends ConsumerWidget {
const SourcesScreen({super.key});
@ -30,7 +31,11 @@ class SourcesScreen extends ConsumerWidget {
if (!snapshot.hasData) {
return const Center(child: Text("Empty"));
}
final entries = snapshot.data!;
final entries = snapshot.data!
.where((element) => ref.watch(showNSFWStateProvider)
? true
: element.isNsfw == false)
.toList();
return GroupedListView<Source, String>(
elements: entries,
groupBy: (element) => completeLang(element.lang!.toLowerCase()),

View file

@ -19,7 +19,7 @@ import 'package:mangayomi/views/library/widgets/library_listview_widget.dart';
import 'package:mangayomi/views/library/widgets/list_tile_manga_category.dart';
import 'package:mangayomi/views/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
import 'package:mangayomi/views/manga/detail/widgets/chapter_sort_list_tile_widget.dart';
import 'package:mangayomi/views/more/settings/categoties/providers/isar_providers.dart';
import 'package:mangayomi/views/more/categoties/providers/isar_providers.dart';
import 'package:mangayomi/views/widgets/error_text.dart';
import 'package:mangayomi/views/widgets/progress_center.dart';

View file

@ -10,7 +10,7 @@ import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/utils/cached_network.dart';
import 'package:mangayomi/utils/colors.dart';
import 'package:mangayomi/utils/headers.dart';
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/more/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/widgets/bottom_text_widget.dart';
import 'package:mangayomi/views/widgets/cover_view_widget.dart';
import 'package:mangayomi/views/widgets/error_text.dart';

View file

@ -10,7 +10,7 @@ import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/utils/cached_network.dart';
import 'package:mangayomi/utils/colors.dart';
import 'package:mangayomi/utils/headers.dart';
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/more/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/widgets/error_text.dart';
import 'package:mangayomi/views/widgets/listview_widget.dart';
import 'package:mangayomi/views/widgets/manga_image_card_widget.dart';

View file

@ -7,18 +7,18 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:mangayomi/utils/colors.dart';
import 'package:mangayomi/utils/media_query.dart';
import 'package:mangayomi/views/library/providers/library_state_provider.dart';
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/more/providers/incognito_mode_state_provider.dart';
class GeneralScreen extends StatefulWidget {
const GeneralScreen({super.key, required this.child});
class MainScreen extends StatefulWidget {
const MainScreen({super.key, required this.child});
final Widget child;
@override
State<GeneralScreen> createState() => _GeneralScreenState();
State<MainScreen> createState() => _MainScreenState();
}
class _GeneralScreenState extends State<GeneralScreen> {
class _MainScreenState extends State<MainScreen> {
@override
Widget build(BuildContext context) {
final route = GoRouter.of(context);

View file

@ -931,12 +931,13 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
elevation: 0),
onPressed: () {
String url = getMangaAPIUrl(widget.manga!.source!).isEmpty
? widget.manga!.link!
: "${getMangaBaseUrl(widget.manga!.source!)}${widget.manga!.link!}";
final manga = widget.manga!;
String url = getMangaAPIUrl(manga.source!).isEmpty
? manga.link!
: "${getMangaBaseUrl(manga.source!)}${manga.link!}";
Map<String, String> data = {
'url': url,
'source': widget.manga!.source!,
'source': manga.source!,
};
context.push("/mangawebview", extra: data);
},

View file

@ -14,7 +14,7 @@ import 'package:mangayomi/utils/media_query.dart';
import 'package:mangayomi/views/manga/detail/manga_detail_view.dart';
import 'package:mangayomi/views/manga/detail/providers/state_providers.dart';
import 'package:mangayomi/views/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/more/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/widgets/error_text.dart';
import 'package:mangayomi/views/widgets/progress_center.dart';

View file

@ -6,8 +6,11 @@ import 'package:extended_image/extended_image.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/sources/utils/utils.dart';
import 'package:mangayomi/views/manga/reader/providers/push_router.dart';
import 'package:mangayomi/services/get_chapter_url.dart';
import 'package:mangayomi/utils/image_detail_info.dart';
@ -16,6 +19,7 @@ import 'package:mangayomi/views/manga/reader/image_view_horizontal.dart';
import 'package:mangayomi/views/manga/reader/image_view_vertical.dart';
import 'package:mangayomi/views/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/views/manga/reader/widgets/circular_progress_indicator_animate_rotate.dart';
import 'package:mangayomi/views/more/settings/reader/reader_screen.dart';
import 'package:mangayomi/views/widgets/progress_center.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
@ -141,13 +145,26 @@ class _MangaChapterPageGalleryState
super.dispose();
}
bool animatePageTransitions =
isar.settings.getSync(227)!.animatePageTransitions!;
Duration? _doubleTapAnimationDuration() {
int doubleTapAnimationValue =
isar.settings.getSync(227)!.doubleTapAnimationSpeed!;
if (doubleTapAnimationValue == 0) {
return const Duration(milliseconds: 10);
} else if (doubleTapAnimationValue == 1) {
return const Duration(milliseconds: 800);
}
return const Duration(milliseconds: 200);
}
@override
void initState() {
_doubleClickAnimationController = AnimationController(
duration: const Duration(milliseconds: 300), vsync: this);
duration: _doubleTapAnimationDuration(), vsync: this);
_scaleAnimationController = AnimationController(
duration: const Duration(milliseconds: 300), vsync: this);
duration: _doubleTapAnimationDuration(), vsync: this);
_animation = Tween(begin: 1.0, end: 2.0).animate(
CurvedAnimation(curve: Curves.ease, parent: _scaleAnimationController));
_animation.addListener(() => _photoViewController.scale = _animation.value);
@ -202,10 +219,14 @@ class _MangaChapterPageGalleryState
index: index,
);
} else {
_itemScrollController.scrollTo(
curve: Curves.ease,
index: index,
duration: Duration(milliseconds: isSlide ? 2 : 150));
animatePageTransitions
? _itemScrollController.scrollTo(
curve: Curves.ease,
index: index,
duration: Duration(milliseconds: isSlide ? 2 : 150))
: _itemScrollController.jumpTo(
index: index,
);
}
}
} else {
@ -214,9 +235,11 @@ class _MangaChapterPageGalleryState
setState(() {
_isZoom = false;
});
_extendedController.animateToPage(index,
duration: Duration(milliseconds: isSlide ? 2 : 150),
curve: Curves.ease);
animatePageTransitions
? _extendedController.animateToPage(index,
duration: Duration(milliseconds: isSlide ? 2 : 150),
curve: Curves.ease)
: _extendedController.jumpToPage(index);
}
}
}
@ -229,10 +252,14 @@ class _MangaChapterPageGalleryState
index: index,
);
} else {
_itemScrollController.scrollTo(
curve: Curves.ease,
index: index,
duration: Duration(milliseconds: isSlide ? 2 : 150));
animatePageTransitions
? _itemScrollController.scrollTo(
curve: Curves.ease,
index: index,
duration: Duration(milliseconds: isSlide ? 2 : 150))
: _itemScrollController.jumpTo(
index: index,
);
}
}
} else {
@ -241,9 +268,11 @@ class _MangaChapterPageGalleryState
setState(() {
_isZoom = false;
});
_extendedController.animateToPage(index.toInt(),
duration: Duration(milliseconds: isSlide ? 2 : 150),
curve: Curves.ease);
animatePageTransitions
? _extendedController.animateToPage(index,
duration: Duration(milliseconds: isSlide ? 2 : 150),
curve: Curves.ease)
: _extendedController.jumpToPage(index);
}
}
}
@ -418,7 +447,18 @@ class _MangaChapterPageGalleryState
? Icons.bookmark
: Icons.bookmark_border_outlined)),
IconButton(
onPressed: () {}, icon: const Icon(Icons.public)),
onPressed: () {
final manga = widget.chapter.manga.value!;
String url = getMangaAPIUrl(manga.source!).isEmpty
? manga.link!
: "${getMangaBaseUrl(manga.source!)}${manga.link!}";
Map<String, String> data = {
'url': url,
'source': manga.source!,
};
context.push("/mangawebview", extra: data);
},
icon: const Icon(Icons.public)),
],
backgroundColor: _backgroundColor(context),
),
@ -611,8 +651,7 @@ class _MangaChapterPageGalleryState
width: 7,
),
Text(
widget.readerController
.getReaderModeValue(readerMode),
getReaderModeName(readerMode),
style: const TextStyle(
color: Colors.white,
fontSize: 12,

View file

@ -4,7 +4,7 @@ import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/history.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/more/providers/incognito_mode_state_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'reader_controller_provider.g.dart';
@ -51,18 +51,6 @@ class ReaderController extends _$ReaderController {
return isar.settings.getSync(227)!.defaultReaderMode;
}
String getReaderModeValue(ReaderMode readerMode) {
return readerMode == ReaderMode.vertical
? 'Vertical'
: readerMode == ReaderMode.verticalContinuous
? 'Verical continuous'
: readerMode == ReaderMode.ltr
? 'Left to Right'
: readerMode == ReaderMode.rtl
? 'Right to Left'
: 'Webtoon';
}
void setReaderMode(ReaderMode newReaderMode) {
List<PersonalReaderMode>? personalReaderModeLists = [];
for (var personalReaderMode in getIsarSetting().personalReaderModeList!) {

View file

@ -123,7 +123,7 @@ class CurrentIndexProvider
}
}
String _$readerControllerHash() => r'cffb8dfcfd338288d90757414d579fffcd478d29';
String _$readerControllerHash() => r'f4d0d66cf65887527b59bb10feaab80cccdcb59a';
abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> {
late final Chapter chapter;

View file

@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/views/more/settings/categoties/providers/isar_providers.dart';
import 'package:mangayomi/views/more/settings/categoties/widgets/custom_textfield.dart';
import 'package:mangayomi/views/more/categoties/providers/isar_providers.dart';
import 'package:mangayomi/views/more/categoties/widgets/custom_textfield.dart';
import 'package:mangayomi/views/widgets/progress_center.dart';
class CategoriesScreen extends ConsumerStatefulWidget {

View file

@ -0,0 +1,89 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/utils/colors.dart';
import 'package:mangayomi/views/more/settings/browse/providers/browse_state_provider.dart';
class BrowseSScreen extends ConsumerWidget {
const BrowseSScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final showNSFWS = ref.watch(showNSFWStateProvider);
final onlyIncludePinnedSource =
ref.watch(onlyIncludePinnedSourceStateProvider);
return Scaffold(
appBar: AppBar(
title: const Text("Browse"),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 30),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Row(
children: [
Text("Global search",
style: TextStyle(
fontSize: 13, color: primaryColor(context))),
],
),
),
SwitchListTile(
value: onlyIncludePinnedSource,
title: const Text("Only inclued pinned sources"),
onChanged: (value) {
ref
.read(onlyIncludePinnedSourceStateProvider.notifier)
.set(value);
}),
],
),
),
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Row(
children: [
Text("NSFW (18+) sources",
style: TextStyle(
fontSize: 13, color: primaryColor(context))),
],
),
),
SwitchListTile(
value: showNSFWS,
title: const Text("Show in sources and extensions lists"),
onChanged: (value) {
ref.read(showNSFWStateProvider.notifier).set(value);
}),
ListTile(
title: Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
children: [
Icon(
Icons.info_outline_rounded,
color: secondaryColor(context),
),
],
),
),
subtitle: Text(
"This does not prevent unofficial or potentially incorrectly flagged extensions from surfacing NSFW (18+) content within the app",
style: TextStyle(
fontSize: 11, color: secondaryColor(context))),
)
],
),
),
],
),
);
}
}

View file

@ -0,0 +1,33 @@
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'browse_state_provider.g.dart';
@riverpod
class OnlyIncludePinnedSourceState extends _$OnlyIncludePinnedSourceState {
@override
bool build() {
return isar.settings.getSync(227)!.onlyIncludePinnedSources!;
}
void set(bool value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(() =>
isar.settings.putSync(settings!..onlyIncludePinnedSources = value));
}
}
@riverpod
class ShowNSFWState extends _$ShowNSFWState {
@override
bool build() {
return isar.settings.getSync(227)!.showNSFW!;
}
void set(bool value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(() => isar.settings.putSync(settings!..showNSFW = value));
}
}

View file

@ -0,0 +1,42 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'browse_state_provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$onlyIncludePinnedSourceStateHash() =>
r'77c4bff96e186c4bce0a5c312871ceec88a269d0';
/// See also [OnlyIncludePinnedSourceState].
@ProviderFor(OnlyIncludePinnedSourceState)
final onlyIncludePinnedSourceStateProvider =
AutoDisposeNotifierProvider<OnlyIncludePinnedSourceState, bool>.internal(
OnlyIncludePinnedSourceState.new,
name: r'onlyIncludePinnedSourceStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$onlyIncludePinnedSourceStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$OnlyIncludePinnedSourceState = AutoDisposeNotifier<bool>;
String _$showNSFWStateHash() => r'fdb147ceef80a95066adc64ee63237fbdb3de81e';
/// See also [ShowNSFWState].
@ProviderFor(ShowNSFWState)
final showNSFWStateProvider =
AutoDisposeNotifierProvider<ShowNSFWState, bool>.internal(
ShowNSFWState.new,
name: r'showNSFWStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$showNSFWStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$ShowNSFWState = AutoDisposeNotifier<bool>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions

View file

@ -0,0 +1,78 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/utils/colors.dart';
import 'package:mangayomi/utils/media_query.dart';
class GeneralScreen extends ConsumerWidget {
const GeneralScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text("General"),
),
body: Column(
children: [
ListTile(
onTap: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text(
"App language",
),
content: SizedBox(
width: mediaWidth(context, 0.8),
child: ListView.builder(
shrinkWrap: true,
itemCount: 1,
itemBuilder: (context, index) {
return RadioListTile(
dense: true,
contentPadding: const EdgeInsets.all(0),
value: index,
groupValue: 0,
onChanged: (value) {
Navigator.pop(context);
},
title: const Row(
children: [Text("English")],
),
);
},
)),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () async {
Navigator.pop(context);
},
child: Text(
"Cancel",
style:
TextStyle(color: primaryColor(context)),
)),
],
)
],
);
});
},
title: const Text(
"App language",
style: TextStyle(),
),
subtitle: Text(
"English",
style: TextStyle(fontSize: 11, color: secondaryColor(context)),
),
),
],
),
);
}
}

View file

@ -0,0 +1,49 @@
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'reader_state_provider.g.dart';
@riverpod
class DefaultReadingModeState extends _$DefaultReadingModeState {
@override
ReaderMode build() {
return isar.settings.getSync(227)!.defaultReaderMode;
}
void set(ReaderMode value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(
() => isar.settings.putSync(settings!..defaultReaderMode = value));
}
}
@riverpod
class AnimatePageTransitionsState extends _$AnimatePageTransitionsState {
@override
bool build() {
return isar.settings.getSync(227)!.animatePageTransitions!;
}
void set(bool value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(
() => isar.settings.putSync(settings!..animatePageTransitions = value));
}
}
@riverpod
class DoubleTapAnimationSpeedState extends _$DoubleTapAnimationSpeedState {
@override
int build() {
return isar.settings.getSync(227)!.doubleTapAnimationSpeed!;
}
void set(int value) {
final settings = isar.settings.getSync(227);
state = value;
isar.writeTxnSync(() =>
isar.settings.putSync(settings!..doubleTapAnimationSpeed = value));
}
}

View file

@ -0,0 +1,60 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'reader_state_provider.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$defaultReadingModeStateHash() =>
r'2fe1d264041dd115bcc1a8c5648d0062a19f4c44';
/// See also [DefaultReadingModeState].
@ProviderFor(DefaultReadingModeState)
final defaultReadingModeStateProvider =
AutoDisposeNotifierProvider<DefaultReadingModeState, ReaderMode>.internal(
DefaultReadingModeState.new,
name: r'defaultReadingModeStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$defaultReadingModeStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$DefaultReadingModeState = AutoDisposeNotifier<ReaderMode>;
String _$animatePageTransitionsStateHash() =>
r'c8fdb2acb7a551c41a54c1aa14e378f6b1edd5c1';
/// See also [AnimatePageTransitionsState].
@ProviderFor(AnimatePageTransitionsState)
final animatePageTransitionsStateProvider =
AutoDisposeNotifierProvider<AnimatePageTransitionsState, bool>.internal(
AnimatePageTransitionsState.new,
name: r'animatePageTransitionsStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$animatePageTransitionsStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$AnimatePageTransitionsState = AutoDisposeNotifier<bool>;
String _$doubleTapAnimationSpeedStateHash() =>
r'd88657a8a587a0a77b6230a7fe5b2c1b833afca8';
/// See also [DoubleTapAnimationSpeedState].
@ProviderFor(DoubleTapAnimationSpeedState)
final doubleTapAnimationSpeedStateProvider =
AutoDisposeNotifierProvider<DoubleTapAnimationSpeedState, int>.internal(
DoubleTapAnimationSpeedState.new,
name: r'doubleTapAnimationSpeedStateProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$doubleTapAnimationSpeedStateHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$DoubleTapAnimationSpeedState = AutoDisposeNotifier<int>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions

View file

@ -0,0 +1,183 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/utils/colors.dart';
import 'package:mangayomi/utils/media_query.dart';
import 'package:mangayomi/views/more/settings/reader/providers/reader_state_provider.dart';
class ReaderScreen extends ConsumerWidget {
const ReaderScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final defaultReadingMode = ref.watch(defaultReadingModeStateProvider);
final animatePageTransitions =
ref.watch(animatePageTransitionsStateProvider);
final doubleTapAnimationSpeed =
ref.watch(doubleTapAnimationSpeedStateProvider);
return Scaffold(
appBar: AppBar(
title: const Text("Reader"),
),
body: Column(
children: [
ListTile(
onTap: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text(
"Default reading mode",
),
content: SizedBox(
width: mediaWidth(context, 0.8),
child: ListView.builder(
shrinkWrap: true,
itemCount: ReaderMode.values.length,
itemBuilder: (context, index) {
return RadioListTile(
dense: true,
contentPadding: const EdgeInsets.all(0),
value: ReaderMode.values[index],
groupValue: defaultReadingMode,
onChanged: (value) {
ref
.read(defaultReadingModeStateProvider
.notifier)
.set(value!);
Navigator.pop(context);
},
title: Row(
children: [
Text(getReaderModeName(
ReaderMode.values[index]))
],
),
);
},
)),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () async {
Navigator.pop(context);
},
child: Text(
"Cancel",
style:
TextStyle(color: primaryColor(context)),
)),
],
)
],
);
});
},
title: const Text(
"Default reading mode",
style: TextStyle(),
),
subtitle: Text(
getReaderModeName(defaultReadingMode),
style: TextStyle(fontSize: 11, color: secondaryColor(context)),
),
),
ListTile(
onTap: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text(
"Double tap animation speed",
),
content: SizedBox(
width: mediaWidth(context, 0.8),
child: ListView.builder(
shrinkWrap: true,
itemCount: 3,
itemBuilder: (context, index) {
return RadioListTile(
dense: true,
contentPadding: const EdgeInsets.all(0),
value: index,
groupValue: doubleTapAnimationSpeed,
onChanged: (value) {
ref
.read(doubleTapAnimationSpeedStateProvider
.notifier)
.set(value!);
Navigator.pop(context);
},
title: Row(
children: [
Text(getAnimationSpeedName(index))
],
),
);
},
)),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () async {
Navigator.pop(context);
},
child: Text(
"Cancel",
style:
TextStyle(color: primaryColor(context)),
)),
],
)
],
);
});
},
title: const Text(
"Double tap animation speed",
style: TextStyle(),
),
subtitle: Text(
getAnimationSpeedName(doubleTapAnimationSpeed),
style: TextStyle(fontSize: 11, color: secondaryColor(context)),
),
),
SwitchListTile(
value: animatePageTransitions,
title: const Text("Animate page transitions"),
onChanged: (value) {
ref
.read(animatePageTransitionsStateProvider.notifier)
.set(value);
}),
],
),
);
}
}
String getReaderModeName(ReaderMode readerMode) {
return readerMode == ReaderMode.vertical
? 'Vertical'
: readerMode == ReaderMode.verticalContinuous
? 'Verical continuous'
: readerMode == ReaderMode.ltr
? 'Left to Right'
: readerMode == ReaderMode.rtl
? 'Right to Left'
: 'Webtoon';
}
String getAnimationSpeedName(int type) {
return type == 0
? 'No animation'
: type == 1
? 'Normal'
: "Fast";
}

View file

@ -17,27 +17,27 @@ class SettingsScreen extends StatelessWidget {
title: 'General',
subtitle: 'App language',
icon: Icons.tune_rounded,
onTap: () {}),
onTap: () => context.push('/general')),
ListTileWidget(
title: 'Appearance',
subtitle: 'Theme',
icon: Icons.color_lens_rounded,
onTap: () => context.push('/appearance')),
ListTileWidget(
title: 'Library',
subtitle: 'Categories',
icon: Icons.collections_bookmark_rounded,
onTap: () {}),
// ListTileWidget(
// title: 'Library',
// subtitle: 'Categories',
// icon: Icons.collections_bookmark_rounded,
// onTap: () {}),
ListTileWidget(
title: 'Reader',
subtitle: 'Reading mode, display, navigation',
icon: Icons.chrome_reader_mode_rounded,
onTap: () {}),
onTap: () => context.push('/readerMode')),
ListTileWidget(
title: 'Browse',
subtitle: 'Sources, extensions, global search',
subtitle: 'Sources, global search',
icon: Icons.explore_rounded,
onTap: () {}),
onTap: () => context.push('/browseS')),
ListTileWidget(
onTap: () {
context.push('/about');

View file

@ -1,7 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/more/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/views/more/widgets/list_tile_widget.dart';
class IncognitoModeWidget extends ConsumerWidget {