code refactor

This commit is contained in:
kodjomoustapha 2023-06-08 18:40:18 +01:00
parent 2a45b1d993
commit e90cf9f736
5 changed files with 453 additions and 356 deletions

View file

@ -1,5 +1,4 @@
// ignore_for_file: depend_on_referenced_packages // ignore_for_file: depend_on_referenced_packages
import 'dart:io';
import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -7,21 +6,12 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/date_symbol_data_local.dart'; import 'package:intl/date_symbol_data_local.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/history.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/providers/storage_provider.dart'; import 'package:mangayomi/providers/storage_provider.dart';
import 'package:mangayomi/router/router.dart'; import 'package:mangayomi/router/router.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/blend_level_state_provider.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/blend_level_state_provider.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/flex_scheme_color_state_provider.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/flex_scheme_color_state_provider.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_state_provider.dart'; import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_state_provider.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
late Isar isar; late Isar isar;
void main(List<String> args) async { void main(List<String> args) async {
@ -29,49 +19,11 @@ void main(List<String> args) async {
return; return;
} }
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await _initDB(); isar = await StorageProvider().initDB(null);
await StorageProvider().requestPermission(); await StorageProvider().requestPermission();
runApp(const ProviderScope(child: MyApp())); runApp(const ProviderScope(child: MyApp()));
} }
_initDB() async {
final dir = await getApplicationDocumentsDirectory();
if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
isar = Isar.openSync(
[
MangaSchema,
ChapterSchema,
CategorySchema,
HistorySchema,
DownloadSchema,
SourceSchema,
SettingsSchema
],
directory: dir.path,
);
} else {
String dbDir = path.join(dir.path, 'Mangayomi', 'databases');
await Directory(dbDir).create(recursive: true);
isar = await Isar.open([
MangaSchema,
ChapterSchema,
CategorySchema,
HistorySchema,
DownloadSchema,
SourceSchema,
SettingsSchema
], directory: dbDir, name: "mangayomiDb");
}
if (isar.settings.filter().idEqualTo(227).isEmptySync()) {
isar.writeTxnSync(
() {
isar.settings.putSync(Settings()
);
},
);
}
}
_iniDateFormatting() { _iniDateFormatting() {
initializeDateFormatting("en", null); initializeDateFormatting("en", null);
initializeDateFormatting("fr", null); initializeDateFormatting("fr", null);

View file

@ -1,4 +1,6 @@
// ignore_for_file: implementation_imports, depend_on_referenced_packages // ignore_for_file: implementation_imports, depend_on_referenced_packages
import 'dart:io';
import 'package:background_downloader/background_downloader.dart'; import 'package:background_downloader/background_downloader.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -40,11 +42,16 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
late final manga = widget.chapter.manga.value!; late final manga = widget.chapter.manga.value!;
_deleteFile(List pageUrl) async { _deleteFile(List pageUrl) async {
final mangaDir =
await _storageProvider.getMangaMainDirectory(widget.chapter);
final path = await _storageProvider.getMangaChapterDirectory( final path = await _storageProvider.getMangaChapterDirectory(
widget.chapter, widget.chapter,
); );
try { try {
if (await File("${mangaDir!.path}${widget.chapter.name}.cbz").exists()) {
File("${mangaDir.path}${widget.chapter.name}.cbz").deleteSync();
}
path!.deleteSync(recursive: true); path!.deleteSync(recursive: true);
} catch (_) {} } catch (_) {}
isar.writeTxnSync(() { isar.writeTxnSync(() {

View file

@ -118,7 +118,8 @@ Future<List<String>> downloadChapter(
} }
} }
bool cbzFileExist = bool cbzFileExist =
await File("${mangaDir!.path}${chapter.name}.cbz").exists(); await File("${mangaDir!.path}${chapter.name}.cbz").exists() &&
ref.watch(saveAsCBZArchiveStateProvider);
if (tasks.isEmpty && pageUrls.isNotEmpty || cbzFileExist) { if (tasks.isEmpty && pageUrls.isNotEmpty || cbzFileExist) {
final model = Download( final model = Download(
succeeded: 0, succeeded: 0,
@ -128,6 +129,7 @@ Future<List<String>> downloadChapter(
taskIds: pageUrls, taskIds: pageUrls,
isStartDownload: false, isStartDownload: false,
chapterId: chapter.id); chapterId: chapter.id);
if (!cbzFileExist) { if (!cbzFileExist) {
await ref.watch(convertToCBZProvider( await ref.watch(convertToCBZProvider(
path.path, mangaDir.path, chapter.name!, pageUrls) path.path, mangaDir.path, chapter.name!, pageUrls)
@ -142,9 +144,11 @@ Future<List<String>> downloadChapter(
tasks, tasks,
batchProgressCallback: (succeeded, failed) async { batchProgressCallback: (succeeded, failed) async {
if (succeeded == tasks.length) { if (succeeded == tasks.length) {
await ref.watch(convertToCBZProvider( if (ref.watch(saveAsCBZArchiveStateProvider)) {
path!.path, mangaDir.path, chapter.name!, pageUrls) await ref.watch(convertToCBZProvider(
.future); path!.path, mangaDir.path, chapter.name!, pageUrls)
.future);
}
} }
bool isEmpty = isar.downloads bool isEmpty = isar.downloads
.filter() .filter()

View file

@ -1,15 +1,21 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'dart:io'; import 'dart:io';
import 'package:draggable_menu/draggable_menu.dart'; import 'package:draggable_menu/draggable_menu.dart';
import 'package:extended_image/extended_image.dart'; import 'package:extended_image/extended_image.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart'; import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart'; 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/models/settings.dart';
import 'package:mangayomi/providers/storage_provider.dart';
import 'package:mangayomi/sources/utils/utils.dart'; import 'package:mangayomi/sources/utils/utils.dart';
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart'; import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
import 'package:mangayomi/services/get_chapter_url.dart'; import 'package:mangayomi/services/get_chapter_url.dart';
@ -206,15 +212,20 @@ class _MangaChapterPageGalleryState
ref.read(currentIndexProvider(widget.chapter).notifier).setCurrentIndex( ref.read(currentIndexProvider(widget.chapter).notifier).setCurrentIndex(
posIndex, posIndex,
); );
widget.readerController.setMangaHistoryUpdate(); final datas = {
widget.readerController.setPageIndex(posIndex); "chapterId": widget.chapter.id,
widget.readerController.setChapterPageLastRead(posIndex); "pageIndex": posIndex,
"path": _dir!.path,
};
compute(_isolateService, jsonEncode(datas));
_currentIndex = posIndex; _currentIndex = posIndex;
} }
} }
} }
Directory? _dir;
_initCurrentIndex() async { _initCurrentIndex() async {
_dir = await StorageProvider().getDatabaseDirectory();
widget.readerController.setMangaHistoryUpdate(); widget.readerController.setMangaHistoryUpdate();
await Future.delayed(const Duration(milliseconds: 1)); await Future.delayed(const Duration(milliseconds: 1));
_selectedValue = widget.readerController.getReaderMode(); _selectedValue = widget.readerController.getReaderMode();
@ -225,9 +236,12 @@ class _MangaChapterPageGalleryState
ref.read(currentIndexProvider(widget.chapter).notifier).setCurrentIndex( ref.read(currentIndexProvider(widget.chapter).notifier).setCurrentIndex(
index, index,
); );
widget.readerController.setMangaHistoryUpdate(); final datas = {
widget.readerController.setPageIndex(index); "chapterId": widget.chapter.id,
widget.readerController.setChapterPageLastRead(index); "pageIndex": index,
"path": _dir!.path,
};
compute(_isolateService, jsonEncode(datas));
_currentIndex = index; _currentIndex = index;
if (_imageDetailY != 0) { if (_imageDetailY != 0) {
_imageDetailY = 0; _imageDetailY = 0;
@ -414,216 +428,107 @@ class _MangaChapterPageGalleryState
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.9); Theme.of(context).scaffoldBackgroundColor.withOpacity(0.9);
Widget _showMore() { Widget _showMore() {
return Consumer( bool isNotFirstChapter = widget.readerController.getChapterIndex() + 1 !=
builder: (context, ref, child) { widget.readerController.getChaptersLength();
final currentIndex = ref.watch(currentIndexProvider(widget.chapter)); bool isNotLastChapter = widget.readerController.getChapterIndex() != 0;
bool isNotFirstChapter = return Column(
widget.readerController.getChapterIndex() + 1 != mainAxisAlignment: MainAxisAlignment.spaceBetween,
widget.readerController.getChaptersLength(); children: [
bool isNotLastChapter = widget.readerController.getChapterIndex() != 0; AnimatedContainer(
return Column( height: _isView ? 80 : 0,
mainAxisAlignment: MainAxisAlignment.spaceBetween, curve: Curves.ease,
children: [ duration: const Duration(milliseconds: 200),
AnimatedContainer( child: PreferredSize(
height: _isView ? 80 : 0, preferredSize: Size.fromHeight(_isView ? 80 : 0),
curve: Curves.ease, child: AppBar(
duration: const Duration(milliseconds: 200), centerTitle: false,
child: PreferredSize( automaticallyImplyLeading: false,
preferredSize: Size.fromHeight(_isView ? 80 : 0), titleSpacing: 0,
child: AppBar( leading: BackButton(
centerTitle: false, onPressed: () {
automaticallyImplyLeading: false, Navigator.pop(context);
titleSpacing: 0, },
leading: BackButton( ),
onPressed: () { title: ListTile(
Navigator.pop(context); dense: true,
}, title: SizedBox(
width: mediaWidth(context, 0.8),
child: Text(
'${widget.readerController.getMangaName()} ',
style: const TextStyle(fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
), ),
title: ListTile( ),
dense: true, subtitle: SizedBox(
title: SizedBox( width: mediaWidth(context, 0.8),
width: mediaWidth(context, 0.8), child: Text(
child: Text( widget.readerController.getChapterTitle(),
'${widget.readerController.getMangaName()} ', style: const TextStyle(
style: const TextStyle(fontWeight: FontWeight.bold), fontSize: 12,
overflow: TextOverflow.ellipsis, fontWeight: FontWeight.w400,
),
),
subtitle: SizedBox(
width: mediaWidth(context, 0.8),
child: Text(
widget.readerController.getChapterTitle(),
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w400,
),
overflow: TextOverflow.ellipsis,
),
), ),
overflow: TextOverflow.ellipsis,
), ),
actions: [
IconButton(
onPressed: () {
widget.readerController.setChapterBookmarked();
setState(() {
_isBookmarked = !_isBookmarked;
});
},
icon: Icon(_isBookmarked
? Icons.bookmark
: Icons.bookmark_border_outlined)),
IconButton(
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!,
'title': widget.chapter.name!
};
context.push("/mangawebview", extra: data);
},
icon: const Icon(Icons.public)),
],
backgroundColor: _backgroundColor(context),
), ),
), ),
actions: [
IconButton(
onPressed: () {
widget.readerController.setChapterBookmarked();
setState(() {
_isBookmarked = !_isBookmarked;
});
},
icon: Icon(_isBookmarked
? Icons.bookmark
: Icons.bookmark_border_outlined)),
IconButton(
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!,
'title': widget.chapter.name!
};
context.push("/mangawebview", extra: data);
},
icon: const Icon(Icons.public)),
],
backgroundColor: _backgroundColor(context),
), ),
AnimatedContainer( ),
curve: Curves.ease, ),
duration: const Duration(milliseconds: 300), AnimatedContainer(
width: mediaWidth(context, 1), curve: Curves.ease,
height: _isView ? 130 : 0, duration: const Duration(milliseconds: 300),
child: Column( width: mediaWidth(context, 1),
children: [ height: _isView ? 130 : 0,
Flexible( child: Column(
child: Row( children: [
children: [ Flexible(
Padding( child: Row(
padding: const EdgeInsets.all(8.0), children: [
child: CircleAvatar( Padding(
radius: 23, padding: const EdgeInsets.all(8.0),
backgroundColor: _backgroundColor(context), child: CircleAvatar(
child: IconButton( radius: 23,
onPressed: isNotFirstChapter backgroundColor: _backgroundColor(context),
? () { child: IconButton(
pushReplacementMangaReaderView( onPressed: isNotFirstChapter
context: context, ? () {
chapter: widget.readerController pushReplacementMangaReaderView(
.getNextChapter());
}
: null,
icon: Transform.scale(
scaleX: 1,
child: Icon(Icons.skip_previous_rounded,
color: isNotFirstChapter
? Theme.of(context)
.textTheme
.bodyLarge!
.color
: Theme.of(context)
.textTheme
.bodyLarge!
.color!
.withOpacity(0.4)),
)),
),
),
Expanded(
child: Transform.scale(
scaleX: !_isReversHorizontal ? 1 : -1,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Container(
height: 70,
decoration: BoxDecoration(
color: _backgroundColor(context),
borderRadius: BorderRadius.circular(25)),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 12),
child: Transform.scale(
scaleX: !_isReversHorizontal ? 1 : -1,
child: SizedBox(
width: 25,
child: Text(
"${currentIndex + 1} ",
style: const TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
Flexible(
child: Slider(
onChanged: (newValue) {
_onBtnTapped(newValue.toInt(), true,
isSlide: true);
},
divisions: max(
widget.readerController
.getPageLength(widget.url) -
1,
1),
value: min(
_currentIndex.toDouble(),
widget.readerController
.getPageLength(widget.url)
.toDouble()),
min: 0,
max: (widget.readerController
.getPageLength(widget.url) -
1)
.toDouble(),
),
),
Padding(
padding: const EdgeInsets.only(right: 12),
child: Transform.scale(
scaleX: !_isReversHorizontal ? 1 : -1,
child: SizedBox(
width: 25,
child: Text(
"${widget.readerController.getPageLength(widget.url)}",
style: const TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: CircleAvatar(
radius: 23,
backgroundColor: _backgroundColor(context),
child: IconButton(
onPressed: isNotLastChapter
? () {
pushReplacementMangaReaderView(
context: context, context: context,
chapter: widget.readerController chapter: widget.readerController
.getPrevChapter(), .getNextChapter());
); }
} : null,
: null, icon: Transform.scale(
icon: Transform.scale( scaleX: 1,
scaleX: 1, child: Icon(Icons.skip_previous_rounded,
child: Icon( color: isNotFirstChapter
Icons.skip_next_rounded,
color: isNotLastChapter
? Theme.of(context) ? Theme.of(context)
.textTheme .textTheme
.bodyLarge! .bodyLarge!
@ -632,113 +537,223 @@ class _MangaChapterPageGalleryState
.textTheme .textTheme
.bodyLarge! .bodyLarge!
.color! .color!
.withOpacity(0.4), .withOpacity(0.4)),
// size: 17, )),
),
),
Expanded(
child: Transform.scale(
scaleX: !_isReversHorizontal ? 1 : -1,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Container(
height: 70,
decoration: BoxDecoration(
color: _backgroundColor(context),
borderRadius: BorderRadius.circular(25)),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 12),
child: Transform.scale(
scaleX: !_isReversHorizontal ? 1 : -1,
child: SizedBox(
width: 25,
child: Consumer(
builder: (context, ref, child) {
final currentIndex = ref.watch(
currentIndexProvider(
widget.chapter));
return Text(
"${currentIndex + 1} ",
style: const TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
);
}),
),
),
), ),
), Flexible(
child:
Consumer(builder: (context, ref, child) {
final currentIndex = ref.watch(
currentIndexProvider(widget.chapter));
return Slider(
onChanged: (newValue) {
_onBtnTapped(newValue.toInt(), true,
isSlide: true);
},
divisions: max(
widget.readerController
.getPageLength(widget.url) -
1,
1),
value: min(
currentIndex.toDouble(),
widget.readerController
.getPageLength(widget.url)
.toDouble()),
min: 0,
max: (widget.readerController
.getPageLength(widget.url) -
1)
.toDouble(),
);
}),
),
Padding(
padding: const EdgeInsets.only(right: 12),
child: Transform.scale(
scaleX: !_isReversHorizontal ? 1 : -1,
child: SizedBox(
width: 25,
child: Text(
"${widget.readerController.getPageLength(widget.url)}",
style: const TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
), ),
), ),
), ),
],
),
),
Flexible(
child: Container(
height: 65,
color: _backgroundColor(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
PopupMenuButton(
color: Colors.black,
child: const Icon(
Icons.app_settings_alt_outlined,
),
onSelected: (value) {
if (mounted) {
setState(() {
_selectedValue = value;
});
}
_(value, true);
},
itemBuilder: (context) => [
for (var readerMode in ReaderMode.values)
PopupMenuItem(
value: readerMode,
child: Row(
children: [
Icon(
Icons.check,
color: _selectedValue == readerMode
? Colors.white
: Colors.transparent,
),
const SizedBox(
width: 7,
),
Text(
getReaderModeName(readerMode),
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
),
],
)),
],
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.screen_rotation,
),
),
IconButton(
onPressed: () {
_showModalSettings();
},
icon: const Icon(
Icons.settings_rounded,
),
),
],
), ),
), ),
), Padding(
], padding: const EdgeInsets.all(8.0),
child: CircleAvatar(
radius: 23,
backgroundColor: _backgroundColor(context),
child: IconButton(
onPressed: isNotLastChapter
? () {
pushReplacementMangaReaderView(
context: context,
chapter: widget.readerController
.getPrevChapter(),
);
}
: null,
icon: Transform.scale(
scaleX: 1,
child: Icon(
Icons.skip_next_rounded,
color: isNotLastChapter
? Theme.of(context).textTheme.bodyLarge!.color
: Theme.of(context)
.textTheme
.bodyLarge!
.color!
.withOpacity(0.4),
// size: 17,
),
),
),
),
),
],
),
), ),
), Flexible(
], child: Container(
); height: 65,
}, color: _backgroundColor(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
PopupMenuButton(
color: Colors.black,
child: const Icon(
Icons.app_settings_alt_outlined,
),
onSelected: (value) {
if (mounted) {
setState(() {
_selectedValue = value;
});
}
_(value, true);
},
itemBuilder: (context) => [
for (var readerMode in ReaderMode.values)
PopupMenuItem(
value: readerMode,
child: Row(
children: [
Icon(
Icons.check,
color: _selectedValue == readerMode
? Colors.white
: Colors.transparent,
),
const SizedBox(
width: 7,
),
Text(
getReaderModeName(readerMode),
style: const TextStyle(
color: Colors.white,
fontSize: 12,
),
),
],
)),
],
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.screen_rotation,
),
),
IconButton(
onPressed: () {
_showModalSettings();
},
icon: const Icon(
Icons.settings_rounded,
),
),
],
),
),
),
],
),
),
],
); );
} }
Widget _showPage() { Widget _showPage() {
return Consumer( return _isView
builder: (context, ref, child) { ? Container()
final currentIndex = ref.watch(currentIndexProvider(widget.chapter)); : _showPagesNumber
return _isView ? Align(
? Container() alignment: Alignment.bottomCenter,
: _showPagesNumber child: Consumer(builder: (context, ref, child) {
? Align( final currentIndex =
alignment: Alignment.bottomCenter, ref.watch(currentIndexProvider(widget.chapter));
child: Text( return Text(
'${currentIndex + 1} / ${widget.readerController.getPageLength(widget.url)}', '${currentIndex + 1} / ${widget.readerController.getPageLength(widget.url)}',
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 12.0, fontSize: 12.0,
shadows: <Shadow>[ shadows: <Shadow>[
Shadow(offset: Offset(0.0, 0.0), blurRadius: 10.0) Shadow(offset: Offset(0.0, 0.0), blurRadius: 10.0)
], ],
),
textAlign: TextAlign.center,
), ),
) textAlign: TextAlign.center,
: Container(); );
}, }),
); )
: Container();
} }
_isViewFunction() { _isViewFunction() {
@ -1184,3 +1199,76 @@ class _MangaChapterPageGalleryState
))); )));
} }
} }
_isolateService(String data) async {
late Isar isarIsolate;
isarIsolate = await StorageProvider().initDB(jsonDecode(data)["path"]);
Chapter? chapter =
isarIsolate.chapters.getSync(jsonDecode(data)["chapterId"]);
Manga? manga = chapter!.manga.value!;
Settings? isarIsolateSettings = isarIsolate.settings.getSync(227)!;
bool incognitoMode = isarIsolate.settings.getSync(227)!.incognitoMode!;
int pageIndex = jsonDecode(data)["pageIndex"];
//setMangaHistoryUpdate
if (!incognitoMode) {
isarIsolate.writeTxnSync(() {
Manga? manga = chapter.manga.value;
manga!.lastRead = DateTime.now().millisecondsSinceEpoch;
isarIsolate.mangas.putSync(manga);
});
History? history;
final empty =
isarIsolate.historys.filter().mangaIdEqualTo(manga.id).isEmptySync();
if (empty) {
history = History(
mangaId: manga.id,
date: DateTime.now().millisecondsSinceEpoch.toString())
..chapter.value = chapter;
} else {
history = (isarIsolate.historys
.filter()
.mangaIdEqualTo(manga.id)
.findFirstSync())!
..chapter.value = chapter
..date = DateTime.now().millisecondsSinceEpoch.toString();
}
isarIsolate.writeTxnSync(() {
isarIsolate.historys.putSync(history!);
history.chapter.saveSync();
});
}
//setPageIndex
if (!incognitoMode) {
List<ChapterPageIndex>? chapterPageIndexs = [];
for (var chapterPageIndex
in isarIsolateSettings.chapterPageIndexList ?? []) {
if (chapterPageIndex.chapterId != chapter.id) {
chapterPageIndexs.add(chapterPageIndex);
}
}
chapterPageIndexs.add(ChapterPageIndex()
..chapterId = chapter.id
..index = pageIndex);
isarIsolate.writeTxnSync(() => isarIsolate.settings.putSync(
isarIsolateSettings..chapterPageIndexList = chapterPageIndexs));
}
//setChapterPageLastRead
if (!incognitoMode) {
final chap = chapter;
isarIsolate.writeTxnSync(() {
chap.isRead = (pageIndex + 1) ==
isarIsolateSettings.chapterPageUrlsList!
.where((element) => element.chapterId == chapter.id)
.first
.urls!
.length;
chap.lastPageRead = (pageIndex + 1).toString();
isarIsolate.chapters.putSync(chap);
});
}
}

View file

@ -1,10 +1,17 @@
// ignore_for_file: depend_on_referenced_packages // ignore_for_file: depend_on_referenced_packages
import 'dart:io'; import 'dart:io';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart'; import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/chapter.dart'; import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/history.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart'; import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/source.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:path/path.dart' as path;
class StorageProvider { class StorageProvider {
RegExp regExpChar = RegExp(r'[^a-zA-Z0-9 .()\-\s]'); RegExp regExpChar = RegExp(r'[^a-zA-Z0-9 .()\-\s]');
@ -67,4 +74,43 @@ class StorageProvider {
return Directory( return Directory(
"${dir!.path}/downloads/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceAll(regExpChar, '_')}/"); "${dir!.path}/downloads/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceAll(regExpChar, '_')}/");
} }
Future<Directory?> getDatabaseDirectory() async {
final dir = await getApplicationDocumentsDirectory();
if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
return dir;
} else {
String dbDir = path.join(dir.path, 'Mangayomi', 'databases');
await Directory(dbDir).create(recursive: true);
return Directory(dbDir);
}
}
Future<Isar> initDB(String? path) async {
Directory? dir;
if (path == null) {
dir = await getDatabaseDirectory();
} else {
dir = Directory(path);
}
final isar = Isar.openSync([
MangaSchema,
ChapterSchema,
CategorySchema,
HistorySchema,
DownloadSchema,
SourceSchema,
SettingsSchema
], directory: dir!.path, name: "mangayomiDb");
if (isar.settings.filter().idEqualTo(227).isEmptySync()) {
isar.writeTxnSync(
() {
isar.settings.putSync(Settings());
},
);
}
return isar;
}
} }