This commit is contained in:
kodjodevf 2023-04-20 18:03:22 +01:00
parent 83d8e2940c
commit 3ff0715f4d
15 changed files with 230 additions and 269 deletions

View file

@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<application <application
android:label="mangayomi" android:label="Mangayomi"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/launcher_icon"> android:icon="@mipmap/launcher_icon">
<activity <activity

View file

@ -13,7 +13,7 @@
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>mangayomi</string> <string>Mangayomi</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>

View file

@ -11,6 +11,7 @@ import 'package:mangayomi/providers/storage_provider.dart';
import 'package:mangayomi/services/get_popular_manga.dart'; import 'package:mangayomi/services/get_popular_manga.dart';
import 'package:mangayomi/services/http_res_to_dom_html.dart'; import 'package:mangayomi/services/http_res_to_dom_html.dart';
import 'package:mangayomi/source/source_model.dart'; import 'package:mangayomi/source/source_model.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/settings/providers/incognito_mode_state_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:flutter_js/flutter_js.dart'; import 'package:flutter_js/flutter_js.dart';
@ -19,7 +20,9 @@ part 'get_manga_chapter_url.g.dart';
class GetMangaChapterUrlModel { class GetMangaChapterUrlModel {
Directory? path; Directory? path;
List urll = []; List urll = [];
GetMangaChapterUrlModel({required this.path, required this.urll}); List<bool> isLocaleList = [];
GetMangaChapterUrlModel(
{required this.path, required this.urll, required this.isLocaleList});
} }
@riverpod @riverpod
@ -30,6 +33,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
}) async { }) async {
Directory? path; Directory? path;
List urll = []; List urll = [];
List<bool> isLocaleList = [];
String source = modelManga.source!.toLowerCase(); String source = modelManga.source!.toLowerCase();
List pagesUrl = ref.watch(hiveBoxMangaInfo).get( List pagesUrl = ref.watch(hiveBoxMangaInfo).get(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl", "${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
@ -130,7 +134,8 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
/***********/ /***********/
else if (modelManga.source == 'mangakawaii') { else if (modelManga.source == 'mangakawaii') {
final response = await http.get(Uri.parse(modelManga.chapters![index].url!)); final response =
await http.get(Uri.parse(modelManga.chapters![index].url!));
var chapterSlug = RegExp("""var chapter_slug = "([^"]*)";""") var chapterSlug = RegExp("""var chapter_slug = "([^"]*)";""")
.allMatches(response.body.toString()) .allMatches(response.body.toString())
.last .last
@ -307,6 +312,16 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
} }
} }
} }
if (urll.isNotEmpty) {
for (var i = 0; i < urll.length; i++) {
if (await File("${path!.path}" "${padIndex(i + 1)}.jpg").exists()) {
isLocaleList.add(true);
} else {
isLocaleList.add(false);
}
}
}
return GetMangaChapterUrlModel(path: path, urll: urll); return GetMangaChapterUrlModel(
path: path, urll: urll, isLocaleList: isLocaleList);
} }

View file

@ -196,7 +196,7 @@ Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
' body > div.container.weekrank.ranking > div > div > ul > li > a > img') ' body > div.container.weekrank.ranking > div > div > ul > li > a > img')
.where((e) => e.attributes.containsKey('src')) .where((e) => e.attributes.containsKey('src'))
.where((e) => e.attributes['src']!.contains("cover")) .where((e) => e.attributes['src']!.contains("cover"))
.map((e) => e.attributes['src']) .map((e) => e.attributes['src']!.split('?').first)
.toList(); .toList();
name = dom name = dom

View file

@ -1,4 +1,8 @@
import 'dart:developer';
Map<String, String> headers(String source) { Map<String, String> headers(String source) {
source = source.toLowerCase();
log(source);
return source == 'mangakawaii' return source == 'mangakawaii'
? { ? {
'Referer': 'https://www.mangakawaii.io/', 'Referer': 'https://www.mangakawaii.io/',

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -6,16 +8,16 @@ import 'package:mangayomi/utils/colors.dart';
import 'package:mangayomi/utils/media_query.dart'; import 'package:mangayomi/utils/media_query.dart';
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart'; import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
class GeneralScreen extends ConsumerStatefulWidget { class GeneralScreen extends StatefulWidget {
const GeneralScreen({super.key, required this.child}); const GeneralScreen({super.key, required this.child});
final Widget child; final Widget child;
@override @override
ConsumerState<GeneralScreen> createState() => _GeneralScreenState(); State<GeneralScreen> createState() => _GeneralScreenState();
} }
class _GeneralScreenState extends ConsumerState<GeneralScreen> { class _GeneralScreenState extends State<GeneralScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final route = GoRouter.of(context); final route = GoRouter.of(context);
@ -36,8 +38,11 @@ class _GeneralScreenState extends ConsumerState<GeneralScreen> {
final incognitoMode = ref.watch(incognitoModeStateProvider); final incognitoMode = ref.watch(incognitoModeStateProvider);
return Material( return Material(
child: AnimatedContainer( child: AnimatedContainer(
height: height: incognitoMode
incognitoMode ? MediaQuery.of(context).padding.top * 2 : 0, ? Platform.isAndroid || Platform.isIOS
? MediaQuery.of(context).padding.top * 2
: 50
: 0,
curve: Curves.easeIn, curve: Curves.easeIn,
duration: const Duration(milliseconds: 150), duration: const Duration(milliseconds: 150),
color: generalColor(context), color: generalColor(context),

View file

@ -211,7 +211,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
controller: _scrollController, controller: _scrollController,
child: ListView.builder( child: ListView.builder(
controller: _scrollController, controller: _scrollController,
padding: const EdgeInsets.only(top: 0), padding: const EdgeInsets.only(top: 0, bottom: 60),
itemCount: widget.listLength, itemCount: widget.listLength,
itemBuilder: (context, index) { itemBuilder: (context, index) {
int finalIndex = index - 1; int finalIndex = index - 1;

View file

@ -81,9 +81,12 @@ class ChapterListTileWidget extends ConsumerWidget {
color: generalColor(context), color: generalColor(context),
) )
: Container(), : Container(),
Text( Flexible(
chapters[finalIndex].name!, child: Text(
style: const TextStyle(fontSize: 13), chapters[finalIndex].name!,
style: const TextStyle(fontSize: 13),
overflow: TextOverflow.ellipsis,
),
), ),
], ],
), ),

View file

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:mangayomi/utils/headers.dart'; import 'package:mangayomi/utils/headers.dart';
import 'package:mangayomi/utils/reg_exp_matcher.dart'; import 'package:mangayomi/utils/reg_exp_matcher.dart';
class ImageViewHorizontal extends StatefulWidget { class ImageViewHorizontal extends StatelessWidget {
final int length; final int length;
final String url; final String url;
final int index; final int index;
@ -12,6 +12,7 @@ class ImageViewHorizontal extends StatefulWidget {
final String source; final String source;
final String chapter; final String chapter;
final Directory path; final Directory path;
final bool isLocale;
final Widget? Function(ExtendedImageState state) loadStateChanged; final Widget? Function(ExtendedImageState state) loadStateChanged;
final Function(ExtendedImageGestureState state) onDoubleTap; final Function(ExtendedImageGestureState state) onDoubleTap;
final GestureConfig Function(ExtendedImageState state) final GestureConfig Function(ExtendedImageState state)
@ -28,70 +29,33 @@ class ImageViewHorizontal extends StatefulWidget {
required this.loadStateChanged, required this.loadStateChanged,
required this.onDoubleTap, required this.onDoubleTap,
required this.initGestureConfigHandler, required this.initGestureConfigHandler,
required this.isLocale,
}); });
@override
State createState() => _ImageViewHorizontalState();
}
typedef DoubleClickAnimationListener = void Function();
class _ImageViewHorizontalState extends State<ImageViewHorizontal> {
@override
void initState() {
_localCheck();
super.initState();
}
_localCheck() async {
if (await File("${widget.path.path}" "${padIndex(widget.index + 1)}.jpg")
.exists()) {
if (mounted) {
setState(() {
_isLocale = true;
_isLoading = false;
});
}
} else {
if (mounted) {
setState(() {
_isLocale = false;
_isLoading = false;
});
}
}
}
bool _isLoading = true;
bool _isLocale = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return _isLoading return isLocale
? const Center( ? ExtendedImage.file(
child: CircularProgressIndicator(), File("${path.path}" "${padIndex(index + 1)}.jpg"),
clearMemoryCacheWhenDispose: true,
enableMemoryCache: false,
mode: ExtendedImageMode.gesture,
initGestureConfigHandler: initGestureConfigHandler,
onDoubleTap: onDoubleTap,
loadStateChanged: loadStateChanged,
) )
: _isLocale : ExtendedImage.network(
? ExtendedImage.file( url,
File("${widget.path.path}" "${padIndex(widget.index + 1)}.jpg"), cache: true,
clearMemoryCacheWhenDispose: true, clearMemoryCacheWhenDispose: true,
enableMemoryCache: false, enableMemoryCache: false,
mode: ExtendedImageMode.gesture, cacheMaxAge: const Duration(days: 7),
initGestureConfigHandler: widget.initGestureConfigHandler, headers: headers(source),
onDoubleTap: widget.onDoubleTap, mode: ExtendedImageMode.gesture,
loadStateChanged: widget.loadStateChanged, initGestureConfigHandler: initGestureConfigHandler,
) onDoubleTap: onDoubleTap,
: ExtendedImage.network( handleLoadingProgress: true,
widget.url, loadStateChanged: loadStateChanged,
cache: true, );
clearMemoryCacheWhenDispose: true,
enableMemoryCache: false,
cacheMaxAge: const Duration(days: 7),
headers: headers(widget.source),
mode: ExtendedImageMode.gesture,
initGestureConfigHandler: widget.initGestureConfigHandler,
onDoubleTap: widget.onDoubleTap,
handleLoadingProgress: true,
loadStateChanged: widget.loadStateChanged,
);
} }
} }

View file

@ -7,9 +7,9 @@ import 'package:mangayomi/utils/headers.dart';
import 'package:mangayomi/utils/media_query.dart'; import 'package:mangayomi/utils/media_query.dart';
import 'package:mangayomi/utils/reg_exp_matcher.dart'; import 'package:mangayomi/utils/reg_exp_matcher.dart';
class ImageViewVertical extends ConsumerStatefulWidget { class ImageViewVertical extends StatelessWidget {
final int length; final int length;
final bool isLocale;
final String url; final String url;
final int index; final int index;
final String titleManga; final String titleManga;
@ -17,142 +17,99 @@ class ImageViewVertical extends ConsumerStatefulWidget {
final String chapter; final String chapter;
final Directory path; final Directory path;
const ImageViewVertical( const ImageViewVertical({
{super.key, super.key,
required this.url, required this.url,
required this.chapter, required this.chapter,
required this.index, required this.index,
required this.path, required this.path,
required this.titleManga, required this.titleManga,
required this.source, required this.source,
required this.length}); required this.length,
required this.isLocale,
});
@override
ConsumerState createState() => _ImageViewVerticalState();
}
class _ImageViewVerticalState extends ConsumerState<ImageViewVertical>
with AutomaticKeepAliveClientMixin<ImageViewVertical> {
@override
void initState() {
_localCheck();
super.initState();
}
_localCheck() async {
if (await File("${widget.path.path}" "${padIndex(widget.index + 1)}.jpg")
.exists()) {
if (mounted) {
setState(() {
_isLocale = true;
_isLoading = false;
});
}
} else {
if (mounted) {
setState(() {
_isLocale = false;
_isLoading = false;
});
}
}
}
bool _isLoading = true;
bool _isLocale = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context);
return Container( return Container(
color: Colors.black, color: Colors.black,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
if (widget.index == 0) if (index == 0)
SizedBox( SizedBox(
height: MediaQuery.of(context).padding.top, height: MediaQuery.of(context).padding.top,
), ),
_isLoading isLocale
? SizedBox( ? ExtendedImage.file(
height: mediaHeight(context, 0.8), fit: BoxFit.contain,
child: const Center( clearMemoryCacheWhenDispose: true,
child: SizedBox( enableMemoryCache: false,
height: 35, File('${path.path}${padIndex(index + 1)}.jpg'))
width: 35, : ExtendedImage.network(url,
child: CircularProgressIndicator()), headers: headers(source),
), handleLoadingProgress: true,
) fit: BoxFit.contain,
: _isLocale cacheMaxAge: const Duration(days: 7),
? ExtendedImage.file( clearMemoryCacheWhenDispose: true,
fit: BoxFit.contain, enableMemoryCache: false,
clearMemoryCacheWhenDispose: true, loadStateChanged: (ExtendedImageState state) {
enableMemoryCache: false, if (state.extendedImageLoadState == LoadState.loading) {
File( final ImageChunkEvent? loadingProgress =
'${widget.path.path}${padIndex(widget.index + 1)}.jpg')) state.loadingProgress;
: ExtendedImage.network(widget.url, final double progress =
headers: headers(widget.source), loadingProgress?.expectedTotalBytes != null
handleLoadingProgress: true, ? loadingProgress!.cumulativeBytesLoaded /
fit: BoxFit.contain, loadingProgress.expectedTotalBytes!
cacheMaxAge: const Duration(days: 7), : 0;
clearMemoryCacheWhenDispose: true, return TweenAnimationBuilder<double>(
enableMemoryCache: false, duration: const Duration(milliseconds: 500),
loadStateChanged: (ExtendedImageState state) { curve: Curves.easeInOut,
if (state.extendedImageLoadState == LoadState.loading) { tween: Tween<double>(
final ImageChunkEvent? loadingProgress = begin: 0,
state.loadingProgress; end: progress,
final double progress = ),
loadingProgress?.expectedTotalBytes != null builder: (context, value, _) => Container(
? loadingProgress!.cumulativeBytesLoaded / color: Colors.black,
loadingProgress.expectedTotalBytes! height: mediaHeight(context, 0.8),
: 0; child: Center(
return TweenAnimationBuilder<double>( child: progress == 0
duration: const Duration(milliseconds: 500), ? const CircularProgressIndicator()
curve: Curves.easeInOut, : CircularProgressIndicator(
tween: Tween<double>( value: progress,
begin: 0, ),
end: progress, ),
), ),
builder: (context, value, _) => Container( );
color: Colors.black, }
height: mediaHeight(context, 0.8), if (state.extendedImageLoadState == LoadState.failed) {
child: Center( return Container(
child: progress == 0 color: Colors.black,
? const CircularProgressIndicator() height: mediaHeight(context, 0.8),
: CircularProgressIndicator( child: Column(
value: progress, mainAxisAlignment: MainAxisAlignment.center,
), children: [
), ElevatedButton(
), onPressed: () {
); state.reLoadImage();
} },
if (state.extendedImageLoadState == LoadState.failed) { child: const Icon(
return Container( Icons.replay_outlined,
color: Colors.black, size: 30,
height: mediaHeight(context, 0.8), )),
child: Column( ],
mainAxisAlignment: MainAxisAlignment.center, ));
children: [ }
ElevatedButton( return null;
onPressed: () { }),
state.reLoadImage(); if (index + 1 == length)
},
child: const Icon(
Icons.replay_outlined,
size: 30,
)),
],
));
}
return null;
}),
if (widget.index + 1 == widget.length)
SizedBox( SizedBox(
height: mediaHeight(context, 0.3), height: mediaHeight(context, 0.3),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
'${widget.chapter} finished', '$chapter finished',
style: const TextStyle( style: const TextStyle(
fontSize: 17.0, fontSize: 17.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

View file

@ -20,6 +20,8 @@ import 'package:photo_view/photo_view_gallery.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
typedef DoubleClickAnimationListener = void Function();
class MangaReaderView extends ConsumerWidget { class MangaReaderView extends ConsumerWidget {
final MangaReaderModel mangaReaderModel; final MangaReaderModel mangaReaderModel;
const MangaReaderView({ const MangaReaderView({
@ -43,6 +45,7 @@ class MangaReaderView extends ConsumerWidget {
path: data.path!, path: data.path!,
url: data.urll, url: data.urll,
readerController: readerController, readerController: readerController,
isLocaleList: data.isLocaleList,
); );
}, },
error: (error, stackTrace) => Scaffold( error: (error, stackTrace) => Scaffold(
@ -104,10 +107,12 @@ class MangaChapterPageGallery extends ConsumerStatefulWidget {
{super.key, {super.key,
required this.path, required this.path,
required this.url, required this.url,
required this.readerController}); required this.readerController,
required this.isLocaleList});
final ReaderController readerController; final ReaderController readerController;
final Directory path; final Directory path;
final List url; final List url;
final List<bool> isLocaleList;
@override @override
ConsumerState createState() { ConsumerState createState() {
@ -122,7 +127,7 @@ class _MangaChapterPageGalleryState
ItemScrollController(); ItemScrollController();
late AnimationController _scaleAnimationController; late AnimationController _scaleAnimationController;
late Animation<double> _animation; late Animation<double> _animation;
late int _currentIndex = widget.readerController.getPageIndex();
@override @override
void dispose() { void dispose() {
_rebuildDetail.close(); _rebuildDetail.close();
@ -157,10 +162,9 @@ class _MangaChapterPageGalleryState
void _onPageChanged(int index) { void _onPageChanged(int index) {
widget.readerController.setMangaHistoryUpdate(); widget.readerController.setMangaHistoryUpdate();
if (mounted) { if (mounted) {
ref setState(() {
.read(currentIndexProvider(widget.readerController.mangaReaderModel) _currentIndex = index;
.notifier) });
.setCurrentIndex(index);
if (_imageDetailY != 0) { if (_imageDetailY != 0) {
_imageDetailY = 0; _imageDetailY = 0;
_rebuildDetail.sink.add(_imageDetailY); _rebuildDetail.sink.add(_imageDetailY);
@ -174,10 +178,16 @@ class _MangaChapterPageGalleryState
if (_selectedValue == ReaderMode.verticalContinuous || if (_selectedValue == ReaderMode.verticalContinuous ||
_selectedValue == ReaderMode.webtoon) { _selectedValue == ReaderMode.webtoon) {
if (index != -1) { if (index != -1) {
_itemScrollController.scrollTo( if (isSlide) {
curve: Curves.ease, _itemScrollController.jumpTo(
index: index, index: index,
duration: Duration(milliseconds: isSlide ? 2 : 150)); );
} else {
_itemScrollController.scrollTo(
curve: Curves.ease,
index: index,
duration: Duration(milliseconds: isSlide ? 2 : 150));
}
} }
} else { } else {
if (index != -1) { if (index != -1) {
@ -192,10 +202,16 @@ class _MangaChapterPageGalleryState
if (_selectedValue == ReaderMode.verticalContinuous || if (_selectedValue == ReaderMode.verticalContinuous ||
_selectedValue == ReaderMode.webtoon) { _selectedValue == ReaderMode.webtoon) {
if (widget.readerController.getPageLength(widget.url) != index) { if (widget.readerController.getPageLength(widget.url) != index) {
_itemScrollController.scrollTo( if (isSlide) {
curve: Curves.ease, _itemScrollController.jumpTo(
index: index, index: index,
duration: Duration(milliseconds: isSlide ? 2 : 150)); );
} else {
_itemScrollController.scrollTo(
curve: Curves.ease,
index: index,
duration: Duration(milliseconds: isSlide ? 2 : 150));
}
} }
} else { } else {
if (widget.readerController.getPageLength(widget.url) != index) { if (widget.readerController.getPageLength(widget.url) != index) {
@ -235,10 +251,9 @@ class _MangaChapterPageGalleryState
void _recordReadProgress(int index) { void _recordReadProgress(int index) {
widget.readerController.setMangaHistoryUpdate(); widget.readerController.setMangaHistoryUpdate();
if (mounted) { if (mounted) {
ref setState(() {
.read(currentIndexProvider(widget.readerController.mangaReaderModel) _currentIndex = index;
.notifier) });
.setCurrentIndex(index);
} }
widget.readerController.setPageIndex(index); widget.readerController.setPageIndex(index);
} }
@ -261,7 +276,7 @@ class _MangaChapterPageGalleryState
} }
late final _extendedController = ExtendedPageController( late final _extendedController = ExtendedPageController(
initialPage: widget.readerController.getPageIndex(), initialPage: _currentIndex,
shouldIgnorePointerWhenScrolling: false, shouldIgnorePointerWhenScrolling: false,
); );
double get pixelRatio => ui.window.devicePixelRatio; double get pixelRatio => ui.window.devicePixelRatio;
@ -315,8 +330,7 @@ class _MangaChapterPageGalleryState
if (isInit) { if (isInit) {
await Future.delayed(const Duration(milliseconds: 30)); await Future.delayed(const Duration(milliseconds: 30));
} }
_extendedController.jumpToPage(ref.watch( _extendedController.jumpToPage(_currentIndex);
currentIndexProvider(widget.readerController.mangaReaderModel)));
} }
} else if (value == ReaderMode.ltr || value == ReaderMode.rtl) { } else if (value == ReaderMode.ltr || value == ReaderMode.rtl) {
if (mounted) { if (mounted) {
@ -332,8 +346,7 @@ class _MangaChapterPageGalleryState
if (isInit) { if (isInit) {
await Future.delayed(const Duration(milliseconds: 30)); await Future.delayed(const Duration(milliseconds: 30));
} }
_extendedController.jumpToPage(ref.watch( _extendedController.jumpToPage(_currentIndex);
currentIndexProvider(widget.readerController.mangaReaderModel)));
} }
} else { } else {
if (mounted) { if (mounted) {
@ -345,9 +358,7 @@ class _MangaChapterPageGalleryState
await Future.delayed(const Duration(milliseconds: 30)); await Future.delayed(const Duration(milliseconds: 30));
} }
_itemScrollController.scrollTo( _itemScrollController.scrollTo(
index: ref.watch( index: _currentIndex, duration: const Duration(milliseconds: 1));
currentIndexProvider(widget.readerController.mangaReaderModel)),
duration: const Duration(milliseconds: 1));
} }
} }
} }
@ -460,7 +471,7 @@ class _MangaChapterPageGalleryState
Padding( Padding(
padding: const EdgeInsets.only(left: 12), padding: const EdgeInsets.only(left: 12),
child: Text( child: Text(
"${ref.watch(currentIndexProvider(widget.readerController.mangaReaderModel)) + 1} ", "${_currentIndex + 1} ",
style: const TextStyle( style: const TextStyle(
fontSize: 15.0, fontSize: 15.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -492,11 +503,7 @@ class _MangaChapterPageGalleryState
.getPageLength(widget.url) - .getPageLength(widget.url) -
1, 1,
1), 1),
value: ref value: _currentIndex.toDouble(),
.watch(currentIndexProvider(widget
.readerController
.mangaReaderModel))
.toDouble(),
min: 0, min: 0,
max: (widget.readerController max: (widget.readerController
.getPageLength(widget.url) - .getPageLength(widget.url) -
@ -509,7 +516,7 @@ class _MangaChapterPageGalleryState
Padding( Padding(
padding: const EdgeInsets.only(right: 12), padding: const EdgeInsets.only(right: 12),
child: Text( child: Text(
"${ref.watch(currentIndexProvider(widget.readerController.mangaReaderModel)) + 1} ", "${_currentIndex + 1} ",
style: const TextStyle( style: const TextStyle(
fontSize: 15.0, fontSize: 15.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -647,7 +654,7 @@ class _MangaChapterPageGalleryState
? Align( ? Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: Text( child: Text(
'${ref.watch(currentIndexProvider(widget.readerController.mangaReaderModel)) + 1} / ${widget.readerController.getPageLength(widget.url)}', '${_currentIndex + 1} / ${widget.readerController.getPageLength(widget.url)}',
style: const TextStyle( style: const TextStyle(
fontSize: 12.0, fontSize: 12.0,
color: Colors.white, color: Colors.white,
@ -681,8 +688,6 @@ class _MangaChapterPageGalleryState
Widget _gestureRightLeft() { Widget _gestureRightLeft() {
return Consumer( return Consumer(
builder: (context, ref, child) { builder: (context, ref, child) {
final currentIndex = ref.watch(
currentIndexProvider(widget.readerController.mangaReaderModel));
return Row( return Row(
children: [ children: [
/// left region /// left region
@ -693,9 +698,9 @@ class _MangaChapterPageGalleryState
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () {
if (_isReversHorizontal) { if (_isReversHorizontal) {
_onAddButtonTapped(currentIndex + 1, false); _onAddButtonTapped(_currentIndex + 1, false);
} else { } else {
_onAddButtonTapped(currentIndex - 1, true); _onAddButtonTapped(_currentIndex - 1, true);
} }
}, },
onDoubleTapDown: (TapDownDetails details) { onDoubleTapDown: (TapDownDetails details) {
@ -710,9 +715,9 @@ class _MangaChapterPageGalleryState
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () {
if (_isReversHorizontal) { if (_isReversHorizontal) {
_onAddButtonTapped(currentIndex + 1, false); _onAddButtonTapped(_currentIndex + 1, false);
} else { } else {
_onAddButtonTapped(currentIndex - 1, true); _onAddButtonTapped(_currentIndex - 1, true);
} }
}, },
), ),
@ -751,9 +756,9 @@ class _MangaChapterPageGalleryState
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () {
if (_isReversHorizontal) { if (_isReversHorizontal) {
_onAddButtonTapped(currentIndex - 1, true); _onAddButtonTapped(_currentIndex - 1, true);
} else { } else {
_onAddButtonTapped(currentIndex + 1, false); _onAddButtonTapped(_currentIndex + 1, false);
} }
}, },
onDoubleTapDown: (TapDownDetails details) { onDoubleTapDown: (TapDownDetails details) {
@ -768,9 +773,9 @@ class _MangaChapterPageGalleryState
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () {
if (_isReversHorizontal) { if (_isReversHorizontal) {
_onAddButtonTapped(currentIndex - 1, true); _onAddButtonTapped(_currentIndex - 1, true);
} else { } else {
_onAddButtonTapped(currentIndex + 1, false); _onAddButtonTapped(_currentIndex + 1, false);
} }
}, },
), ),
@ -784,8 +789,6 @@ class _MangaChapterPageGalleryState
Widget _gestureTopBottom() { Widget _gestureTopBottom() {
return Consumer( return Consumer(
builder: (context, ref, child) { builder: (context, ref, child) {
final currentIndex = ref.watch(
currentIndexProvider(widget.readerController.mangaReaderModel));
return Column( return Column(
children: [ children: [
/// top region /// top region
@ -795,7 +798,7 @@ class _MangaChapterPageGalleryState
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () {
_onAddButtonTapped(currentIndex - 1, true); _onAddButtonTapped(_currentIndex - 1, true);
}, },
onDoubleTapDown: (TapDownDetails details) { onDoubleTapDown: (TapDownDetails details) {
_toggleScale(details.globalPosition); _toggleScale(details.globalPosition);
@ -808,7 +811,7 @@ class _MangaChapterPageGalleryState
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () {
_onAddButtonTapped(currentIndex - 1, true); _onAddButtonTapped(_currentIndex - 1, true);
}, },
), ),
), ),
@ -823,7 +826,7 @@ class _MangaChapterPageGalleryState
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () {
_onAddButtonTapped(currentIndex + 1, false); _onAddButtonTapped(_currentIndex + 1, false);
}, },
onDoubleTapDown: (TapDownDetails details) { onDoubleTapDown: (TapDownDetails details) {
_toggleScale(details.globalPosition); _toggleScale(details.globalPosition);
@ -836,7 +839,7 @@ class _MangaChapterPageGalleryState
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
onTap: () { onTap: () {
_onAddButtonTapped(currentIndex + 1, false); _onAddButtonTapped(_currentIndex + 1, false);
}, },
), ),
), ),
@ -885,8 +888,7 @@ class _MangaChapterPageGalleryState
child: ScrollablePositionedList.separated( child: ScrollablePositionedList.separated(
physics: const ClampingScrollPhysics(), physics: const ClampingScrollPhysics(),
minCacheExtent: 8 * (MediaQuery.of(context).size.height), minCacheExtent: 8 * (MediaQuery.of(context).size.height),
initialScrollIndex: initialScrollIndex: _currentIndex,
widget.readerController.getPageIndex(),
itemCount: itemCount:
widget.readerController.getPageLength(widget.url), widget.readerController.getPageLength(widget.url),
itemScrollController: _itemScrollController, itemScrollController: _itemScrollController,
@ -899,13 +901,18 @@ class _MangaChapterPageGalleryState
onDoubleTap: () {}, onDoubleTap: () {},
child: ImageViewVertical( child: ImageViewVertical(
titleManga: widget.readerController.getMangaName(), titleManga: widget.readerController.getMangaName(),
source: widget.readerController.getSourceName(), source: widget.readerController
.getSourceName()
.replaceAll(
'${widget.readerController.mangaReaderModel.modelManga.lang}-',
''),
index: index, index: index,
url: widget.url[index], url: widget.url[index],
path: widget.path, path: widget.path,
chapter: widget.readerController.getChapterTitle(), chapter: widget.readerController.getChapterTitle(),
length: length:
widget.readerController.getPageLength(widget.url), widget.readerController.getPageLength(widget.url),
isLocale: widget.isLocaleList[index],
), ),
), ),
separatorBuilder: (_, __) => Divider( separatorBuilder: (_, __) => Divider(
@ -930,7 +937,11 @@ class _MangaChapterPageGalleryState
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ImageViewHorizontal( return ImageViewHorizontal(
titleManga: widget.readerController.getMangaName(), titleManga: widget.readerController.getMangaName(),
source: widget.readerController.getSourceName(), source: widget.readerController
.getSourceName()
.replaceAll(
'${widget.readerController.mangaReaderModel.modelManga.lang}-',
''),
index: index, index: index,
url: widget.url[index], url: widget.url[index],
path: widget.path, path: widget.path,
@ -1075,6 +1086,9 @@ class _MangaChapterPageGalleryState
_doubleClickAnimationController.forward(); _doubleClickAnimationController.forward();
}, },
isLocale: _isReversHorizontal
? widget.isLocaleList.reversed.toList()[index]
: widget.isLocaleList[index],
); );
}, },
itemCount: itemCount:

View file

@ -8,18 +8,17 @@ part 'flex_scheme_color_state_provider.g.dart';
class FlexSchemeColorState extends _$FlexSchemeColorState { class FlexSchemeColorState extends _$FlexSchemeColorState {
@override @override
FlexSchemeColor build() { FlexSchemeColor build() {
if (ref.read(themeModeStateProvider)) { return ref.read(themeModeStateProvider)
if (ref.watch(hiveBoxSettings).get('FlexColorIndex') != null) { ? ThemeAA
state = ThemeAA .schemes[ref
.schemes[ref.watch(hiveBoxSettings).get('FlexColorIndex')].light; .watch(hiveBoxSettings)
} .get('FlexColorIndex', defaultValue: 2)]
} else { .light
if (ref.watch(hiveBoxSettings).get('FlexColorIndex') != null) { : ThemeAA
state = ThemeAA .schemes[ref
.schemes[ref.watch(hiveBoxSettings).get('FlexColorIndex')].dark; .watch(hiveBoxSettings)
} .get('FlexColorIndex', defaultValue: 2)]
} .dark;
return state;
} }
void setTheme(FlexSchemeColor color, int index) { void setTheme(FlexSchemeColor color, int index) {

View file

@ -22,7 +22,7 @@ class BlendLevelSlider extends ConsumerWidget {
Slider( Slider(
min: 0.0, min: 0.0,
max: 40.0, max: 40.0,
divisions: max(40 - 1, 1), divisions: max(39, 1),
value: blendLevel, value: blendLevel,
onChanged: (value) { onChanged: (value) {
ref.read(blendLevelStateProvider.notifier).setBlendLevel(value); ref.read(blendLevelStateProvider.notifier).setBlendLevel(value);

View file

@ -387,10 +387,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_riverpod name: flutter_riverpod
sha256: b3c3a8a9714b7f88dd2a41e1efbc47f76d620b06ab427c62ae7bc82298cd7dbb sha256: "9692634c2c00d2a1a5e96bbde0b79a7c6f0f266aa266d76cd52841f791949a89"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.5"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -837,10 +837,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: riverpod name: riverpod
sha256: b0fbf7927333c5c318f7e2c22c8b4fd2542ba294de0373e80ecdb34e0dcd8dc4 sha256: ec5641067d111681ef825754d1327565c987985c7cb52e09bc867b78248854b2
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.2" version: "2.3.5"
riverpod_analyzer_utils: riverpod_analyzer_utils:
dependency: transitive dependency: transitive
description: description:
@ -1042,10 +1042,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
sha256: dd729390aa936bf1bdf5cd1bc7468ff340263f80a2c4f569416507667de8e3c8 sha256: a52628068d282d01a07cd86e6ba99e497aa45ce8c91159015b2416907d78e411
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.26" version: "6.0.27"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:

View file

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 0.0.11+3 version: 0.0.15+4
environment: environment:
sdk: '>=2.19.5 <3.0.0' sdk: '>=2.19.5 <3.0.0'