mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-01-11 22:40:36 +00:00
Compare commits
112 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89dd50dc25 | ||
|
|
1f3fe65945 | ||
|
|
88f8d7b4be | ||
|
|
83b7d31e0a | ||
|
|
40fdfc2592 | ||
|
|
74b194602c | ||
|
|
b9f9a8398f | ||
|
|
9458ae120b | ||
|
|
701a696820 | ||
|
|
db24951673 | ||
|
|
7c4c8d8a20 | ||
|
|
6b70fff6cc | ||
|
|
2365e28a1a | ||
|
|
922582b270 | ||
|
|
79ee4b4fc8 | ||
|
|
c8328fa347 | ||
|
|
a63f0d67bd | ||
|
|
2c92d74a03 | ||
|
|
a2a10a799d | ||
|
|
ba77c5baea | ||
|
|
4e2d8b0038 | ||
|
|
821cbfa0dd | ||
|
|
4fb9f0a9df | ||
|
|
1ac605e30a | ||
|
|
9efd76581f | ||
|
|
7664e38cfd | ||
|
|
42f1dcff92 | ||
|
|
86fb19ecb2 | ||
|
|
bdcd28488e | ||
|
|
30e6d50210 | ||
|
|
66b508d65d | ||
|
|
004885d557 | ||
|
|
e463cce61a | ||
|
|
67a83c0e6a | ||
|
|
da566d3d0b | ||
|
|
c911594e73 | ||
|
|
9bd8a62d31 | ||
|
|
53cd2101f4 | ||
|
|
4e18e18489 | ||
|
|
481deb1344 | ||
|
|
344533aeb1 | ||
|
|
e40e1b8fe6 | ||
|
|
b5d37caaa9 | ||
|
|
e342fe16fb | ||
|
|
390e6fed46 | ||
|
|
19a051b660 | ||
|
|
5f7ea7fcf4 | ||
|
|
0f83899bac | ||
|
|
a078b59678 | ||
|
|
0ed8ee2cd2 | ||
|
|
67dee18776 | ||
|
|
76645d97c1 | ||
|
|
8fe910900b | ||
|
|
1e469614d9 | ||
|
|
284fccd1ef | ||
|
|
9ac6237caf | ||
|
|
0bfcdaddf4 | ||
|
|
fc49b33826 | ||
|
|
23e41373dc | ||
|
|
6e4d3dd52e | ||
|
|
2cade3db56 | ||
|
|
1b708d6884 | ||
|
|
77357312a0 | ||
|
|
85ff4d7d4c | ||
|
|
da7c32f71e | ||
|
|
e48c475fcb | ||
|
|
4e9af30e8e | ||
|
|
0789f4c85a | ||
|
|
3f065feeef | ||
|
|
23ff95afce | ||
|
|
04267b7a50 | ||
|
|
782d3963c1 | ||
|
|
29091e4b5f | ||
|
|
a306b10e5e | ||
|
|
3a1c69ef3f | ||
|
|
91b8c08658 | ||
|
|
a6df770275 | ||
|
|
9b5bae831e | ||
|
|
958e91ac9a | ||
|
|
6e5322137e | ||
|
|
30c74423ad | ||
|
|
c7e648a6d9 | ||
|
|
33152fc035 | ||
|
|
5fdbf530cb | ||
|
|
5c34dcab9a | ||
|
|
cc84c33c25 | ||
|
|
e0ecc94869 | ||
|
|
01b3ed9f24 | ||
|
|
b44cf29b2c | ||
|
|
57fcb9e1c9 | ||
|
|
485696ea3f | ||
|
|
b6eb5f2f3f | ||
|
|
c2a1e5ee17 | ||
|
|
adcde15d0e | ||
|
|
26362fe556 | ||
|
|
405c3d8e35 | ||
|
|
ee46f8a8bc | ||
|
|
f06df9b3b1 | ||
|
|
1d81906c4f | ||
|
|
6a099415db | ||
|
|
9e9ffb4e79 | ||
|
|
18e8abce94 | ||
|
|
20f8f1ad7c | ||
|
|
f2fbaf5ec5 | ||
|
|
cf871f5d7c | ||
|
|
dc40dc28d4 | ||
|
|
1cc40a2f2f | ||
|
|
afc4c620f8 | ||
|
|
29fe96151d | ||
|
|
daa205044f | ||
|
|
a8f78d41fb | ||
|
|
f7887dd0dc |
214 changed files with 7751 additions and 5306 deletions
2
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
2
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
|
|
@ -74,7 +74,7 @@ body:
|
|||
required: true
|
||||
- label: I have written a short but informative title.
|
||||
required: true
|
||||
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/kodjodevf/mangayomi-extensions/issues/new/choose).
|
||||
- label: If this is an issue with an extension, I should be opening an issue in the extension's repository.
|
||||
required: true
|
||||
- label: I have updated all installed extensions.
|
||||
required: true
|
||||
|
|
|
|||
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
|
|
@ -71,13 +71,6 @@ jobs:
|
|||
mv app-armeabi-v7a-release.apk Mangayomi-${{ github.ref_name }}-android-armeabi-v7a.apk
|
||||
mv app-x86_64-release.apk Mangayomi-${{ github.ref_name }}-android-x86_64.apk
|
||||
|
||||
- name: build android apk (all architectures)
|
||||
run: |
|
||||
export GRADLE_OPTS="-Xmx4096m -XX:MaxMetaspaceSize=512m -XX:+UseG1GC"
|
||||
flutter build apk --release --verbose
|
||||
cd build/app/outputs/flutter-apk
|
||||
mv app-release.apk Mangayomi-${{ github.ref_name }}-android-all.apk
|
||||
|
||||
- name: upload artifact android apks
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
|
@ -189,7 +182,7 @@ jobs:
|
|||
pod update
|
||||
cd ..
|
||||
flutter build macos --release --verbose
|
||||
brew install create-dmg
|
||||
brew install create-dmg
|
||||
create-dmg --volname Mangayomi-${{ github.ref_name }}-macos --window-pos 200 120 --window-size 800 450 --icon-size 100 --app-drop-link 600 185 Mangayomi-${{ github.ref_name }}-macos.dmg build/macos/Build/Products/Release/Mangayomi.app
|
||||
|
||||
- name: upload artifact macos dmg
|
||||
|
|
@ -314,6 +307,11 @@ jobs:
|
|||
# Copy built files
|
||||
cp -r build/linux/x64/release/bundle/* AppDir/usr/bin/
|
||||
cp -rL linux/packaging/icons/* AppDir/usr/share/icons
|
||||
# AppImage fix: Create Symlink AppDir/usr/bin/lib/libmpv.so to AppDir/usr/lib/libmpv.so.2
|
||||
if [ ! -e AppDir/usr/bin/lib/libmpv.so ]; then
|
||||
mkdir -p AppDir/usr/lib
|
||||
ln -s libmpv.so.2 AppDir/usr/lib/libmpv.so
|
||||
fi
|
||||
# Scan AppDir/usr/bin/lib for existing libraries to exclude them from linuxdeploy packaging
|
||||
EXCLUDE_LIBS=$(find AppDir/usr/bin/lib -type f -name "*.so*" -exec basename {} \; | sort -u)
|
||||
# Add --exclude-library flag to each found library
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
PODS:
|
||||
- app_links (6.4.1):
|
||||
- Flutter
|
||||
- audio_session (0.0.1):
|
||||
- app_links (7.0.0):
|
||||
- Flutter
|
||||
- connectivity_plus (0.0.1):
|
||||
- Flutter
|
||||
|
|
@ -57,9 +55,8 @@ PODS:
|
|||
- Flutter
|
||||
- isar_community_flutter_libs (1.0.0):
|
||||
- Flutter
|
||||
- just_audio (0.0.1):
|
||||
- m_extension_server (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- media_kit_libs_ios_video (1.0.4):
|
||||
- Flutter
|
||||
- media_kit_video (0.0.1):
|
||||
|
|
@ -81,26 +78,16 @@ PODS:
|
|||
- SDWebImage/Core (5.17.0)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
- sqflite_darwin (0.0.4):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- SwiftyGif (5.4.4)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
- video_player_avfoundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- volume_controller (0.0.1):
|
||||
- Flutter
|
||||
- wakelock_plus (0.0.1):
|
||||
- Flutter
|
||||
- webview_flutter_wkwebview (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
|
||||
DEPENDENCIES:
|
||||
- app_links (from `.symlinks/plugins/app_links/ios`)
|
||||
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||
|
|
@ -110,7 +97,7 @@ DEPENDENCIES:
|
|||
- flutter_qjs (from `.symlinks/plugins/flutter_qjs/ios`)
|
||||
- flutter_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`)
|
||||
- isar_community_flutter_libs (from `.symlinks/plugins/isar_community_flutter_libs/ios`)
|
||||
- just_audio (from `.symlinks/plugins/just_audio/darwin`)
|
||||
- m_extension_server (from `.symlinks/plugins/m_extension_server/ios`)
|
||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
|
|
@ -119,12 +106,9 @@ DEPENDENCIES:
|
|||
- rust_lib_mangayomi (from `.symlinks/plugins/rust_lib_mangayomi/ios`)
|
||||
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
|
||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
|
||||
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
|
|
@ -137,8 +121,6 @@ SPEC REPOS:
|
|||
EXTERNAL SOURCES:
|
||||
app_links:
|
||||
:path: ".symlinks/plugins/app_links/ios"
|
||||
audio_session:
|
||||
:path: ".symlinks/plugins/audio_session/ios"
|
||||
connectivity_plus:
|
||||
:path: ".symlinks/plugins/connectivity_plus/ios"
|
||||
device_info_plus:
|
||||
|
|
@ -157,8 +139,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/flutter_web_auth_2/ios"
|
||||
isar_community_flutter_libs:
|
||||
:path: ".symlinks/plugins/isar_community_flutter_libs/ios"
|
||||
just_audio:
|
||||
:path: ".symlinks/plugins/just_audio/darwin"
|
||||
m_extension_server:
|
||||
:path: ".symlinks/plugins/m_extension_server/ios"
|
||||
media_kit_libs_ios_video:
|
||||
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
|
||||
media_kit_video:
|
||||
|
|
@ -175,22 +157,15 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/screen_brightness_ios/ios"
|
||||
share_plus:
|
||||
:path: ".symlinks/plugins/share_plus/ios"
|
||||
sqflite_darwin:
|
||||
:path: ".symlinks/plugins/sqflite_darwin/darwin"
|
||||
url_launcher_ios:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
video_player_avfoundation:
|
||||
:path: ".symlinks/plugins/video_player_avfoundation/darwin"
|
||||
volume_controller:
|
||||
:path: ".symlinks/plugins/volume_controller/ios"
|
||||
wakelock_plus:
|
||||
:path: ".symlinks/plugins/wakelock_plus/ios"
|
||||
webview_flutter_wkwebview:
|
||||
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
app_links: 3dbc685f76b1693c66a6d9dd1e9ab6f73d97dc0a
|
||||
audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0
|
||||
app_links: a754cbec3c255bd4bbb4d236ecc06f28cd9a7ce8
|
||||
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
|
||||
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
||||
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
|
||||
|
|
@ -202,24 +177,21 @@ SPEC CHECKSUMS:
|
|||
flutter_qjs: 1d5918f42171154e88dd545dd45f126c0291976f
|
||||
flutter_web_auth_2: 3464a7c16dc6480b6194fc89913bae6e82f28405
|
||||
isar_community_flutter_libs: bede843185a61a05ff364a05c9b23209523f7e0d
|
||||
just_audio: 4e391f57b79cad2b0674030a00453ca5ce817eed
|
||||
m_extension_server: 6946ec189542b271dbd15629b9498595f1036761
|
||||
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
||||
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
|
||||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
rust_lib_mangayomi: 360a904274b47351a0f7c26d3ce5aa6392bb8db3
|
||||
screen_brightness_ios: 9953fd7da5bd480f1a93990daeec2eb42d4f3b52
|
||||
SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9
|
||||
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
|
||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||
video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
|
||||
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
|
||||
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
|
||||
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
||||
webview_flutter_wkwebview: 8ebf4fded22593026f7dbff1fbff31ea98573c8d
|
||||
|
||||
PODFILE CHECKSUM: a57f30d18f102dd3ce366b1d62a55ecbef2158e5
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class DartExtensionService implements ExtensionService {
|
|||
|
||||
interpreter.execute(
|
||||
source: source.sourceCode!.replaceAll('Client(source)', 'Client()'),
|
||||
args: source.toMSource(),
|
||||
positionalArgs: [source.toMSource()],
|
||||
);
|
||||
return interpreter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:epubx/epubx.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_qjs/flutter_qjs.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:path/path.dart' as p;
|
||||
|
|
@ -25,7 +25,12 @@ class JsUtils {
|
|||
}
|
||||
|
||||
runtime.onMessage('log', (dynamic args) {
|
||||
Logger.add(LoggerLevel.warning, "${args[0]}");
|
||||
if (kDebugMode || useLogger) {
|
||||
// ignore: avoid_print
|
||||
print("LoggerLevel.warning:${args[0]}");
|
||||
Logger.add(LoggerLevel.warning, "${args[0]}");
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
runtime.onMessage('cryptoHandler', (dynamic args) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_qjs/flutter_qjs.dart';
|
||||
import 'package:mangayomi/utils/log/log.dart';
|
||||
|
||||
|
|
@ -7,7 +8,11 @@ class JsLibs {
|
|||
|
||||
void init() {
|
||||
runtime.onMessage('log', (dynamic args) {
|
||||
Logger.add(LoggerLevel.warning, "${args[0]}");
|
||||
if (kDebugMode || useLogger) {
|
||||
// ignore: avoid_print
|
||||
print("LoggerLevel.warning:${args[0]}");
|
||||
Logger.add(LoggerLevel.warning, "${args[0]}");
|
||||
}
|
||||
return null;
|
||||
});
|
||||
runtime.onMessage('urlencode', (dynamic args) {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import 'package:mangayomi/eval/model/m_chapter.dart';
|
|||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/page.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/services/http/m_client.dart';
|
||||
|
|
@ -55,7 +57,9 @@ class MihonExtensionService implements ExtensionService {
|
|||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
headers: getCookie(),
|
||||
);
|
||||
hasError(res);
|
||||
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
final pages = MangaPages.fromJson(data, source.itemType);
|
||||
return MPages(
|
||||
|
|
@ -90,7 +94,9 @@ class MihonExtensionService implements ExtensionService {
|
|||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
headers: getCookie(),
|
||||
);
|
||||
hasError(res);
|
||||
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
final pages = MangaPages.fromJson(data, source.itemType);
|
||||
return MPages(
|
||||
|
|
@ -126,7 +132,9 @@ class MihonExtensionService implements ExtensionService {
|
|||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
headers: getCookie(),
|
||||
);
|
||||
hasError(res);
|
||||
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
final pages = MangaPages.fromJson(data, source.itemType);
|
||||
return MPages(
|
||||
|
|
@ -161,7 +169,9 @@ class MihonExtensionService implements ExtensionService {
|
|||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
headers: getCookie(),
|
||||
);
|
||||
hasError(res);
|
||||
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
final chapters = await getChapterList(url);
|
||||
return MManga(
|
||||
|
|
@ -196,7 +206,9 @@ class MihonExtensionService implements ExtensionService {
|
|||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
headers: getCookie(),
|
||||
);
|
||||
hasError(res);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
return data
|
||||
.map(
|
||||
|
|
@ -222,7 +234,9 @@ class MihonExtensionService implements ExtensionService {
|
|||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
headers: getCookie(),
|
||||
);
|
||||
hasError(res);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
return data.map((e) => PageUrl(e['imageUrl'])).toList();
|
||||
}
|
||||
|
|
@ -237,7 +251,9 @@ class MihonExtensionService implements ExtensionService {
|
|||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
headers: getCookie(),
|
||||
);
|
||||
hasError(res);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
return data.map((e) {
|
||||
final tempHeaders =
|
||||
|
|
@ -336,4 +352,29 @@ class MihonExtensionService implements ExtensionService {
|
|||
}
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Map<String, String> getCookie() {
|
||||
final userAgent = isar.settings.getSync(227)!.userAgent;
|
||||
return {
|
||||
...MClient.getCookiesPref(source.baseUrl!),
|
||||
if (userAgent != null) 'user-agent': userAgent,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void hasError(Response response) {
|
||||
try {
|
||||
final errorMessage = jsonDecode(response.body)['error'];
|
||||
final code = jsonDecode(response.body)['code'];
|
||||
if (errorMessage != null && code != null) {
|
||||
if ((code as int) == 403) {
|
||||
throw "errorMessage: Failed to bypass Cloudflare.\n\n\nYou can try to bypass it manually in the webview \n\n\nstatusCode: 403";
|
||||
}
|
||||
throw "errorMessage: $errorMessage \n\n\nstatusCode: $code";
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.toString().startsWith('errorMessage:')) {
|
||||
throw e.toString().replaceFirst('errorMessage: ', '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,14 +75,12 @@ class MBridge {
|
|||
var query = htmlXPath.query(xpath);
|
||||
if (query.nodes.length > 1) {
|
||||
for (var element in query.attrs) {
|
||||
attrs.add(element!.trim().trimLeft().trimRight());
|
||||
attrs.add(element!.trim());
|
||||
}
|
||||
}
|
||||
//Return one attr
|
||||
else if (query.nodes.length == 1) {
|
||||
String attr = query.attr != null
|
||||
? query.attr!.trim().trimLeft().trimRight()
|
||||
: "";
|
||||
String attr = query.attr != null ? query.attr!.trim() : "";
|
||||
if (attr.isNotEmpty) {
|
||||
attrs = [attr];
|
||||
}
|
||||
|
|
@ -102,7 +100,7 @@ class MBridge {
|
|||
statusMap = element;
|
||||
for (var element in statusMap.entries) {
|
||||
if (element.key.toString().toLowerCase().contains(
|
||||
status.toLowerCase().trim().trimLeft().trimRight(),
|
||||
status.toLowerCase().trim(),
|
||||
)) {
|
||||
return switch (element.value as int) {
|
||||
0 => Status.ongoing,
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ const SourcePreferenceSchema = CollectionSchema(
|
|||
getId: _sourcePreferenceGetId,
|
||||
getLinks: _sourcePreferenceGetLinks,
|
||||
attach: _sourcePreferenceAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _sourcePreferenceEstimateSize(
|
||||
|
|
@ -993,7 +993,7 @@ const SourcePreferenceStringValueSchema = CollectionSchema(
|
|||
getId: _sourcePreferenceStringValueGetId,
|
||||
getLinks: _sourcePreferenceStringValueGetLinks,
|
||||
attach: _sourcePreferenceStringValueAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _sourcePreferenceStringValueEstimateSize(
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@
|
|||
"downloaded_only": "المحملة فقط",
|
||||
"downloaded_only_description": "إظهار الإدخالات المحملة فقط في مكتبتك",
|
||||
"concurrent_downloads": "التحميلات المتزامنة",
|
||||
"logs_on": "تفعيل التسجيل",
|
||||
"share_app_logs": "مشاركة سجلات التطبيق",
|
||||
"no_app_logs": "لا يوجد ملف log.txt!",
|
||||
"failed": "فشل!",
|
||||
|
|
@ -560,4 +561,4 @@
|
|||
"show_scroll_percentage": "إظهار نسبة التمرير",
|
||||
"remove_extra_paragraph_spacing": "إزالة المسافات الإضافية بين الفقرات",
|
||||
"select_label_color": "تحديد لون {label}"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@
|
|||
"default_subtitle_language": "ডিফল্ট উপশিৰোনাম ভাষা",
|
||||
"follow_system_theme": "ছিষ্টেম থিম অনুসৰণ কৰক",
|
||||
"concurrent_downloads": "সমসাময়িক ডাউনলোড",
|
||||
"logs_on": "লগিং সক্ষম কৰক",
|
||||
"share_app_logs": "এপ লগ শ্বেয়াৰ কৰক",
|
||||
"no_app_logs": "কোনো log.txt ফাইল উপলব্ধ নাই!",
|
||||
"failed": "বিফল!",
|
||||
|
|
|
|||
|
|
@ -465,6 +465,7 @@
|
|||
"downloaded_only": "Nur heruntergeladene",
|
||||
"downloaded_only_description": "Nur heruntergeladene Einträge in deiner Bibliothek anzeigen",
|
||||
"concurrent_downloads": "Gleichzeitige Downloads",
|
||||
"logs_on": "Protokollierung aktivieren",
|
||||
"share_app_logs": "App-Protokolle teilen",
|
||||
"no_app_logs": "Keine log.txt Datei verfügbar!",
|
||||
"failed": "Fehlgeschlagen!",
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@
|
|||
"nsfw_sources_info": "This does not prevent unofficial or potentially incorrectly flagged extensions from surfacing NSFW (18+) content within the app",
|
||||
"version": "Version",
|
||||
"check_for_update": "Check for update",
|
||||
"logs_on": "Enable logging",
|
||||
"share_app_logs": "Share app logs",
|
||||
"no_app_logs": "No log.txt available!",
|
||||
"failed": "Failed!",
|
||||
|
|
@ -559,5 +560,8 @@
|
|||
"line_height": "Line Height",
|
||||
"show_scroll_percentage": "Show Scroll Percentage",
|
||||
"remove_extra_paragraph_spacing": "Remove Extra Paragraph Spacing",
|
||||
"select_label_color": "Select {label} Color"
|
||||
"select_label_color": "Select {label} Color",
|
||||
"default_user_agent": "Defaul user agent",
|
||||
"forceLandscapeMode": "Force landscape mode",
|
||||
"forceLandscapeModeSubtitle": "Force the player to use landscape orientation."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@
|
|||
"downloaded_only": "Solo descargados",
|
||||
"downloaded_only_description": "Mostrar solo entradas descargadas en tu biblioteca",
|
||||
"concurrent_downloads": "Descargas simultáneas",
|
||||
"logs_on": "Activar registro",
|
||||
"share_app_logs": "Compartir registros de la aplicación",
|
||||
"no_app_logs": "¡No hay archivo log.txt disponible!",
|
||||
"failed": "¡Fallido!",
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@
|
|||
"downloaded_only": "Solo descargados",
|
||||
"downloaded_only_description": "Mostrar solo entradas descargadas en tu biblioteca",
|
||||
"concurrent_downloads": "Descargas simultáneas",
|
||||
"logs_on": "Habilitar registro",
|
||||
"share_app_logs": "Compartir registros de la aplicación",
|
||||
"no_app_logs": "¡No hay archivo log.txt disponible!",
|
||||
"failed": "¡Fallido!",
|
||||
|
|
|
|||
|
|
@ -455,6 +455,7 @@
|
|||
"downloaded_only": "Téléchargés uniquement",
|
||||
"downloaded_only_description": "Afficher uniquement les entrées téléchargées dans votre bibliothèque",
|
||||
"concurrent_downloads": "Téléchargements simultanés",
|
||||
"logs_on": "Activer la journalisation",
|
||||
"share_app_logs": "Partager les journaux de l'application",
|
||||
"no_app_logs": "Aucun fichier log.txt disponible !",
|
||||
"failed": "Échoué !",
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@
|
|||
"default_subtitle_language": "डिफ़ॉल्ट उपशीर्षक भाषा",
|
||||
"follow_system_theme": "सिस्टम थीम का पालन करें",
|
||||
"concurrent_downloads": "समवर्ती डाउनलोड",
|
||||
"logs_on": "लॉगिंग सक्षम करें",
|
||||
"share_app_logs": "ऐप लॉग साझा करें",
|
||||
"no_app_logs": "कोई log.txt फ़ाइल उपलब्ध नहीं!",
|
||||
"failed": "विफल!",
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@
|
|||
"downloaded_only": "Hanya yang diunduh",
|
||||
"downloaded_only_description": "Hanya tampilkan entri yang diunduh di perpustakaan Anda",
|
||||
"concurrent_downloads": "Unduhan bersamaan",
|
||||
"logs_on": "Aktifkan pencatatan",
|
||||
"share_app_logs": "Bagikan log aplikasi",
|
||||
"no_app_logs": "Tidak ada file log.txt tersedia!",
|
||||
"failed": "Gagal!",
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@
|
|||
"downloaded_only": "Solo scaricati",
|
||||
"downloaded_only_description": "Mostra solo le voci scaricate nella tua libreria",
|
||||
"concurrent_downloads": "Download simultanei",
|
||||
"logs_on": "Abilita registrazione",
|
||||
"share_app_logs": "Condividi i log dell'app",
|
||||
"no_app_logs": "Nessun file log.txt disponibile!",
|
||||
"failed": "Fallito!",
|
||||
|
|
|
|||
|
|
@ -304,6 +304,7 @@
|
|||
"default_subtitle_language": "デフォルト字幕言語",
|
||||
"follow_system_theme": "システムテーマに従う",
|
||||
"concurrent_downloads": "同時ダウンロード",
|
||||
"logs_on": "ログを有効にする",
|
||||
"share_app_logs": "アプリログを共有",
|
||||
"no_app_logs": "log.txtファイルが利用できません!",
|
||||
"failed": "失敗!",
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@
|
|||
"downloaded_only": "Apenas baixados",
|
||||
"downloaded_only_description": "Mostrar apenas entradas baixadas na sua biblioteca",
|
||||
"concurrent_downloads": "Downloads simultâneos",
|
||||
"logs_on": "Ativar registro",
|
||||
"share_app_logs": "Compartilhar logs do aplicativo",
|
||||
"no_app_logs": "Nenhum arquivo log.txt disponível!",
|
||||
"failed": "Falhou!",
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@
|
|||
"downloaded_only": "Apenas baixados",
|
||||
"downloaded_only_description": "Mostrar apenas entradas baixadas na sua biblioteca",
|
||||
"concurrent_downloads": "Downloads simultâneos",
|
||||
"logs_on": "Ativar registro",
|
||||
"share_app_logs": "Compartilhar logs do aplicativo",
|
||||
"no_app_logs": "Nenhum arquivo log.txt disponível!",
|
||||
"failed": "Falhou!",
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@
|
|||
"downloaded_only": "Только загруженные",
|
||||
"downloaded_only_description": "Показывать только загруженные записи в вашей библиотеке",
|
||||
"concurrent_downloads": "Одновременные загрузки",
|
||||
"logs_on": "Включить ведение журнала",
|
||||
"share_app_logs": "Поделиться журналами приложения",
|
||||
"no_app_logs": "Файл log.txt недоступен!",
|
||||
"failed": "Не удалось!",
|
||||
|
|
|
|||
|
|
@ -452,6 +452,7 @@
|
|||
"downloaded_only": "ที่ดาวน์โหลดแล้วเท่านั้น",
|
||||
"downloaded_only_description": "แสดงเฉพาะรายการที่ดาวน์โหลดแล้วในห้องสมุดของคุณ",
|
||||
"concurrent_downloads": "ดาวน์โหลดพร้อมกัน",
|
||||
"logs_on": "เปิดการบันทึก",
|
||||
"share_app_logs": "แชร์บันทึกแอป",
|
||||
"no_app_logs": "ไม่มีไฟล์ log.txt!",
|
||||
"failed": "ล้มเหลว!",
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@
|
|||
"downloaded_only": "Sadece indirilmiş",
|
||||
"downloaded_only_description": "Kütüphanenizde yalnızca indirilmiş girişleri göster",
|
||||
"concurrent_downloads": "Eş zamanlı indirmeler",
|
||||
"logs_on": "Günlük kaydını etkinleştir",
|
||||
"share_app_logs": "Uygulama günlüklerini paylaş",
|
||||
"no_app_logs": "log.txt dosyası yok!",
|
||||
"failed": "Başarısız!",
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@
|
|||
"downloaded_only": "仅已下载",
|
||||
"downloaded_only_description": "仅显示库中已下载的条目",
|
||||
"concurrent_downloads": "并发下载",
|
||||
"logs_on": "启用日志",
|
||||
"share_app_logs": "分享应用日志",
|
||||
"no_app_logs": "没有可用的 log.txt 文件!",
|
||||
"failed": "失败!",
|
||||
|
|
@ -562,5 +563,8 @@
|
|||
"line_height": "行高",
|
||||
"show_scroll_percentage": "显示滚动百分比",
|
||||
"remove_extra_paragraph_spacing": "删除额外的段落间距",
|
||||
"select_label_color": "选择 {label} 颜色"
|
||||
}
|
||||
"select_label_color": "选择 {label} 颜色",
|
||||
"default_user_agent": "默认用户代理",
|
||||
"forceLandscapeMode": "强制横屏模式",
|
||||
"forceLandscapeModeSubtitle": "强制播放器使用横屏方向。"
|
||||
}
|
||||
|
|
@ -935,6 +935,12 @@ abstract class AppLocalizations {
|
|||
/// **'Check for update'**
|
||||
String get check_for_update;
|
||||
|
||||
/// No description provided for @logs_on.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enable logging'**
|
||||
String get logs_on;
|
||||
|
||||
/// No description provided for @share_app_logs.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -3430,6 +3436,24 @@ abstract class AppLocalizations {
|
|||
/// In en, this message translates to:
|
||||
/// **'Select {label} Color'**
|
||||
String select_label_color(Object label);
|
||||
|
||||
/// No description provided for @default_user_agent.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Defaul user agent'**
|
||||
String get default_user_agent;
|
||||
|
||||
/// No description provided for @forceLandscapeMode.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Force landscape mode'**
|
||||
String get forceLandscapeMode;
|
||||
|
||||
/// No description provided for @forceLandscapeModeSubtitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Force the player to use landscape orientation.'**
|
||||
String get forceLandscapeModeSubtitle;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
|
|
|||
|
|
@ -434,6 +434,9 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'التحقق من التحديثات';
|
||||
|
||||
@override
|
||||
String get logs_on => 'تفعيل التسجيل';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'مشاركة سجلات التطبيق';
|
||||
|
||||
|
|
@ -1775,4 +1778,14 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'تحديد لون $label';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,6 +436,9 @@ class AppLocalizationsAs extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'আপডেটৰ বাবে পৰীক্ষা কৰক';
|
||||
|
||||
@override
|
||||
String get logs_on => 'লগিং সক্ষম কৰক';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'এপ লগ শ্বেয়াৰ কৰক';
|
||||
|
||||
|
|
@ -1781,4 +1784,14 @@ class AppLocalizationsAs extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return '$label ৰং নিৰ্বাচন কৰক';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,6 +438,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Auf Aktualisierung prüfen';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Protokollierung aktivieren';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'App-Protokolle teilen';
|
||||
|
||||
|
|
@ -1796,4 +1799,14 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'Farbe für $label auswählen';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,6 +436,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Check for update';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Enable logging';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Share app logs';
|
||||
|
||||
|
|
@ -1775,4 +1778,14 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'Select $label Color';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,6 +440,9 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Buscar actualizaciones';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Activar registro';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Compartir registros de la aplicación';
|
||||
|
||||
|
|
@ -1804,6 +1807,16 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'Seleccionar color de $label';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
||||
/// The translations for Spanish Castilian, as used in Latin America and the Caribbean (`es_419`).
|
||||
|
|
@ -2242,6 +2255,9 @@ class AppLocalizationsEs419 extends AppLocalizationsEs {
|
|||
@override
|
||||
String get check_for_update => 'Buscar actualizaciones';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Habilitar registro';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Compartir registros de la aplicación';
|
||||
|
||||
|
|
|
|||
|
|
@ -442,6 +442,9 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Rechercher des mises à jour';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Activer la journalisation';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Partager les journaux de l\'application';
|
||||
|
||||
|
|
@ -1804,4 +1807,14 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'Sélectionner la couleur $label';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,6 +436,9 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'अपडेट के लिए जांचें';
|
||||
|
||||
@override
|
||||
String get logs_on => 'लॉगिंग सक्षम करें';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'ऐप लॉग साझा करें';
|
||||
|
||||
|
|
@ -1781,4 +1784,14 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return '$label रंग चुनें';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,6 +440,9 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Periksa Pembaruan';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Aktifkan pencatatan';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Bagikan log aplikasi';
|
||||
|
||||
|
|
@ -1787,4 +1790,14 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'Pilih Warna $label';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,6 +440,9 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Controlla aggiornamenti';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Abilita registrazione';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Condividi i log dell\'app';
|
||||
|
||||
|
|
@ -1801,4 +1804,14 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'Seleziona colore $label';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -431,6 +431,9 @@ class AppLocalizationsJa extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Check for update';
|
||||
|
||||
@override
|
||||
String get logs_on => 'ログを有効にする';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'アプリログを共有';
|
||||
|
||||
|
|
@ -1752,4 +1755,14 @@ class AppLocalizationsJa extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return '$labelの色を選択';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,6 +440,9 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Verificar atualização';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Ativar registro';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Compartilhar logs do aplicativo';
|
||||
|
||||
|
|
@ -1799,6 +1802,16 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'Selecionar cor de $label';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
||||
/// The translations for Portuguese, as used in Brazil (`pt_BR`).
|
||||
|
|
@ -2237,6 +2250,9 @@ class AppLocalizationsPtBr extends AppLocalizationsPt {
|
|||
@override
|
||||
String get check_for_update => 'Verificar atualização';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Ativar registro';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Compartilhar logs do aplicativo';
|
||||
|
||||
|
|
|
|||
|
|
@ -441,6 +441,9 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Проверить обновления';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Включить ведение журнала';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Поделиться журналами приложения';
|
||||
|
||||
|
|
@ -1804,4 +1807,14 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'Выбрать цвет $label';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,6 +436,9 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'ตรวจสอบการอัพเดท';
|
||||
|
||||
@override
|
||||
String get logs_on => 'เปิดการบันทึก';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'แชร์บันทึกแอป';
|
||||
|
||||
|
|
@ -1775,4 +1778,14 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return 'เลือกสี $label';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,6 +436,9 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => 'Güncelleme Kontrol Et';
|
||||
|
||||
@override
|
||||
String get logs_on => 'Günlük kaydını etkinleştir';
|
||||
|
||||
@override
|
||||
String get share_app_logs => 'Uygulama günlüklerini paylaş';
|
||||
|
||||
|
|
@ -1787,4 +1790,14 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return '$label Rengini Seç';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => 'Defaul user agent';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => 'Force landscape mode';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle =>
|
||||
'Force the player to use landscape orientation.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -427,6 +427,9 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
@override
|
||||
String get check_for_update => '检查更新';
|
||||
|
||||
@override
|
||||
String get logs_on => '启用日志';
|
||||
|
||||
@override
|
||||
String get share_app_logs => '分享应用日志';
|
||||
|
||||
|
|
@ -1733,4 +1736,13 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
String select_label_color(Object label) {
|
||||
return '选择 $label 颜色';
|
||||
}
|
||||
|
||||
@override
|
||||
String get default_user_agent => '默认用户代理';
|
||||
|
||||
@override
|
||||
String get forceLandscapeMode => '强制横屏模式';
|
||||
|
||||
@override
|
||||
String get forceLandscapeModeSubtitle => '强制播放器使用横屏方向。';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_
|
|||
import 'package:mangayomi/l10n/generated/app_localizations.dart';
|
||||
import 'package:mangayomi/services/http/m_client.dart';
|
||||
import 'package:mangayomi/services/isolate_service.dart';
|
||||
import 'package:mangayomi/services/m_extension_server.dart';
|
||||
import 'package:mangayomi/services/download_manager/m_downloader.dart';
|
||||
import 'package:mangayomi/src/rust/frb_generated.dart';
|
||||
import 'package:mangayomi/utils/discord_rpc.dart';
|
||||
import 'package:mangayomi/utils/log/logger.dart';
|
||||
|
|
@ -75,7 +77,6 @@ void main(List<String> args) async {
|
|||
}
|
||||
final storage = StorageProvider();
|
||||
await storage.requestPermission();
|
||||
await _migrateOldLayout();
|
||||
isar = await storage.initDB(null, inspector: kDebugMode);
|
||||
runApp(ProviderScope(child: MyApp(), retry: (retryCount, error) => null));
|
||||
unawaited(_postLaunchInit(storage)); // Defer non-essential async operations
|
||||
|
|
@ -83,6 +84,7 @@ void main(List<String> args) async {
|
|||
|
||||
Future<void> _postLaunchInit(StorageProvider storage) async {
|
||||
await AppLogger.init();
|
||||
unawaited(MDownloader.initializeIsolatePool(poolSize: 6));
|
||||
final hivePath = (Platform.isIOS || Platform.isMacOS)
|
||||
? "databases"
|
||||
: p.join("Mangayomi", "databases");
|
||||
|
|
@ -93,54 +95,7 @@ Future<void> _postLaunchInit(StorageProvider storage) async {
|
|||
await discordRpc?.initialize();
|
||||
}
|
||||
await storage.deleteBtDirectory();
|
||||
}
|
||||
|
||||
/// This can be removed after next release (v0.6.40?)
|
||||
/// It is a one-time thing to migrate the database and folders to the new
|
||||
/// iOS and macOS location (PR #517)
|
||||
Future<void> _migrateOldLayout() async {
|
||||
if (!(Platform.isIOS || Platform.isMacOS)) return;
|
||||
final root = await getApplicationDocumentsDirectory();
|
||||
final oldRoot = Directory(p.join(root.path, 'Mangayomi'));
|
||||
if (!await oldRoot.exists()) return;
|
||||
final newDbDir = Directory(p.join(root.path, 'databases'));
|
||||
await newDbDir.create(recursive: true);
|
||||
// Move database files to new directory
|
||||
for (final filename in [
|
||||
'mangayomiDb.isar',
|
||||
'mangayomiDb.isar.lock',
|
||||
'tracker_library.hive',
|
||||
'tracker_library.lock',
|
||||
]) {
|
||||
final oldFile = File(p.join(root.path, filename));
|
||||
if (await oldFile.exists()) {
|
||||
final newFile = File(p.join(newDbDir.path, filename));
|
||||
await oldFile.rename(newFile.path);
|
||||
}
|
||||
}
|
||||
// Move subfolders up a level
|
||||
for (final sub in ['backup', 'downloads', 'Pictures', 'local']) {
|
||||
final oldSubDir = Directory(p.join(oldRoot.path, sub));
|
||||
final newSubDir = Directory(p.join(root.path, sub));
|
||||
if (!await oldSubDir.exists()) continue;
|
||||
// If by chance newSubDir is empty, safe to rename; otherwise, move contents
|
||||
if (!(await newSubDir.exists())) {
|
||||
await oldSubDir.rename(newSubDir.path);
|
||||
} else {
|
||||
// merge contents
|
||||
await for (final entity in oldSubDir.list()) {
|
||||
await entity.rename(p.join(newSubDir.path, p.basename(entity.path)));
|
||||
}
|
||||
}
|
||||
// remove subfolder if empty
|
||||
if (await oldSubDir.exists() && await oldSubDir.list().isEmpty) {
|
||||
await oldSubDir.delete();
|
||||
}
|
||||
}
|
||||
// Clean up old empty folder
|
||||
if (await oldRoot.exists() && await oldRoot.list().isEmpty) {
|
||||
await oldRoot.delete();
|
||||
}
|
||||
await cfResolutionWebviewServer();
|
||||
}
|
||||
|
||||
class MyApp extends ConsumerStatefulWidget {
|
||||
|
|
@ -166,7 +121,10 @@ class _MyAppState extends ConsumerState<MyApp> {
|
|||
unawaited(ref.read(scanLocalLibraryProvider.future));
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
MExtensionServerPlatform(ref).startServer();
|
||||
if (ref.read(clearChapterCacheOnAppLaunchStateProvider)) {
|
||||
// Watch before calling clearcache to keep it alive, so that _getTotalDiskSpace completes safely
|
||||
ref.watch(totalChapterCacheSizeStateProvider);
|
||||
ref
|
||||
.read(totalChapterCacheSizeStateProvider.notifier)
|
||||
.clearCache(showToast: false);
|
||||
|
|
@ -203,8 +161,10 @@ class _MyAppState extends ConsumerState<MyApp> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
MExtensionServerPlatform(ref).stopServer();
|
||||
_linkSubscription?.cancel();
|
||||
discordRpc?.destroy();
|
||||
stopCfResolutionWebviewServer();
|
||||
AppLogger.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const CategorySchema = CollectionSchema(
|
|||
getId: _categoryGetId,
|
||||
getLinks: _categoryGetLinks,
|
||||
attach: _categoryAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _categoryEstimateSize(
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const ChangedPartSchema = CollectionSchema(
|
|||
getId: _changedPartGetId,
|
||||
getLinks: _changedPartGetLinks,
|
||||
attach: _changedPartAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _changedPartEstimateSize(
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ const ChapterSchema = CollectionSchema(
|
|||
getId: _chapterGetId,
|
||||
getLinks: _chapterGetLinks,
|
||||
attach: _chapterAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _chapterEstimateSize(
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ const CustomButtonSchema = CollectionSchema(
|
|||
getId: _customButtonGetId,
|
||||
getLinks: _customButtonGetLinks,
|
||||
attach: _customButtonAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _customButtonEstimateSize(
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ const DownloadSchema = CollectionSchema(
|
|||
getId: _downloadGetId,
|
||||
getLinks: _downloadGetLinks,
|
||||
attach: _downloadAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _downloadEstimateSize(
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ const HistorySchema = CollectionSchema(
|
|||
getId: _historyGetId,
|
||||
getLinks: _historyGetLinks,
|
||||
attach: _historyAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _historyEstimateSize(
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ const MangaSchema = CollectionSchema(
|
|||
getId: _mangaGetId,
|
||||
getLinks: _mangaGetLinks,
|
||||
attach: _mangaAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _mangaEstimateSize(
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ class Settings {
|
|||
|
||||
int? pagePreloadAmount;
|
||||
|
||||
bool? enableLogs;
|
||||
|
||||
bool? checkForAppUpdates;
|
||||
|
||||
bool? checkForExtensionUpdates;
|
||||
|
|
@ -161,6 +163,8 @@ class Settings {
|
|||
|
||||
bool? fullScreenPlayer;
|
||||
|
||||
bool? forceLandscapePlayer;
|
||||
|
||||
bool? updateProgressAfterReading;
|
||||
|
||||
bool? enableAniSkip;
|
||||
|
|
@ -357,6 +361,7 @@ class Settings {
|
|||
this.sortLibraryAnime,
|
||||
this.pagePreloadAmount = 6,
|
||||
this.scaleType = ScaleType.fitScreen,
|
||||
this.enableLogs = false,
|
||||
this.checkForAppUpdates = true,
|
||||
this.checkForExtensionUpdates = true,
|
||||
this.backgroundColor = BackgroundColor.black,
|
||||
|
|
@ -372,6 +377,7 @@ class Settings {
|
|||
this.defaultDoubleTapToSkipLength = 10,
|
||||
this.defaultPlayBackSpeed = 1.0,
|
||||
this.fullScreenPlayer = false,
|
||||
this.forceLandscapePlayer = false,
|
||||
this.updateProgressAfterReading = true,
|
||||
this.enableAniSkip,
|
||||
this.enableAutoSkip,
|
||||
|
|
@ -482,6 +488,7 @@ class Settings {
|
|||
.map((e) => ChapterPageurls.fromJson(e))
|
||||
.toList();
|
||||
}
|
||||
enableLogs = json['enableLogs'];
|
||||
checkForAppUpdates = json['checkForAppUpdates'];
|
||||
checkForExtensionUpdates = json['checkForExtensionUpdates'];
|
||||
if (json['cookiesList'] != null) {
|
||||
|
|
@ -577,6 +584,7 @@ class Settings {
|
|||
? json['defaultPlayBackSpeed']
|
||||
: (json['defaultPlayBackSpeed'] as int).toDouble();
|
||||
fullScreenPlayer = json['fullScreenPlayer'];
|
||||
forceLandscapePlayer = json['forceLandscapePlayer'];
|
||||
updateProgressAfterReading = json['updateProgressAfterReading'];
|
||||
enableAniSkip = json['enableAniSkip'];
|
||||
enableAutoSkip = json['enableAutoSkip'];
|
||||
|
|
@ -720,6 +728,7 @@ class Settings {
|
|||
?.map((v) => v.toJson())
|
||||
.toList(),
|
||||
'chapterPageUrlsList': chapterPageUrlsList?.map((v) => v.toJson()).toList(),
|
||||
'enableLogs': enableLogs,
|
||||
'checkForAppUpdates': checkForAppUpdates,
|
||||
'checkForExtensionUpdates': checkForExtensionUpdates,
|
||||
'cookiesList': cookiesList,
|
||||
|
|
@ -782,6 +791,7 @@ class Settings {
|
|||
'defaultDoubleTapToSkipLength': defaultDoubleTapToSkipLength,
|
||||
'defaultPlayBackSpeed': defaultPlayBackSpeed,
|
||||
'fullScreenPlayer': fullScreenPlayer,
|
||||
'forceLandscapePlayer': forceLandscapePlayer,
|
||||
'updateProgressAfterReading': updateProgressAfterReading,
|
||||
'enableAniSkip': enableAniSkip,
|
||||
'enableAutoSkip': enableAutoSkip,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -145,7 +145,7 @@ const SourceSchema = CollectionSchema(
|
|||
getId: _sourceGetId,
|
||||
getLinks: _sourceGetLinks,
|
||||
attach: _sourceAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _sourceEstimateSize(
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ const SyncPreferenceSchema = CollectionSchema(
|
|||
getId: _syncPreferenceGetId,
|
||||
getLinks: _syncPreferenceGetLinks,
|
||||
attach: _syncPreferenceAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _syncPreferenceEstimateSize(
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ const TrackSchema = CollectionSchema(
|
|||
getId: _trackGetId,
|
||||
getLinks: _trackGetLinks,
|
||||
attach: _trackAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _trackEstimateSize(
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ const TrackPreferenceSchema = CollectionSchema(
|
|||
getId: _trackPreferenceGetId,
|
||||
getLinks: _trackPreferenceGetLinks,
|
||||
attach: _trackPreferenceAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _trackPreferenceEstimateSize(
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ const UpdateSchema = CollectionSchema(
|
|||
getId: _updateGetId,
|
||||
getLinks: _updateGetLinks,
|
||||
attach: _updateAttach,
|
||||
version: '3.3.0-dev.3',
|
||||
version: '3.3.0',
|
||||
);
|
||||
|
||||
int _updateEstimateSize(
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import 'package:flutter/services.dart';
|
|||
import 'package:flutter_qjs/quickjs/ffi.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart' as riv;
|
||||
import 'package:isar_community/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
|
@ -29,7 +30,6 @@ import 'package:mangayomi/modules/anime/widgets/mobile.dart';
|
|||
import 'package:mangayomi/modules/anime/widgets/subtitle_view.dart';
|
||||
import 'package:mangayomi/modules/anime/widgets/subtitle_setting_widget.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||
import 'package:mangayomi/modules/more/settings/player/providers/custom_buttons_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/player/providers/player_audio_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/player/providers/player_decoder_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/player/providers/player_state_provider.dart';
|
||||
|
|
@ -48,11 +48,11 @@ import 'package:media_kit/generated/libmpv/bindings.dart' as generated;
|
|||
import 'package:media_kit_video/media_kit_video.dart';
|
||||
import 'package:media_kit_video/media_kit_video_controls/src/controls/extensions/duration.dart';
|
||||
import 'package:numberpicker/numberpicker.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:super_sliver_list/super_sliver_list.dart';
|
||||
import 'package:window_manager/window_manager.dart' show windowManager;
|
||||
|
||||
import 'widgets/search_subtitles.dart';
|
||||
|
||||
|
|
@ -193,7 +193,10 @@ enum _AniSkipPhase { none, opening, ending }
|
|||
bool _firstTime = true;
|
||||
|
||||
class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage>
|
||||
with TickerProviderStateMixin, WidgetsBindingObserver {
|
||||
with
|
||||
_AlwaysOnTopStateMixin,
|
||||
TickerProviderStateMixin,
|
||||
WidgetsBindingObserver {
|
||||
late final GlobalKey<VideoState> _key = GlobalKey<VideoState>();
|
||||
late final useLibass = ref.read(useLibassStateProvider);
|
||||
late final useMpvConfig = ref.read(useMpvConfigStateProvider);
|
||||
|
|
@ -667,7 +670,11 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage>
|
|||
|
||||
Future<void> _initCustomButton() async {
|
||||
if (!useMpvConfig) return;
|
||||
final customButtons = await ref.read(getCustomButtonsStreamProvider.future);
|
||||
final customButtons = isar.customButtons
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.sortByPos()
|
||||
.findAllSync();
|
||||
if (customButtons.isEmpty) return;
|
||||
final primaryButton =
|
||||
customButtons.firstWhereOrNull((e) => e.isFavourite ?? false) ??
|
||||
|
|
@ -875,6 +882,12 @@ mp.register_script_message('call_button_${button.id}_long', button${button.id}lo
|
|||
});
|
||||
_firstTime = false;
|
||||
}
|
||||
if (!_isDesktop) {
|
||||
final forceLandscape = ref.read(forceLandscapePlayerStateProvider);
|
||||
if (forceLandscape) {
|
||||
_setLandscapeMode(true);
|
||||
}
|
||||
}
|
||||
_currentPositionSub = _player.stream.position.listen(
|
||||
_unifiedPositionHandler,
|
||||
);
|
||||
|
|
@ -922,7 +935,7 @@ mp.register_script_message('call_button_${button.id}_long', button${button.id}lo
|
|||
if (Platform.isAndroid && useLibass) {
|
||||
try {
|
||||
final subDir = await getApplicationDocumentsDirectory();
|
||||
final fontPath = p.join(subDir.path, 'subfont.ttf');
|
||||
final fontPath = path.join(subDir.path, 'subfont.ttf');
|
||||
final data = await rootBundle.load('assets/fonts/subfont.ttf');
|
||||
final bytes = data.buffer.asInt8List(
|
||||
data.offsetInBytes,
|
||||
|
|
@ -964,30 +977,31 @@ mp.register_script_message('call_button_${button.id}_long', button${button.id}lo
|
|||
@override
|
||||
void dispose() {
|
||||
_currentPosition.removeListener(_updateRpcTimestamp);
|
||||
_subDelayController.removeListener(_onSubDelayChanged);
|
||||
_subSpeedController.removeListener(_onSubSpeedChanged);
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_setCurrentPosition(true);
|
||||
_player.dispose();
|
||||
_player.stop();
|
||||
_completed.cancel();
|
||||
_currentPositionSub.cancel();
|
||||
_currentTotalDurationSub.cancel();
|
||||
_completed.cancel();
|
||||
_currentPosition.dispose();
|
||||
_currentTotalDuration.dispose();
|
||||
_video.dispose();
|
||||
_playbackSpeed.dispose();
|
||||
_isDoubleSpeed.dispose();
|
||||
_currentTotalDuration.dispose();
|
||||
_showFitLabel.dispose();
|
||||
_isCompleted.dispose();
|
||||
_tempPosition.dispose();
|
||||
_fit.dispose();
|
||||
if (!_isDesktop) {
|
||||
_setLandscapeMode(false);
|
||||
}
|
||||
_skipPhase.dispose();
|
||||
discordRpc?.showIdleText();
|
||||
discordRpc?.showOriginalTimestamp();
|
||||
_currentPosition.dispose();
|
||||
_subDelayController.dispose();
|
||||
_subSpeedController.dispose();
|
||||
if (!_isDesktop) _setLandscapeMode(false);
|
||||
discordRpc?.showIdleText();
|
||||
discordRpc?.showOriginalTimestamp();
|
||||
_streamController.keepAliveLink?.close();
|
||||
_player.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -1344,8 +1358,8 @@ mp.register_script_message('call_button_${button.id}_long', button${button.id}lo
|
|||
}
|
||||
if (!context.mounted) return;
|
||||
Navigator.pop(context);
|
||||
} catch (_) {
|
||||
botToast("Error");
|
||||
} catch (e) {
|
||||
botToast("Error: $e");
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
|
|
@ -1958,6 +1972,17 @@ mp.register_script_message('call_button_${button.id}_long', button${button.id}lo
|
|||
),
|
||||
Row(
|
||||
children: [
|
||||
if (_supportAlwaysOnTop())
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
_alwaysOnTop ? Icons.push_pin : Icons.push_pin_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() => _alwaysOnTop = !_alwaysOnTop);
|
||||
windowManager.setAlwaysOnTop(_alwaysOnTop);
|
||||
},
|
||||
),
|
||||
btnToShowChapterListDialog(
|
||||
context,
|
||||
context.l10n.episodes,
|
||||
|
|
@ -2290,7 +2315,9 @@ mp.register_script_message('call_button_${button.id}_long', button${button.id}lo
|
|||
);
|
||||
final dir = await StorageProvider()
|
||||
.getGalleryDirectory();
|
||||
final file = File(p.join(dir!.path, "$name.png"));
|
||||
final file = File(
|
||||
path.join(dir!.path, "$name.png"),
|
||||
);
|
||||
file.writeAsBytesSync(imageBytes!);
|
||||
if (context.mounted) {
|
||||
botToast(context.l10n.picture_saved, second: 3);
|
||||
|
|
@ -2369,3 +2396,44 @@ class VideoPrefs {
|
|||
this.title,
|
||||
});
|
||||
}
|
||||
|
||||
mixin _AlwaysOnTopStateMixin<T extends StatefulWidget> on State<T> {
|
||||
// The original alwaysOnTop state.
|
||||
// This will be used to restore the original state when the widget disposed.
|
||||
bool? _savedAlwaysOnTop;
|
||||
|
||||
bool _alwaysOnTop = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initAlwaysOnTop();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_disposeAlwaysOnTop();
|
||||
}
|
||||
|
||||
Future<void> _initAlwaysOnTop() async {
|
||||
if (_supportAlwaysOnTop()) {
|
||||
_savedAlwaysOnTop = await windowManager.isAlwaysOnTop();
|
||||
if (mounted) {
|
||||
setState(() => _alwaysOnTop = _savedAlwaysOnTop!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _disposeAlwaysOnTop() async {
|
||||
if (_supportAlwaysOnTop()) {
|
||||
if (_savedAlwaysOnTop != null) {
|
||||
await windowManager.setAlwaysOnTop(_savedAlwaysOnTop!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Whether the platform support AlwaysOnTop feature.
|
||||
bool _supportAlwaysOnTop() =>
|
||||
!kIsWeb && (Platform.isLinux || Platform.isMacOS || Platform.isWindows);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ part of 'anime_player_controller_provider.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(AnimeStreamController)
|
||||
const animeStreamControllerProvider = AnimeStreamControllerFamily._();
|
||||
final animeStreamControllerProvider = AnimeStreamControllerFamily._();
|
||||
|
||||
final class AnimeStreamControllerProvider
|
||||
extends $NotifierProvider<AnimeStreamController, KeepAliveLink> {
|
||||
const AnimeStreamControllerProvider._({
|
||||
AnimeStreamControllerProvider._({
|
||||
required AnimeStreamControllerFamily super.from,
|
||||
required Chapter super.argument,
|
||||
}) : super(
|
||||
|
|
@ -70,7 +70,7 @@ final class AnimeStreamControllerFamily extends $Family
|
|||
KeepAliveLink,
|
||||
Chapter
|
||||
> {
|
||||
const AnimeStreamControllerFamily._()
|
||||
AnimeStreamControllerFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'animeStreamControllerProvider',
|
||||
|
|
@ -94,7 +94,6 @@ abstract class _$AnimeStreamController extends $Notifier<KeepAliveLink> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(episode: _$args);
|
||||
final ref = this.ref as $Ref<KeepAliveLink, KeepAliveLink>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -104,6 +103,6 @@ abstract class _$AnimeStreamController extends $Notifier<KeepAliveLink> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, () => build(episode: _$args));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ part of 'state_provider.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(SubtitleSettingsState)
|
||||
const subtitleSettingsStateProvider = SubtitleSettingsStateProvider._();
|
||||
final subtitleSettingsStateProvider = SubtitleSettingsStateProvider._();
|
||||
|
||||
final class SubtitleSettingsStateProvider
|
||||
extends $NotifierProvider<SubtitleSettingsState, PlayerSubtitleSettings> {
|
||||
const SubtitleSettingsStateProvider._()
|
||||
SubtitleSettingsStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -50,7 +50,6 @@ abstract class _$SubtitleSettingsState
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref =
|
||||
this.ref as $Ref<PlayerSubtitleSettings, PlayerSubtitleSettings>;
|
||||
final element =
|
||||
|
|
@ -61,6 +60,6 @@ abstract class _$SubtitleSettingsState
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import 'package:mangayomi/modules/browse/extension/extension_screen.dart';
|
|||
import 'package:mangayomi/modules/browse/sources/sources_screen.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/search_text_form_field.dart';
|
||||
import 'package:mangayomi/services/fetch_sources_list.dart';
|
||||
import 'package:mangayomi/utils/item_type_localization.dart';
|
||||
|
||||
class BrowseScreen extends ConsumerStatefulWidget {
|
||||
const BrowseScreen({super.key});
|
||||
|
|
@ -20,19 +21,35 @@ class BrowseScreen extends ConsumerStatefulWidget {
|
|||
ConsumerState<BrowseScreen> createState() => _BrowseScreenState();
|
||||
}
|
||||
|
||||
enum BrowseTabKind { sources, extensions }
|
||||
|
||||
class BrowseTab {
|
||||
final ItemType type;
|
||||
final BrowseTabKind kind;
|
||||
|
||||
const BrowseTab(this.type, this.kind);
|
||||
}
|
||||
|
||||
class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
||||
with TickerProviderStateMixin {
|
||||
late final hideItems = ref.read(hideItemsStateProvider);
|
||||
final _textEditingController = TextEditingController();
|
||||
late TabController _tabBarController;
|
||||
|
||||
late final _tabList = [
|
||||
if (!hideItems.contains("/MangaLibrary")) 'manga',
|
||||
if (!hideItems.contains("/AnimeLibrary")) 'anime',
|
||||
if (!hideItems.contains("/NovelLibrary")) 'novel',
|
||||
if (!hideItems.contains("/MangaLibrary")) 'mangaExtension',
|
||||
if (!hideItems.contains("/AnimeLibrary")) 'animeExtension',
|
||||
if (!hideItems.contains("/NovelLibrary")) 'novelExtension',
|
||||
late final List<BrowseTab> _tabList = [
|
||||
if (!hideItems.contains("/MangaLibrary"))
|
||||
BrowseTab(ItemType.manga, BrowseTabKind.sources),
|
||||
if (!hideItems.contains("/AnimeLibrary"))
|
||||
BrowseTab(ItemType.anime, BrowseTabKind.sources),
|
||||
if (!hideItems.contains("/NovelLibrary"))
|
||||
BrowseTab(ItemType.novel, BrowseTabKind.sources),
|
||||
|
||||
if (!hideItems.contains("/MangaLibrary"))
|
||||
BrowseTab(ItemType.manga, BrowseTabKind.extensions),
|
||||
if (!hideItems.contains("/AnimeLibrary"))
|
||||
BrowseTab(ItemType.anime, BrowseTabKind.extensions),
|
||||
if (!hideItems.contains("/NovelLibrary"))
|
||||
BrowseTab(ItemType.novel, BrowseTabKind.extensions),
|
||||
];
|
||||
|
||||
@override
|
||||
|
|
@ -65,11 +82,8 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
if (_tabList.isEmpty) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
final containsExtensionTab = [
|
||||
"mangaExtension",
|
||||
"animeExtension",
|
||||
"novelExtension",
|
||||
].any((element) => _tabList[_tabBarController.index] == element);
|
||||
final currentTab = _tabList[_tabBarController.index];
|
||||
final isExtensionTab = currentTab.kind == BrowseTabKind.extensions;
|
||||
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return DefaultTabController(
|
||||
|
|
@ -102,9 +116,7 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
)
|
||||
: Row(
|
||||
children: [
|
||||
if (_tabBarController.index == 3 ||
|
||||
_tabBarController.index == 4 ||
|
||||
_tabBarController.index == 5)
|
||||
if (isExtensionTab)
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.push('/createExtension');
|
||||
|
|
@ -117,26 +129,19 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
if (containsExtensionTab) {
|
||||
if (isExtensionTab) {
|
||||
setState(() {
|
||||
_isSearch = true;
|
||||
});
|
||||
} else {
|
||||
context.push(
|
||||
'/globalSearch',
|
||||
extra: (
|
||||
null,
|
||||
switch (_tabList[_tabBarController.index]) {
|
||||
"manga" => ItemType.manga,
|
||||
"anime" => ItemType.anime,
|
||||
_ => ItemType.novel,
|
||||
},
|
||||
),
|
||||
extra: (null, currentTab.type),
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
!containsExtensionTab
|
||||
!isExtensionTab
|
||||
? Icons.travel_explore_rounded
|
||||
: Icons.search_rounded,
|
||||
color: Theme.of(context).hintColor,
|
||||
|
|
@ -148,16 +153,12 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
context.push(
|
||||
containsExtensionTab ? '/ExtensionLang' : '/sourceFilter',
|
||||
extra: switch (_tabList[_tabBarController.index]) {
|
||||
"manga" || "mangaExtension" => ItemType.manga,
|
||||
"anime" || "animeExtension" => ItemType.anime,
|
||||
_ => ItemType.novel,
|
||||
},
|
||||
isExtensionTab ? '/ExtensionLang' : '/sourceFilter',
|
||||
extra: currentTab.type,
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
!containsExtensionTab
|
||||
!isExtensionTab
|
||||
? Icons.filter_list_sharp
|
||||
: Icons.translate_rounded,
|
||||
color: Theme.of(context).hintColor,
|
||||
|
|
@ -168,86 +169,44 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
indicatorSize: TabBarIndicatorSize.label,
|
||||
isScrollable: true,
|
||||
controller: _tabBarController,
|
||||
tabs: [
|
||||
if (!hideItems.contains("/MangaLibrary"))
|
||||
Tab(text: l10n.manga_sources),
|
||||
if (!hideItems.contains("/AnimeLibrary"))
|
||||
Tab(text: l10n.anime_sources),
|
||||
if (!hideItems.contains("/NovelLibrary"))
|
||||
Tab(text: l10n.novel_sources),
|
||||
if (!hideItems.contains("/MangaLibrary"))
|
||||
Tab(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(l10n.manga_extensions),
|
||||
tabs: _tabList.map((tab) {
|
||||
final type = tab.type;
|
||||
final isExt = tab.kind == BrowseTabKind.extensions;
|
||||
|
||||
return Tab(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
isExt
|
||||
? type.localizedExtensions(l10n)
|
||||
: type.localizedSources(l10n),
|
||||
),
|
||||
if (isExt) ...[
|
||||
const SizedBox(width: 8),
|
||||
_extensionUpdateNumbers(ref, ItemType.manga),
|
||||
_extensionUpdateNumbers(ref, type),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
if (!hideItems.contains("/AnimeLibrary"))
|
||||
Tab(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(l10n.anime_extensions),
|
||||
const SizedBox(width: 8),
|
||||
_extensionUpdateNumbers(ref, ItemType.anime),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (!hideItems.contains("/NovelLibrary"))
|
||||
Tab(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(l10n.novel_extensions),
|
||||
const SizedBox(width: 8),
|
||||
_extensionUpdateNumbers(ref, ItemType.novel),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
body: TabBarView(
|
||||
controller: _tabBarController,
|
||||
children: [
|
||||
if (!hideItems.contains("/MangaLibrary"))
|
||||
SourcesScreen(
|
||||
itemType: ItemType.manga,
|
||||
tabIndex: (index) {
|
||||
_tabBarController.animateTo(index);
|
||||
},
|
||||
),
|
||||
if (!hideItems.contains("/AnimeLibrary"))
|
||||
SourcesScreen(
|
||||
itemType: ItemType.anime,
|
||||
tabIndex: (index) {
|
||||
_tabBarController.animateTo(index);
|
||||
},
|
||||
),
|
||||
if (!hideItems.contains("/NovelLibrary"))
|
||||
SourcesScreen(
|
||||
itemType: ItemType.novel,
|
||||
tabIndex: (index) {
|
||||
_tabBarController.animateTo(index);
|
||||
},
|
||||
),
|
||||
if (!hideItems.contains("/MangaLibrary"))
|
||||
ExtensionScreen(
|
||||
children: _tabList.map((tab) {
|
||||
if (tab.kind == BrowseTabKind.sources) {
|
||||
return SourcesScreen(
|
||||
itemType: tab.type,
|
||||
tabs: _tabList,
|
||||
tabIndex: (index) => _tabBarController.animateTo(index),
|
||||
);
|
||||
} else {
|
||||
return ExtensionScreen(
|
||||
query: _textEditingController.text,
|
||||
itemType: ItemType.manga,
|
||||
),
|
||||
if (!hideItems.contains("/AnimeLibrary"))
|
||||
ExtensionScreen(
|
||||
query: _textEditingController.text,
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
if (!hideItems.contains("/NovelLibrary"))
|
||||
ExtensionScreen(
|
||||
query: _textEditingController.text,
|
||||
itemType: ItemType.novel,
|
||||
),
|
||||
],
|
||||
itemType: tab.type,
|
||||
);
|
||||
}
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -96,7 +96,9 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
_logsNotifier.value.add(event);
|
||||
try {
|
||||
await Future.delayed(const Duration(milliseconds: 5));
|
||||
_scrollController.jumpTo(_scrollController.position.maxScrollExtent);
|
||||
if (_scrollController.hasClients) {
|
||||
_scrollController.jumpTo(_scrollController.position.maxScrollExtent);
|
||||
}
|
||||
} catch (_) {}
|
||||
});
|
||||
}
|
||||
|
|
@ -489,6 +491,7 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
proxyServer: ref.read(
|
||||
androidProxyServerStateProvider,
|
||||
),
|
||||
useLogger: true,
|
||||
);
|
||||
result = getManga!.toJson();
|
||||
} else if (_serviceIndex == 1) {
|
||||
|
|
@ -502,6 +505,7 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
proxyServer: ref.read(
|
||||
androidProxyServerStateProvider,
|
||||
),
|
||||
useLogger: true,
|
||||
);
|
||||
result = getManga!.toJson();
|
||||
} else if (_serviceIndex == 2) {
|
||||
|
|
@ -514,6 +518,7 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
page: _page,
|
||||
serviceType: 'search',
|
||||
proxyServer: proxyServer,
|
||||
useLogger: true,
|
||||
);
|
||||
result = getManga!.toJson();
|
||||
} else if (_serviceIndex == 3) {
|
||||
|
|
@ -524,6 +529,7 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
source: source,
|
||||
serviceType: 'getDetail',
|
||||
proxyServer: proxyServer,
|
||||
useLogger: true,
|
||||
);
|
||||
|
||||
result = getManga.toJson();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
|
@ -30,6 +31,12 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
|||
late Source source = isar.sources.getSync(widget.source.id!)!;
|
||||
late List<SourcePreference>? sourcePreference = () {
|
||||
try {
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.mihon &&
|
||||
source.preferenceList != null) {
|
||||
return (jsonDecode(source.preferenceList!) as List)
|
||||
.map((e) => SourcePreference.fromJson(e))
|
||||
.toList();
|
||||
}
|
||||
return getSourcePreference(
|
||||
source: source,
|
||||
).map((e) => getSourcePreferenceEntry(e.key!, source.id!)).toList();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ part of 'extensions_provider.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(getExtensionsStream)
|
||||
const getExtensionsStreamProvider = GetExtensionsStreamFamily._();
|
||||
final getExtensionsStreamProvider = GetExtensionsStreamFamily._();
|
||||
|
||||
final class GetExtensionsStreamProvider
|
||||
extends
|
||||
|
|
@ -20,7 +20,7 @@ final class GetExtensionsStreamProvider
|
|||
Stream<List<Source>>
|
||||
>
|
||||
with $FutureModifier<List<Source>>, $StreamProvider<List<Source>> {
|
||||
const GetExtensionsStreamProvider._({
|
||||
GetExtensionsStreamProvider._({
|
||||
required GetExtensionsStreamFamily super.from,
|
||||
required ItemType super.argument,
|
||||
}) : super(
|
||||
|
|
@ -69,7 +69,7 @@ String _$getExtensionsStreamHash() =>
|
|||
|
||||
final class GetExtensionsStreamFamily extends $Family
|
||||
with $FunctionalFamilyOverride<Stream<List<Source>>, ItemType> {
|
||||
const GetExtensionsStreamFamily._()
|
||||
GetExtensionsStreamFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getExtensionsStreamProvider',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/modules/browse/browse_screen.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_sliver_grouped_list_view.dart';
|
||||
import 'package:isar_community/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
|
|
@ -11,10 +12,12 @@ import 'package:mangayomi/utils/language.dart';
|
|||
|
||||
class SourcesScreen extends ConsumerStatefulWidget {
|
||||
final Function(int) tabIndex;
|
||||
final List<BrowseTab> tabs;
|
||||
final ItemType itemType;
|
||||
const SourcesScreen({
|
||||
required this.tabIndex,
|
||||
required this.itemType,
|
||||
required this.tabs,
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
|
@ -62,13 +65,17 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () => widget.tabIndex(
|
||||
widget.itemType == ItemType.manga
|
||||
? 3
|
||||
: widget.itemType == ItemType.anime
|
||||
? 4
|
||||
: 5,
|
||||
),
|
||||
onPressed: () {
|
||||
final extensionIndex = widget.tabs.indexWhere(
|
||||
(t) =>
|
||||
t.type == widget.itemType &&
|
||||
t.kind == BrowseTabKind.extensions,
|
||||
);
|
||||
|
||||
if (extensionIndex != -1) {
|
||||
widget.tabIndex(extensionIndex);
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.extension_rounded),
|
||||
label: Text(context.l10n.show_extensions),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import 'package:mangayomi/models/source.dart';
|
|||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/item_type_localization.dart';
|
||||
import 'package:mangayomi/utils/language.dart';
|
||||
|
||||
class SourceListTile extends StatelessWidget {
|
||||
|
|
@ -81,11 +82,7 @@ class SourceListTile extends StatelessWidget {
|
|||
title: Text(
|
||||
!isLocal
|
||||
? source.name!
|
||||
: "${context.l10n.local_source} ${source.itemType == ItemType.manga
|
||||
? context.l10n.manga
|
||||
: source.itemType == ItemType.anime
|
||||
? context.l10n.anime
|
||||
: context.l10n.novel}",
|
||||
: "${context.l10n.local_source} ${source.itemType.localized(context.l10n)}",
|
||||
),
|
||||
trailing: SizedBox(
|
||||
width: 150,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:isar_community/isar.dart';
|
|||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/calendar/providers/calendar_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_sliver_grouped_list_view.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
|
|
@ -15,6 +16,8 @@ import 'package:mangayomi/utils/constant.dart';
|
|||
import 'package:mangayomi/utils/date.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/utils/item_type_filters.dart';
|
||||
import 'package:mangayomi/utils/item_type_localization.dart';
|
||||
import 'package:table_calendar/table_calendar.dart';
|
||||
|
||||
class CalendarScreen extends ConsumerStatefulWidget {
|
||||
|
|
@ -35,11 +38,19 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
|||
DateTime? _selectedDay;
|
||||
DateTime? _rangeStart;
|
||||
DateTime? _rangeEnd;
|
||||
late ItemType? itemType = widget.itemType ?? ItemType.manga;
|
||||
late ItemType? itemType;
|
||||
late List<ItemType> _visibleTypes;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_visibleTypes = hiddenItemTypes(ref.read(hideItemsStateProvider));
|
||||
final initialItemType = widget.itemType ?? ItemType.manga;
|
||||
if (_visibleTypes.contains(initialItemType)) {
|
||||
itemType = initialItemType;
|
||||
} else {
|
||||
itemType = _visibleTypes.isNotEmpty ? _visibleTypes.first : null;
|
||||
}
|
||||
_selectedDay = _focusedDay;
|
||||
_selectedEntries = ValueNotifier([]);
|
||||
}
|
||||
|
|
@ -69,31 +80,7 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
|||
SliverToBoxAdapter(
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 3),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.warning_amber_outlined,
|
||||
color: context.secondaryColor,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: Text(
|
||||
l10n.calendar_info,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.clip,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: context.secondaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildWarningTile(context),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: Row(
|
||||
|
|
@ -107,29 +94,15 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
|||
borderRadius: BorderRadius.circular(50),
|
||||
),
|
||||
),
|
||||
segments: [
|
||||
ButtonSegment(
|
||||
value: ItemType.manga.index,
|
||||
segments: _visibleTypes.map((type) {
|
||||
return ButtonSegment(
|
||||
value: type.index,
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Text(l10n.manga),
|
||||
child: Text(type.localized(l10n)),
|
||||
),
|
||||
),
|
||||
ButtonSegment(
|
||||
value: ItemType.anime.index,
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Text(l10n.anime),
|
||||
),
|
||||
),
|
||||
ButtonSegment(
|
||||
value: ItemType.novel.index,
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Text(l10n.novel),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
selected: {itemType?.index},
|
||||
onSelectionChanged: (newSelection) {
|
||||
if (newSelection.isNotEmpty &&
|
||||
|
|
@ -145,40 +118,7 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
|||
],
|
||||
),
|
||||
),
|
||||
TableCalendar(
|
||||
firstDay: firstDay,
|
||||
lastDay: lastDay,
|
||||
focusedDay: _focusedDay,
|
||||
locale: locale.toLanguageTag(),
|
||||
selectedDayPredicate: (day) =>
|
||||
isSameDay(_selectedDay, day),
|
||||
rangeStartDay: _rangeStart,
|
||||
rangeEndDay: _rangeEnd,
|
||||
calendarFormat: _calendarFormat,
|
||||
rangeSelectionMode: _rangeSelectionMode,
|
||||
eventLoader: (day) => _getEntriesForDay(day, data),
|
||||
startingDayOfWeek: StartingDayOfWeek.monday,
|
||||
calendarStyle: CalendarStyle(
|
||||
outsideDaysVisible: true,
|
||||
weekendTextStyle: TextStyle(
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
onDaySelected: (selectedDay, focusedDay) =>
|
||||
_onDaySelected(selectedDay, focusedDay, data),
|
||||
onRangeSelected: (start, end, focusedDay) =>
|
||||
_onRangeSelected(start, end, focusedDay, data),
|
||||
onFormatChanged: (format) {
|
||||
if (_calendarFormat != format) {
|
||||
setState(() {
|
||||
_calendarFormat = format;
|
||||
});
|
||||
}
|
||||
},
|
||||
onPageChanged: (focusedDay) {
|
||||
_focusedDay = focusedDay;
|
||||
},
|
||||
),
|
||||
_buildCalendar(data, locale),
|
||||
const SizedBox(height: 15),
|
||||
],
|
||||
),
|
||||
|
|
@ -241,8 +181,64 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildWarningTile(BuildContext context) {
|
||||
return ListTile(
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 3),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.warning_amber_outlined, color: context.secondaryColor),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: Text(
|
||||
context.l10n.calendar_info,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.clip,
|
||||
style: TextStyle(fontSize: 13, color: context.secondaryColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCalendar(List<Manga> data, Locale locale) {
|
||||
return TableCalendar(
|
||||
firstDay: firstDay,
|
||||
lastDay: lastDay,
|
||||
focusedDay: _focusedDay,
|
||||
locale: locale.toLanguageTag(),
|
||||
selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
|
||||
rangeStartDay: _rangeStart,
|
||||
rangeEndDay: _rangeEnd,
|
||||
calendarFormat: _calendarFormat,
|
||||
rangeSelectionMode: _rangeSelectionMode,
|
||||
eventLoader: (day) => _getEntriesForDay(day, data),
|
||||
startingDayOfWeek: StartingDayOfWeek.monday,
|
||||
calendarStyle: CalendarStyle(
|
||||
outsideDaysVisible: true,
|
||||
weekendTextStyle: TextStyle(color: context.primaryColor),
|
||||
),
|
||||
onDaySelected: (selectedDay, focusedDay) =>
|
||||
_onDaySelected(selectedDay, focusedDay, data),
|
||||
onRangeSelected: (start, end, focusedDay) =>
|
||||
_onRangeSelected(start, end, focusedDay, data),
|
||||
onFormatChanged: (format) {
|
||||
if (_calendarFormat != format) {
|
||||
setState(() => _calendarFormat = format);
|
||||
}
|
||||
},
|
||||
onPageChanged: (focusedDay) => _focusedDay = focusedDay,
|
||||
);
|
||||
}
|
||||
|
||||
final Map<String, List<Manga>> _dayCache = {};
|
||||
|
||||
List<Manga> _getEntriesForDay(DateTime day, List<Manga> data) {
|
||||
return data.where((e) {
|
||||
final key = "${day.year}-${day.month}-${day.day}";
|
||||
if (_dayCache.containsKey(key)) return _dayCache[key]!;
|
||||
final result = data.where((e) {
|
||||
final lastChapter = e.chapters
|
||||
.filter()
|
||||
.sortByDateUploadDesc()
|
||||
|
|
@ -252,10 +248,12 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
|
|||
? DateTime.fromMillisecondsSinceEpoch(lastDate)
|
||||
: DateTime.now();
|
||||
final temp = start.add(Duration(days: e.smartUpdateDays!));
|
||||
final predictedDay = "${temp.year}-${temp.month}-${temp.day}";
|
||||
final selectedDay = "${day.year}-${day.month}-${day.day}";
|
||||
return predictedDay == selectedDay;
|
||||
return temp.year == day.year &&
|
||||
temp.month == day.month &&
|
||||
temp.day == day.day;
|
||||
}).toList();
|
||||
_dayCache[key] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
List<Manga> _getEntriesForRange(
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ part of 'calendar_provider.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(getCalendarStream)
|
||||
const getCalendarStreamProvider = GetCalendarStreamFamily._();
|
||||
final getCalendarStreamProvider = GetCalendarStreamFamily._();
|
||||
|
||||
final class GetCalendarStreamProvider
|
||||
extends
|
||||
|
|
@ -20,7 +20,7 @@ final class GetCalendarStreamProvider
|
|||
Stream<List<Manga>>
|
||||
>
|
||||
with $FutureModifier<List<Manga>>, $StreamProvider<List<Manga>> {
|
||||
const GetCalendarStreamProvider._({
|
||||
GetCalendarStreamProvider._({
|
||||
required GetCalendarStreamFamily super.from,
|
||||
required ItemType? super.argument,
|
||||
}) : super(
|
||||
|
|
@ -68,7 +68,7 @@ String _$getCalendarStreamHash() => r'850d81742f8ac5ce88175732c0edf57a7a9295d4';
|
|||
|
||||
final class GetCalendarStreamFamily extends $Family
|
||||
with $FunctionalFamilyOverride<Stream<List<Manga>>, ItemType?> {
|
||||
const GetCalendarStreamFamily._()
|
||||
GetCalendarStreamFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getCalendarStreamProvider',
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mangayomi/l10n/generated/app_localizations.dart';
|
||||
import 'package:mangayomi/modules/widgets/base_library_tab_screen.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_sliver_grouped_list_view.dart';
|
||||
|
||||
import 'package:isar_community/isar.dart';
|
||||
|
|
@ -12,7 +13,6 @@ import 'package:mangayomi/models/chapter.dart';
|
|||
import 'package:mangayomi/models/history.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/history/providers/isar_providers.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
|
|
@ -20,7 +20,6 @@ import 'package:mangayomi/utils/constant.dart';
|
|||
import 'package:mangayomi/utils/date.dart';
|
||||
import 'package:mangayomi/utils/extensions/chapter.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/search_text_form_field.dart';
|
||||
import 'package:mangayomi/modules/widgets/error_text.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
|
||||
|
|
@ -31,175 +30,61 @@ class HistoryScreen extends ConsumerStatefulWidget {
|
|||
ConsumerState<HistoryScreen> createState() => _HistoryScreenState();
|
||||
}
|
||||
|
||||
class _HistoryScreenState extends ConsumerState<HistoryScreen>
|
||||
with TickerProviderStateMixin {
|
||||
final _textEditingController = TextEditingController();
|
||||
late TabController _tabBarController;
|
||||
class _HistoryScreenState extends BaseLibraryTabScreenState<HistoryScreen> {
|
||||
@override
|
||||
String get title => l10nLocalizations(context)!.history;
|
||||
|
||||
void tabListener() {
|
||||
setState(() {
|
||||
_textEditingController.clear();
|
||||
_isSearch = false;
|
||||
});
|
||||
@override
|
||||
Widget buildTab(ItemType type) {
|
||||
return HistoryTab(itemType: type, query: textEditingController.text);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final hideItems = ref.read(hideItemsStateProvider);
|
||||
final tabCount = [
|
||||
if (!hideItems.contains("/MangaLibrary")) "/MangaLibrary",
|
||||
if (!hideItems.contains("/AnimeLibrary")) "/AnimeLibrary",
|
||||
if (!hideItems.contains("/NovelLibrary")) "/NovelLibrary",
|
||||
].length;
|
||||
_tabBarController = TabController(length: tabCount, vsync: this);
|
||||
_tabBarController.addListener(tabListener);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_tabBarController.dispose();
|
||||
_textEditingController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
bool _isSearch = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final hideItems = ref.watch(hideItemsStateProvider);
|
||||
List<Widget> buildExtraActions(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
title: _isSearch
|
||||
? null
|
||||
: Text(
|
||||
l10n.history,
|
||||
style: TextStyle(color: Theme.of(context).hintColor),
|
||||
),
|
||||
actions: [
|
||||
_isSearch
|
||||
? SeachFormTextField(
|
||||
onChanged: (value) {
|
||||
setState(() {});
|
||||
},
|
||||
onSuffixPressed: () {
|
||||
_textEditingController.clear();
|
||||
setState(() {});
|
||||
},
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isSearch = false;
|
||||
});
|
||||
_textEditingController.clear();
|
||||
},
|
||||
controller: _textEditingController,
|
||||
)
|
||||
: IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isSearch = true;
|
||||
});
|
||||
},
|
||||
icon: Icon(Icons.search, color: Theme.of(context).hintColor),
|
||||
),
|
||||
IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(l10n.remove_everything),
|
||||
content: Text(l10n.remove_everything_msg),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (mounted) Navigator.pop(context);
|
||||
await _clearHistory(hideItems);
|
||||
},
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.delete_sweep_outlined,
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
bottom: TabBar(
|
||||
indicatorSize: TabBarIndicatorSize.tab,
|
||||
controller: _tabBarController,
|
||||
tabs: [
|
||||
if (!hideItems.contains("/MangaLibrary")) Tab(text: l10n.manga),
|
||||
if (!hideItems.contains("/AnimeLibrary")) Tab(text: l10n.anime),
|
||||
if (!hideItems.contains("/NovelLibrary")) Tab(text: l10n.novel),
|
||||
],
|
||||
|
||||
return [
|
||||
IconButton(
|
||||
splashRadius: 20,
|
||||
icon: Icon(
|
||||
Icons.delete_sweep_outlined,
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (dialogContext) => AlertDialog(
|
||||
title: Text(l10n.remove_everything),
|
||||
content: Text(l10n.remove_everything_msg),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(dialogContext).pop(),
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
Navigator.of(dialogContext).pop();
|
||||
await _clearHistory();
|
||||
},
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
body: TabBarView(
|
||||
controller: _tabBarController,
|
||||
children: [
|
||||
if (!hideItems.contains("/MangaLibrary"))
|
||||
HistoryTab(
|
||||
itemType: ItemType.manga,
|
||||
query: _textEditingController.text,
|
||||
),
|
||||
if (!hideItems.contains("/AnimeLibrary"))
|
||||
HistoryTab(
|
||||
itemType: ItemType.anime,
|
||||
query: _textEditingController.text,
|
||||
),
|
||||
if (!hideItems.contains("/NovelLibrary"))
|
||||
HistoryTab(
|
||||
itemType: ItemType.novel,
|
||||
query: _textEditingController.text,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
Future<void> _clearHistory(List<String> hideItems) async {
|
||||
Future<void> _clearHistory() async {
|
||||
List<History> histories = await isar.historys
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.chapter(
|
||||
(q) =>
|
||||
q.manga((q) => q.itemTypeEqualTo(getCurrentItemType(hideItems))),
|
||||
)
|
||||
.chapter((q) => q.manga((q) => q.itemTypeEqualTo(getCurrentItemType())))
|
||||
.findAll();
|
||||
final List<Id> idsToDelete = histories.map((h) => h.id!).toList();
|
||||
await isar.writeTxn(() => isar.historys.deleteAll(idsToDelete));
|
||||
}
|
||||
|
||||
ItemType getCurrentItemType(List<String> hideItems) {
|
||||
return _tabBarController.index == 0 && !hideItems.contains("/MangaLibrary")
|
||||
? ItemType.manga
|
||||
: _tabBarController.index ==
|
||||
1 - (hideItems.contains("/MangaLibrary") ? 1 : 0) &&
|
||||
!hideItems.contains("/AnimeLibrary")
|
||||
? ItemType.anime
|
||||
: ItemType.novel;
|
||||
}
|
||||
}
|
||||
|
||||
class HistoryTab extends ConsumerStatefulWidget {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ part of 'isar_providers.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(getAllHistoryStream)
|
||||
const getAllHistoryStreamProvider = GetAllHistoryStreamFamily._();
|
||||
final getAllHistoryStreamProvider = GetAllHistoryStreamFamily._();
|
||||
|
||||
final class GetAllHistoryStreamProvider
|
||||
extends
|
||||
|
|
@ -20,7 +20,7 @@ final class GetAllHistoryStreamProvider
|
|||
Stream<List<History>>
|
||||
>
|
||||
with $FutureModifier<List<History>>, $StreamProvider<List<History>> {
|
||||
const GetAllHistoryStreamProvider._({
|
||||
GetAllHistoryStreamProvider._({
|
||||
required GetAllHistoryStreamFamily super.from,
|
||||
required ({ItemType itemType, String search}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -77,7 +77,7 @@ final class GetAllHistoryStreamFamily extends $Family
|
|||
Stream<List<History>>,
|
||||
({ItemType itemType, String search})
|
||||
> {
|
||||
const GetAllHistoryStreamFamily._()
|
||||
GetAllHistoryStreamFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getAllHistoryStreamProvider',
|
||||
|
|
@ -99,7 +99,7 @@ final class GetAllHistoryStreamFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(getAllUpdateStream)
|
||||
const getAllUpdateStreamProvider = GetAllUpdateStreamFamily._();
|
||||
final getAllUpdateStreamProvider = GetAllUpdateStreamFamily._();
|
||||
|
||||
final class GetAllUpdateStreamProvider
|
||||
extends
|
||||
|
|
@ -109,7 +109,7 @@ final class GetAllUpdateStreamProvider
|
|||
Stream<List<Update>>
|
||||
>
|
||||
with $FutureModifier<List<Update>>, $StreamProvider<List<Update>> {
|
||||
const GetAllUpdateStreamProvider._({
|
||||
GetAllUpdateStreamProvider._({
|
||||
required GetAllUpdateStreamFamily super.from,
|
||||
required ({ItemType itemType, String search}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -166,7 +166,7 @@ final class GetAllUpdateStreamFamily extends $Family
|
|||
Stream<List<Update>>,
|
||||
({ItemType itemType, String search})
|
||||
> {
|
||||
const GetAllUpdateStreamFamily._()
|
||||
GetAllUpdateStreamFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getAllUpdateStreamProvider',
|
||||
|
|
|
|||
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:isar_community/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/changed.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
|
@ -19,10 +17,8 @@ import 'package:mangayomi/models/update.dart';
|
|||
import 'package:mangayomi/modules/library/providers/add_torrent.dart';
|
||||
import 'package:mangayomi/modules/library/providers/local_archive.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/providers/state_providers.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/providers/update_manga_detail_providers.dart';
|
||||
import 'package:mangayomi/modules/more/categories/providers/isar_providers.dart';
|
||||
import 'package:mangayomi/modules/more/providers/downloaded_only_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
|
||||
import 'package:mangayomi/modules/widgets/bottom_select_bar.dart';
|
||||
import 'package:mangayomi/modules/widgets/category_selection_dialog.dart';
|
||||
|
|
@ -30,6 +26,7 @@ import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
|
|||
import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
import 'package:mangayomi/services/library_updater.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/modules/library/providers/isar_providers.dart';
|
||||
import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
|
||||
|
|
@ -42,6 +39,7 @@ import 'package:mangayomi/modules/widgets/error_text.dart';
|
|||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
import 'package:mangayomi/utils/extensions/string_extensions.dart';
|
||||
import 'package:mangayomi/utils/global_style.dart';
|
||||
import 'package:mangayomi/utils/item_type_localization.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
|
|
@ -82,53 +80,6 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _updateLibrary(List<Manga> mangaList) async {
|
||||
bool isDark = ref.read(themeModeStateProvider);
|
||||
botToast(
|
||||
context.l10n.updating_library("0", "0", "0"),
|
||||
fontSize: 13,
|
||||
second: 30,
|
||||
alignY: !context.isTablet ? 0.85 : 1,
|
||||
themeDark: isDark,
|
||||
);
|
||||
int numbers = 0;
|
||||
int failed = 0;
|
||||
for (var manga in mangaList) {
|
||||
try {
|
||||
await ref.read(
|
||||
updateMangaDetailProvider(
|
||||
mangaId: manga.id,
|
||||
isInit: false,
|
||||
showToast: false,
|
||||
).future,
|
||||
);
|
||||
} catch (_) {
|
||||
failed++;
|
||||
}
|
||||
numbers++;
|
||||
if (mounted) {
|
||||
botToast(
|
||||
context.l10n.updating_library(numbers, failed, mangaList.length),
|
||||
fontSize: 13,
|
||||
second: 10,
|
||||
alignY: !context.isTablet ? 0.85 : 1,
|
||||
animationDuration: 0,
|
||||
dismissDirections: [DismissDirection.none],
|
||||
onlyOne: false,
|
||||
themeDark: isDark,
|
||||
);
|
||||
}
|
||||
}
|
||||
await Future.doWhile(() async {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
if (mangaList.length == numbers) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
BotToast.cleanAll();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final settingsStream = ref.watch(getSettingsStreamProvider);
|
||||
|
|
@ -776,7 +727,12 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
final entriesManga = reverse ? entries.reversed.toList() : entries;
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
await _updateLibrary(data);
|
||||
await updateLibrary(
|
||||
ref: ref,
|
||||
context: context,
|
||||
mangaList: data,
|
||||
itemType: widget.itemType,
|
||||
);
|
||||
},
|
||||
child: displayType == DisplayType.list
|
||||
? LibraryListViewWidget(
|
||||
|
|
@ -867,7 +823,12 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
final entriesManga = reverse ? entries.reversed.toList() : entries;
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
await _updateLibrary(data);
|
||||
await updateLibrary(
|
||||
ref: ref,
|
||||
context: context,
|
||||
mangaList: data,
|
||||
itemType: widget.itemType,
|
||||
);
|
||||
},
|
||||
child: displayType == DisplayType.list
|
||||
? LibraryListViewWidget(
|
||||
|
|
@ -1901,11 +1862,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
: Row(
|
||||
children: [
|
||||
Text(
|
||||
widget.itemType == ItemType.manga
|
||||
? l10n.manga
|
||||
: widget.itemType == ItemType.anime
|
||||
? l10n.anime
|
||||
: l10n.novel,
|
||||
widget.itemType.localized(l10n),
|
||||
style: TextStyle(color: Theme.of(context).hintColor),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
|
|
@ -2013,7 +1970,12 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
onSelected: (value) {
|
||||
if (value == 0) {
|
||||
manga.whenData((value) {
|
||||
_updateLibrary(value);
|
||||
updateLibrary(
|
||||
ref: ref,
|
||||
context: context,
|
||||
mangaList: value,
|
||||
itemType: widget.itemType,
|
||||
);
|
||||
});
|
||||
} else if (value == 1) {
|
||||
manga.whenData((value) {
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ part of 'add_torrent.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(addTorrentFromUrlOrFromFile)
|
||||
const addTorrentFromUrlOrFromFileProvider =
|
||||
final addTorrentFromUrlOrFromFileProvider =
|
||||
AddTorrentFromUrlOrFromFileFamily._();
|
||||
|
||||
final class AddTorrentFromUrlOrFromFileProvider
|
||||
extends $FunctionalProvider<AsyncValue<dynamic>, dynamic, FutureOr<dynamic>>
|
||||
with $FutureModifier<dynamic>, $FutureProvider<dynamic> {
|
||||
const AddTorrentFromUrlOrFromFileProvider._({
|
||||
AddTorrentFromUrlOrFromFileProvider._({
|
||||
required AddTorrentFromUrlOrFromFileFamily super.from,
|
||||
required (Manga?, {bool init, String? url}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -74,7 +74,7 @@ final class AddTorrentFromUrlOrFromFileFamily extends $Family
|
|||
FutureOr<dynamic>,
|
||||
(Manga?, {bool init, String? url})
|
||||
> {
|
||||
const AddTorrentFromUrlOrFromFileFamily._()
|
||||
AddTorrentFromUrlOrFromFileFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'addTorrentFromUrlOrFromFileProvider',
|
||||
|
|
|
|||
|
|
@ -306,20 +306,16 @@ Future<void> _scanDirectory(Ref ref, Directory? dir) async {
|
|||
: Uint8List.fromList(coverImage).getCoverImage;
|
||||
saveManga++;
|
||||
}
|
||||
for (var chapter in book.Chapters ?? []) {
|
||||
chaptersToSave.add(
|
||||
Chapter(
|
||||
mangaId: manga.id,
|
||||
name: chapter.Title is String && chapter.Title.isEmpty
|
||||
? "Book"
|
||||
: chapter.Title,
|
||||
archivePath: chapterPath,
|
||||
downloadSize: chapterFile.existsSync()
|
||||
? chapterFile.lengthSync().formattedFileSize()
|
||||
: null,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
}
|
||||
chaptersToSave.add(
|
||||
Chapter(
|
||||
mangaId: manga.id,
|
||||
name: book.Title,
|
||||
archivePath: chapterPath,
|
||||
downloadSize: chapterFile.existsSync()
|
||||
? chapterFile.lengthSync().formattedFileSize()
|
||||
: null,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
} else {
|
||||
final chap = Chapter(
|
||||
mangaId: manga.id,
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ part of 'file_scanner.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(LocalFoldersState)
|
||||
const localFoldersStateProvider = LocalFoldersStateProvider._();
|
||||
final localFoldersStateProvider = LocalFoldersStateProvider._();
|
||||
|
||||
final class LocalFoldersStateProvider
|
||||
extends $NotifierProvider<LocalFoldersState, List<String>> {
|
||||
const LocalFoldersStateProvider._()
|
||||
LocalFoldersStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -48,7 +48,6 @@ abstract class _$LocalFoldersState extends $Notifier<List<String>> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<List<String>, List<String>>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -58,7 +57,7 @@ abstract class _$LocalFoldersState extends $Notifier<List<String>> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +80,7 @@ abstract class _$LocalFoldersState extends $Notifier<List<String>> {
|
|||
/// ```
|
||||
|
||||
@ProviderFor(scanLocalLibrary)
|
||||
const scanLocalLibraryProvider = ScanLocalLibraryProvider._();
|
||||
final scanLocalLibraryProvider = ScanLocalLibraryProvider._();
|
||||
|
||||
/// Scans `Mangayomi/local` folder (if exists) for Mangas/Animes and imports in library.
|
||||
///
|
||||
|
|
@ -121,7 +120,7 @@ final class ScanLocalLibraryProvider
|
|||
/// Archivetypes: cbz, zip, cbt, tar
|
||||
/// Other types: epub
|
||||
/// ```
|
||||
const ScanLocalLibraryProvider._()
|
||||
ScanLocalLibraryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ part of 'isar_providers.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(getAllMangaStream)
|
||||
const getAllMangaStreamProvider = GetAllMangaStreamFamily._();
|
||||
final getAllMangaStreamProvider = GetAllMangaStreamFamily._();
|
||||
|
||||
final class GetAllMangaStreamProvider
|
||||
extends
|
||||
|
|
@ -20,7 +20,7 @@ final class GetAllMangaStreamProvider
|
|||
Stream<List<Manga>>
|
||||
>
|
||||
with $FutureModifier<List<Manga>>, $StreamProvider<List<Manga>> {
|
||||
const GetAllMangaStreamProvider._({
|
||||
GetAllMangaStreamProvider._({
|
||||
required GetAllMangaStreamFamily super.from,
|
||||
required ({int? categoryId, ItemType itemType}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -76,7 +76,7 @@ final class GetAllMangaStreamFamily extends $Family
|
|||
Stream<List<Manga>>,
|
||||
({int? categoryId, ItemType itemType})
|
||||
> {
|
||||
const GetAllMangaStreamFamily._()
|
||||
GetAllMangaStreamFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getAllMangaStreamProvider',
|
||||
|
|
@ -98,7 +98,7 @@ final class GetAllMangaStreamFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(getAllMangaWithoutCategoriesStream)
|
||||
const getAllMangaWithoutCategoriesStreamProvider =
|
||||
final getAllMangaWithoutCategoriesStreamProvider =
|
||||
GetAllMangaWithoutCategoriesStreamFamily._();
|
||||
|
||||
final class GetAllMangaWithoutCategoriesStreamProvider
|
||||
|
|
@ -109,7 +109,7 @@ final class GetAllMangaWithoutCategoriesStreamProvider
|
|||
Stream<List<Manga>>
|
||||
>
|
||||
with $FutureModifier<List<Manga>>, $StreamProvider<List<Manga>> {
|
||||
const GetAllMangaWithoutCategoriesStreamProvider._({
|
||||
GetAllMangaWithoutCategoriesStreamProvider._({
|
||||
required GetAllMangaWithoutCategoriesStreamFamily super.from,
|
||||
required ItemType super.argument,
|
||||
}) : super(
|
||||
|
|
@ -160,7 +160,7 @@ String _$getAllMangaWithoutCategoriesStreamHash() =>
|
|||
|
||||
final class GetAllMangaWithoutCategoriesStreamFamily extends $Family
|
||||
with $FunctionalFamilyOverride<Stream<List<Manga>>, ItemType> {
|
||||
const GetAllMangaWithoutCategoriesStreamFamily._()
|
||||
GetAllMangaWithoutCategoriesStreamFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getAllMangaWithoutCategoriesStreamProvider',
|
||||
|
|
@ -181,7 +181,7 @@ final class GetAllMangaWithoutCategoriesStreamFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(getSettingsStream)
|
||||
const getSettingsStreamProvider = GetSettingsStreamProvider._();
|
||||
final getSettingsStreamProvider = GetSettingsStreamProvider._();
|
||||
|
||||
final class GetSettingsStreamProvider
|
||||
extends
|
||||
|
|
@ -191,7 +191,7 @@ final class GetSettingsStreamProvider
|
|||
Stream<List<Settings>>
|
||||
>
|
||||
with $FutureModifier<List<Settings>>, $StreamProvider<List<Settings>> {
|
||||
const GetSettingsStreamProvider._()
|
||||
GetSettingsStreamProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ part of 'library_state_provider.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(LibraryDisplayTypeState)
|
||||
const libraryDisplayTypeStateProvider = LibraryDisplayTypeStateFamily._();
|
||||
final libraryDisplayTypeStateProvider = LibraryDisplayTypeStateFamily._();
|
||||
|
||||
final class LibraryDisplayTypeStateProvider
|
||||
extends $NotifierProvider<LibraryDisplayTypeState, DisplayType> {
|
||||
const LibraryDisplayTypeStateProvider._({
|
||||
LibraryDisplayTypeStateProvider._({
|
||||
required LibraryDisplayTypeStateFamily super.from,
|
||||
required ({ItemType itemType, Settings settings}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -71,7 +71,7 @@ final class LibraryDisplayTypeStateFamily extends $Family
|
|||
DisplayType,
|
||||
({ItemType itemType, Settings settings})
|
||||
> {
|
||||
const LibraryDisplayTypeStateFamily._()
|
||||
LibraryDisplayTypeStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'libraryDisplayTypeStateProvider',
|
||||
|
|
@ -101,7 +101,6 @@ abstract class _$LibraryDisplayTypeState extends $Notifier<DisplayType> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args.itemType, settings: _$args.settings);
|
||||
final ref = this.ref as $Ref<DisplayType, DisplayType>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -111,16 +110,19 @@ abstract class _$LibraryDisplayTypeState extends $Notifier<DisplayType> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(itemType: _$args.itemType, settings: _$args.settings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(LibraryGridSizeState)
|
||||
const libraryGridSizeStateProvider = LibraryGridSizeStateFamily._();
|
||||
final libraryGridSizeStateProvider = LibraryGridSizeStateFamily._();
|
||||
|
||||
final class LibraryGridSizeStateProvider
|
||||
extends $NotifierProvider<LibraryGridSizeState, int?> {
|
||||
const LibraryGridSizeStateProvider._({
|
||||
LibraryGridSizeStateProvider._({
|
||||
required LibraryGridSizeStateFamily super.from,
|
||||
required ItemType super.argument,
|
||||
}) : super(
|
||||
|
|
@ -170,7 +172,7 @@ String _$libraryGridSizeStateHash() =>
|
|||
final class LibraryGridSizeStateFamily extends $Family
|
||||
with
|
||||
$ClassFamilyOverride<LibraryGridSizeState, int?, int?, int?, ItemType> {
|
||||
const LibraryGridSizeStateFamily._()
|
||||
LibraryGridSizeStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'libraryGridSizeStateProvider',
|
||||
|
|
@ -194,7 +196,6 @@ abstract class _$LibraryGridSizeState extends $Notifier<int?> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args);
|
||||
final ref = this.ref as $Ref<int?, int?>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -204,16 +205,16 @@ abstract class _$LibraryGridSizeState extends $Notifier<int?> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, () => build(itemType: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(MangaFilterDownloadedState)
|
||||
const mangaFilterDownloadedStateProvider = MangaFilterDownloadedStateFamily._();
|
||||
final mangaFilterDownloadedStateProvider = MangaFilterDownloadedStateFamily._();
|
||||
|
||||
final class MangaFilterDownloadedStateProvider
|
||||
extends $NotifierProvider<MangaFilterDownloadedState, int> {
|
||||
const MangaFilterDownloadedStateProvider._({
|
||||
MangaFilterDownloadedStateProvider._({
|
||||
required MangaFilterDownloadedStateFamily super.from,
|
||||
required ({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
super.argument,
|
||||
|
|
@ -271,7 +272,7 @@ final class MangaFilterDownloadedStateFamily extends $Family
|
|||
int,
|
||||
({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
> {
|
||||
const MangaFilterDownloadedStateFamily._()
|
||||
MangaFilterDownloadedStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'mangaFilterDownloadedStateProvider',
|
||||
|
|
@ -309,11 +310,6 @@ abstract class _$MangaFilterDownloadedState extends $Notifier<int> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
);
|
||||
final ref = this.ref as $Ref<int, int>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -323,16 +319,23 @@ abstract class _$MangaFilterDownloadedState extends $Notifier<int> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(MangaFilterUnreadState)
|
||||
const mangaFilterUnreadStateProvider = MangaFilterUnreadStateFamily._();
|
||||
final mangaFilterUnreadStateProvider = MangaFilterUnreadStateFamily._();
|
||||
|
||||
final class MangaFilterUnreadStateProvider
|
||||
extends $NotifierProvider<MangaFilterUnreadState, int> {
|
||||
const MangaFilterUnreadStateProvider._({
|
||||
MangaFilterUnreadStateProvider._({
|
||||
required MangaFilterUnreadStateFamily super.from,
|
||||
required ({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
super.argument,
|
||||
|
|
@ -390,7 +393,7 @@ final class MangaFilterUnreadStateFamily extends $Family
|
|||
int,
|
||||
({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
> {
|
||||
const MangaFilterUnreadStateFamily._()
|
||||
MangaFilterUnreadStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'mangaFilterUnreadStateProvider',
|
||||
|
|
@ -428,11 +431,6 @@ abstract class _$MangaFilterUnreadState extends $Notifier<int> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
);
|
||||
final ref = this.ref as $Ref<int, int>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -442,16 +440,23 @@ abstract class _$MangaFilterUnreadState extends $Notifier<int> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(MangaFilterStartedState)
|
||||
const mangaFilterStartedStateProvider = MangaFilterStartedStateFamily._();
|
||||
final mangaFilterStartedStateProvider = MangaFilterStartedStateFamily._();
|
||||
|
||||
final class MangaFilterStartedStateProvider
|
||||
extends $NotifierProvider<MangaFilterStartedState, int> {
|
||||
const MangaFilterStartedStateProvider._({
|
||||
MangaFilterStartedStateProvider._({
|
||||
required MangaFilterStartedStateFamily super.from,
|
||||
required ({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
super.argument,
|
||||
|
|
@ -509,7 +514,7 @@ final class MangaFilterStartedStateFamily extends $Family
|
|||
int,
|
||||
({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
> {
|
||||
const MangaFilterStartedStateFamily._()
|
||||
MangaFilterStartedStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'mangaFilterStartedStateProvider',
|
||||
|
|
@ -547,11 +552,6 @@ abstract class _$MangaFilterStartedState extends $Notifier<int> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
);
|
||||
final ref = this.ref as $Ref<int, int>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -561,16 +561,23 @@ abstract class _$MangaFilterStartedState extends $Notifier<int> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(MangaFilterBookmarkedState)
|
||||
const mangaFilterBookmarkedStateProvider = MangaFilterBookmarkedStateFamily._();
|
||||
final mangaFilterBookmarkedStateProvider = MangaFilterBookmarkedStateFamily._();
|
||||
|
||||
final class MangaFilterBookmarkedStateProvider
|
||||
extends $NotifierProvider<MangaFilterBookmarkedState, int> {
|
||||
const MangaFilterBookmarkedStateProvider._({
|
||||
MangaFilterBookmarkedStateProvider._({
|
||||
required MangaFilterBookmarkedStateFamily super.from,
|
||||
required ({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
super.argument,
|
||||
|
|
@ -628,7 +635,7 @@ final class MangaFilterBookmarkedStateFamily extends $Family
|
|||
int,
|
||||
({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
> {
|
||||
const MangaFilterBookmarkedStateFamily._()
|
||||
MangaFilterBookmarkedStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'mangaFilterBookmarkedStateProvider',
|
||||
|
|
@ -666,11 +673,6 @@ abstract class _$MangaFilterBookmarkedState extends $Notifier<int> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
);
|
||||
final ref = this.ref as $Ref<int, int>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -680,16 +682,23 @@ abstract class _$MangaFilterBookmarkedState extends $Notifier<int> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(MangasFilterResultState)
|
||||
const mangasFilterResultStateProvider = MangasFilterResultStateFamily._();
|
||||
final mangasFilterResultStateProvider = MangasFilterResultStateFamily._();
|
||||
|
||||
final class MangasFilterResultStateProvider
|
||||
extends $NotifierProvider<MangasFilterResultState, bool> {
|
||||
const MangasFilterResultStateProvider._({
|
||||
MangasFilterResultStateProvider._({
|
||||
required MangasFilterResultStateFamily super.from,
|
||||
required ({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
super.argument,
|
||||
|
|
@ -747,7 +756,7 @@ final class MangasFilterResultStateFamily extends $Family
|
|||
bool,
|
||||
({List<Manga> mangaList, ItemType itemType, Settings settings})
|
||||
> {
|
||||
const MangasFilterResultStateFamily._()
|
||||
MangasFilterResultStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'mangasFilterResultStateProvider',
|
||||
|
|
@ -785,11 +794,6 @@ abstract class _$MangasFilterResultState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
);
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -799,17 +803,24 @@ abstract class _$MangasFilterResultState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(
|
||||
mangaList: _$args.mangaList,
|
||||
itemType: _$args.itemType,
|
||||
settings: _$args.settings,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(LibraryShowCategoryTabsState)
|
||||
const libraryShowCategoryTabsStateProvider =
|
||||
final libraryShowCategoryTabsStateProvider =
|
||||
LibraryShowCategoryTabsStateFamily._();
|
||||
|
||||
final class LibraryShowCategoryTabsStateProvider
|
||||
extends $NotifierProvider<LibraryShowCategoryTabsState, bool> {
|
||||
const LibraryShowCategoryTabsStateProvider._({
|
||||
LibraryShowCategoryTabsStateProvider._({
|
||||
required LibraryShowCategoryTabsStateFamily super.from,
|
||||
required ({ItemType itemType, Settings settings}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -866,7 +877,7 @@ final class LibraryShowCategoryTabsStateFamily extends $Family
|
|||
bool,
|
||||
({ItemType itemType, Settings settings})
|
||||
> {
|
||||
const LibraryShowCategoryTabsStateFamily._()
|
||||
LibraryShowCategoryTabsStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'libraryShowCategoryTabsStateProvider',
|
||||
|
|
@ -896,7 +907,6 @@ abstract class _$LibraryShowCategoryTabsState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args.itemType, settings: _$args.settings);
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -906,17 +916,20 @@ abstract class _$LibraryShowCategoryTabsState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(itemType: _$args.itemType, settings: _$args.settings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(LibraryDownloadedChaptersState)
|
||||
const libraryDownloadedChaptersStateProvider =
|
||||
final libraryDownloadedChaptersStateProvider =
|
||||
LibraryDownloadedChaptersStateFamily._();
|
||||
|
||||
final class LibraryDownloadedChaptersStateProvider
|
||||
extends $NotifierProvider<LibraryDownloadedChaptersState, bool> {
|
||||
const LibraryDownloadedChaptersStateProvider._({
|
||||
LibraryDownloadedChaptersStateProvider._({
|
||||
required LibraryDownloadedChaptersStateFamily super.from,
|
||||
required ({ItemType itemType, Settings settings}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -973,7 +986,7 @@ final class LibraryDownloadedChaptersStateFamily extends $Family
|
|||
bool,
|
||||
({ItemType itemType, Settings settings})
|
||||
> {
|
||||
const LibraryDownloadedChaptersStateFamily._()
|
||||
LibraryDownloadedChaptersStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'libraryDownloadedChaptersStateProvider',
|
||||
|
|
@ -1003,7 +1016,6 @@ abstract class _$LibraryDownloadedChaptersState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args.itemType, settings: _$args.settings);
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -1013,16 +1025,19 @@ abstract class _$LibraryDownloadedChaptersState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(itemType: _$args.itemType, settings: _$args.settings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(LibraryLanguageState)
|
||||
const libraryLanguageStateProvider = LibraryLanguageStateFamily._();
|
||||
final libraryLanguageStateProvider = LibraryLanguageStateFamily._();
|
||||
|
||||
final class LibraryLanguageStateProvider
|
||||
extends $NotifierProvider<LibraryLanguageState, bool> {
|
||||
const LibraryLanguageStateProvider._({
|
||||
LibraryLanguageStateProvider._({
|
||||
required LibraryLanguageStateFamily super.from,
|
||||
required ({ItemType itemType, Settings settings}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -1078,7 +1093,7 @@ final class LibraryLanguageStateFamily extends $Family
|
|||
bool,
|
||||
({ItemType itemType, Settings settings})
|
||||
> {
|
||||
const LibraryLanguageStateFamily._()
|
||||
LibraryLanguageStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'libraryLanguageStateProvider',
|
||||
|
|
@ -1108,7 +1123,6 @@ abstract class _$LibraryLanguageState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args.itemType, settings: _$args.settings);
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -1118,16 +1132,19 @@ abstract class _$LibraryLanguageState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(itemType: _$args.itemType, settings: _$args.settings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(LibraryLocalSourceState)
|
||||
const libraryLocalSourceStateProvider = LibraryLocalSourceStateFamily._();
|
||||
final libraryLocalSourceStateProvider = LibraryLocalSourceStateFamily._();
|
||||
|
||||
final class LibraryLocalSourceStateProvider
|
||||
extends $NotifierProvider<LibraryLocalSourceState, bool> {
|
||||
const LibraryLocalSourceStateProvider._({
|
||||
LibraryLocalSourceStateProvider._({
|
||||
required LibraryLocalSourceStateFamily super.from,
|
||||
required ({ItemType itemType, Settings settings}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -1184,7 +1201,7 @@ final class LibraryLocalSourceStateFamily extends $Family
|
|||
bool,
|
||||
({ItemType itemType, Settings settings})
|
||||
> {
|
||||
const LibraryLocalSourceStateFamily._()
|
||||
LibraryLocalSourceStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'libraryLocalSourceStateProvider',
|
||||
|
|
@ -1214,7 +1231,6 @@ abstract class _$LibraryLocalSourceState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args.itemType, settings: _$args.settings);
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -1224,17 +1240,20 @@ abstract class _$LibraryLocalSourceState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(itemType: _$args.itemType, settings: _$args.settings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(LibraryShowNumbersOfItemsState)
|
||||
const libraryShowNumbersOfItemsStateProvider =
|
||||
final libraryShowNumbersOfItemsStateProvider =
|
||||
LibraryShowNumbersOfItemsStateFamily._();
|
||||
|
||||
final class LibraryShowNumbersOfItemsStateProvider
|
||||
extends $NotifierProvider<LibraryShowNumbersOfItemsState, bool> {
|
||||
const LibraryShowNumbersOfItemsStateProvider._({
|
||||
LibraryShowNumbersOfItemsStateProvider._({
|
||||
required LibraryShowNumbersOfItemsStateFamily super.from,
|
||||
required ({ItemType itemType, Settings settings}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -1291,7 +1310,7 @@ final class LibraryShowNumbersOfItemsStateFamily extends $Family
|
|||
bool,
|
||||
({ItemType itemType, Settings settings})
|
||||
> {
|
||||
const LibraryShowNumbersOfItemsStateFamily._()
|
||||
LibraryShowNumbersOfItemsStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'libraryShowNumbersOfItemsStateProvider',
|
||||
|
|
@ -1321,7 +1340,6 @@ abstract class _$LibraryShowNumbersOfItemsState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args.itemType, settings: _$args.settings);
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -1331,17 +1349,20 @@ abstract class _$LibraryShowNumbersOfItemsState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(itemType: _$args.itemType, settings: _$args.settings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(LibraryShowContinueReadingButtonState)
|
||||
const libraryShowContinueReadingButtonStateProvider =
|
||||
final libraryShowContinueReadingButtonStateProvider =
|
||||
LibraryShowContinueReadingButtonStateFamily._();
|
||||
|
||||
final class LibraryShowContinueReadingButtonStateProvider
|
||||
extends $NotifierProvider<LibraryShowContinueReadingButtonState, bool> {
|
||||
const LibraryShowContinueReadingButtonStateProvider._({
|
||||
LibraryShowContinueReadingButtonStateProvider._({
|
||||
required LibraryShowContinueReadingButtonStateFamily super.from,
|
||||
required ({ItemType itemType, Settings settings}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -1400,7 +1421,7 @@ final class LibraryShowContinueReadingButtonStateFamily extends $Family
|
|||
bool,
|
||||
({ItemType itemType, Settings settings})
|
||||
> {
|
||||
const LibraryShowContinueReadingButtonStateFamily._()
|
||||
LibraryShowContinueReadingButtonStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'libraryShowContinueReadingButtonStateProvider',
|
||||
|
|
@ -1430,7 +1451,6 @@ abstract class _$LibraryShowContinueReadingButtonState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args.itemType, settings: _$args.settings);
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -1440,16 +1460,19 @@ abstract class _$LibraryShowContinueReadingButtonState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(itemType: _$args.itemType, settings: _$args.settings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(SortLibraryMangaState)
|
||||
const sortLibraryMangaStateProvider = SortLibraryMangaStateFamily._();
|
||||
final sortLibraryMangaStateProvider = SortLibraryMangaStateFamily._();
|
||||
|
||||
final class SortLibraryMangaStateProvider
|
||||
extends $NotifierProvider<SortLibraryMangaState, SortLibraryManga> {
|
||||
const SortLibraryMangaStateProvider._({
|
||||
SortLibraryMangaStateProvider._({
|
||||
required SortLibraryMangaStateFamily super.from,
|
||||
required ({ItemType itemType, Settings settings}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -1505,7 +1528,7 @@ final class SortLibraryMangaStateFamily extends $Family
|
|||
SortLibraryManga,
|
||||
({ItemType itemType, Settings settings})
|
||||
> {
|
||||
const SortLibraryMangaStateFamily._()
|
||||
SortLibraryMangaStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'sortLibraryMangaStateProvider',
|
||||
|
|
@ -1538,7 +1561,6 @@ abstract class _$SortLibraryMangaState extends $Notifier<SortLibraryManga> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(itemType: _$args.itemType, settings: _$args.settings);
|
||||
final ref = this.ref as $Ref<SortLibraryManga, SortLibraryManga>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -1548,16 +1570,19 @@ abstract class _$SortLibraryMangaState extends $Notifier<SortLibraryManga> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(itemType: _$args.itemType, settings: _$args.settings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(MangasListState)
|
||||
const mangasListStateProvider = MangasListStateProvider._();
|
||||
final mangasListStateProvider = MangasListStateProvider._();
|
||||
|
||||
final class MangasListStateProvider
|
||||
extends $NotifierProvider<MangasListState, List<int>> {
|
||||
const MangasListStateProvider._()
|
||||
MangasListStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -1591,7 +1616,6 @@ abstract class _$MangasListState extends $Notifier<List<int>> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<List<int>, List<int>>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -1601,16 +1625,16 @@ abstract class _$MangasListState extends $Notifier<List<int>> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(MangasSetIsReadState)
|
||||
const mangasSetIsReadStateProvider = MangasSetIsReadStateFamily._();
|
||||
final mangasSetIsReadStateProvider = MangasSetIsReadStateFamily._();
|
||||
|
||||
final class MangasSetIsReadStateProvider
|
||||
extends $NotifierProvider<MangasSetIsReadState, void> {
|
||||
const MangasSetIsReadStateProvider._({
|
||||
MangasSetIsReadStateProvider._({
|
||||
required MangasSetIsReadStateFamily super.from,
|
||||
required ({List<int> mangaIds, bool markAsRead}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -1666,7 +1690,7 @@ final class MangasSetIsReadStateFamily extends $Family
|
|||
void,
|
||||
({List<int> mangaIds, bool markAsRead})
|
||||
> {
|
||||
const MangasSetIsReadStateFamily._()
|
||||
MangasSetIsReadStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'mangasSetIsReadStateProvider',
|
||||
|
|
@ -1696,7 +1720,6 @@ abstract class _$MangasSetIsReadState extends $Notifier<void> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
build(mangaIds: _$args.mangaIds, markAsRead: _$args.markAsRead);
|
||||
final ref = this.ref as $Ref<void, void>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -1706,6 +1729,9 @@ abstract class _$MangasSetIsReadState extends $Notifier<void> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, null);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(mangaIds: _$args.mangaIds, markAsRead: _$args.markAsRead),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,18 +85,14 @@ Future importArchivesFromFile(
|
|||
: Uint8List.fromList(coverImage).getCoverImage,
|
||||
);
|
||||
}
|
||||
for (var chapter in book.Chapters ?? []) {
|
||||
chapters.add(
|
||||
Chapter(
|
||||
mangaId: mangaId,
|
||||
name: chapter.Title is String && chapter.Title.isEmpty
|
||||
? "Book"
|
||||
: chapter.Title,
|
||||
archivePath: file.path,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
}
|
||||
chapters.add(
|
||||
Chapter(
|
||||
mangaId: mangaId,
|
||||
name: book.Title,
|
||||
archivePath: file.path,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
} else {
|
||||
chapters.add(
|
||||
Chapter(
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ part of 'local_archive.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(importArchivesFromFile)
|
||||
const importArchivesFromFileProvider = ImportArchivesFromFileFamily._();
|
||||
final importArchivesFromFileProvider = ImportArchivesFromFileFamily._();
|
||||
|
||||
final class ImportArchivesFromFileProvider
|
||||
extends $FunctionalProvider<AsyncValue<dynamic>, dynamic, FutureOr<dynamic>>
|
||||
with $FutureModifier<dynamic>, $FutureProvider<dynamic> {
|
||||
const ImportArchivesFromFileProvider._({
|
||||
ImportArchivesFromFileProvider._({
|
||||
required ImportArchivesFromFileFamily super.from,
|
||||
required (Manga?, {ItemType itemType, bool init}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -65,7 +65,7 @@ final class ImportArchivesFromFileProvider
|
|||
}
|
||||
|
||||
String _$importArchivesFromFileHash() =>
|
||||
r'a3fbf9d9ba7eacfa52366bfb10ba9f5f9117585b';
|
||||
r'8a26aaed0c29e76899ab37c6f64a1f8b80792e41';
|
||||
|
||||
final class ImportArchivesFromFileFamily extends $Family
|
||||
with
|
||||
|
|
@ -73,7 +73,7 @@ final class ImportArchivesFromFileFamily extends $Family
|
|||
FutureOr<dynamic>,
|
||||
(Manga?, {ItemType itemType, bool init})
|
||||
> {
|
||||
const ImportArchivesFromFileFamily._()
|
||||
ImportArchivesFromFileFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'importArchivesFromFileProvider',
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ part of 'migration.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(migration)
|
||||
const migrationProvider = MigrationProvider._();
|
||||
final migrationProvider = MigrationProvider._();
|
||||
|
||||
final class MigrationProvider
|
||||
extends $FunctionalProvider<AsyncValue<void>, void, FutureOr<void>>
|
||||
with $FutureModifier<void>, $FutureProvider<void> {
|
||||
const MigrationProvider._()
|
||||
MigrationProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ part of 'archive_reader_providers.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(getArchivesDataFromDirectory)
|
||||
const getArchivesDataFromDirectoryProvider =
|
||||
final getArchivesDataFromDirectoryProvider =
|
||||
GetArchivesDataFromDirectoryFamily._();
|
||||
|
||||
final class GetArchivesDataFromDirectoryProvider
|
||||
|
|
@ -23,7 +23,7 @@ final class GetArchivesDataFromDirectoryProvider
|
|||
with
|
||||
$FutureModifier<List<(String, LocalExtensionType, Uint8List, String)>>,
|
||||
$FutureProvider<List<(String, LocalExtensionType, Uint8List, String)>> {
|
||||
const GetArchivesDataFromDirectoryProvider._({
|
||||
GetArchivesDataFromDirectoryProvider._({
|
||||
required GetArchivesDataFromDirectoryFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
|
|
@ -78,7 +78,7 @@ final class GetArchivesDataFromDirectoryFamily extends $Family
|
|||
FutureOr<List<(String, LocalExtensionType, Uint8List, String)>>,
|
||||
String
|
||||
> {
|
||||
const GetArchivesDataFromDirectoryFamily._()
|
||||
GetArchivesDataFromDirectoryFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getArchivesDataFromDirectoryProvider',
|
||||
|
|
@ -95,7 +95,7 @@ final class GetArchivesDataFromDirectoryFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(getArchiveDataFromDirectory)
|
||||
const getArchiveDataFromDirectoryProvider =
|
||||
final getArchiveDataFromDirectoryProvider =
|
||||
GetArchiveDataFromDirectoryFamily._();
|
||||
|
||||
final class GetArchiveDataFromDirectoryProvider
|
||||
|
|
@ -108,7 +108,7 @@ final class GetArchiveDataFromDirectoryProvider
|
|||
with
|
||||
$FutureModifier<List<LocalArchive>>,
|
||||
$FutureProvider<List<LocalArchive>> {
|
||||
const GetArchiveDataFromDirectoryProvider._({
|
||||
GetArchiveDataFromDirectoryProvider._({
|
||||
required GetArchiveDataFromDirectoryFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
|
|
@ -158,7 +158,7 @@ String _$getArchiveDataFromDirectoryHash() =>
|
|||
|
||||
final class GetArchiveDataFromDirectoryFamily extends $Family
|
||||
with $FunctionalFamilyOverride<FutureOr<List<LocalArchive>>, String> {
|
||||
const GetArchiveDataFromDirectoryFamily._()
|
||||
GetArchiveDataFromDirectoryFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getArchiveDataFromDirectoryProvider',
|
||||
|
|
@ -175,7 +175,7 @@ final class GetArchiveDataFromDirectoryFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(getArchivesDataFromFile)
|
||||
const getArchivesDataFromFileProvider = GetArchivesDataFromFileFamily._();
|
||||
final getArchivesDataFromFileProvider = GetArchivesDataFromFileFamily._();
|
||||
|
||||
final class GetArchivesDataFromFileProvider
|
||||
extends
|
||||
|
|
@ -187,7 +187,7 @@ final class GetArchivesDataFromFileProvider
|
|||
with
|
||||
$FutureModifier<(String, LocalExtensionType, Uint8List, String)>,
|
||||
$FutureProvider<(String, LocalExtensionType, Uint8List, String)> {
|
||||
const GetArchivesDataFromFileProvider._({
|
||||
GetArchivesDataFromFileProvider._({
|
||||
required GetArchivesDataFromFileFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
|
|
@ -240,7 +240,7 @@ final class GetArchivesDataFromFileFamily extends $Family
|
|||
FutureOr<(String, LocalExtensionType, Uint8List, String)>,
|
||||
String
|
||||
> {
|
||||
const GetArchivesDataFromFileFamily._()
|
||||
GetArchivesDataFromFileFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getArchivesDataFromFileProvider',
|
||||
|
|
@ -257,7 +257,7 @@ final class GetArchivesDataFromFileFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(getArchiveDataFromFile)
|
||||
const getArchiveDataFromFileProvider = GetArchiveDataFromFileFamily._();
|
||||
final getArchiveDataFromFileProvider = GetArchiveDataFromFileFamily._();
|
||||
|
||||
final class GetArchiveDataFromFileProvider
|
||||
extends
|
||||
|
|
@ -267,7 +267,7 @@ final class GetArchiveDataFromFileProvider
|
|||
FutureOr<LocalArchive>
|
||||
>
|
||||
with $FutureModifier<LocalArchive>, $FutureProvider<LocalArchive> {
|
||||
const GetArchiveDataFromFileProvider._({
|
||||
GetArchiveDataFromFileProvider._({
|
||||
required GetArchiveDataFromFileFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
|
|
@ -317,7 +317,7 @@ String _$getArchiveDataFromFileHash() =>
|
|||
|
||||
final class GetArchiveDataFromFileFamily extends $Family
|
||||
with $FunctionalFamilyOverride<FutureOr<LocalArchive>, String> {
|
||||
const GetArchiveDataFromFileFamily._()
|
||||
GetArchiveDataFromFileFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getArchiveDataFromFileProvider',
|
||||
|
|
|
|||
|
|
@ -1936,10 +1936,11 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
return Container(
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(child: widget.action!),
|
||||
if (!isLocalArchive) Expanded(child: _smartUpdateDays()),
|
||||
if (widget.itemType != ItemType.novel) Expanded(child: _action()),
|
||||
_action(),
|
||||
if (!isLocalArchive)
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
|
|
@ -2031,9 +2032,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
builder: (context, snapshot) {
|
||||
List<TrackPreference>? entries = snapshot.hasData ? snapshot.data! : [];
|
||||
if (entries.isEmpty) {
|
||||
return Container();
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return SizedBox(
|
||||
return Expanded(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ part of 'isar_providers.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(getMangaDetailStream)
|
||||
const getMangaDetailStreamProvider = GetMangaDetailStreamFamily._();
|
||||
final getMangaDetailStreamProvider = GetMangaDetailStreamFamily._();
|
||||
|
||||
final class GetMangaDetailStreamProvider
|
||||
extends $FunctionalProvider<AsyncValue<Manga?>, Manga?, Stream<Manga?>>
|
||||
with $FutureModifier<Manga?>, $StreamProvider<Manga?> {
|
||||
const GetMangaDetailStreamProvider._({
|
||||
GetMangaDetailStreamProvider._({
|
||||
required GetMangaDetailStreamFamily super.from,
|
||||
required int super.argument,
|
||||
}) : super(
|
||||
|
|
@ -63,7 +63,7 @@ String _$getMangaDetailStreamHash() =>
|
|||
|
||||
final class GetMangaDetailStreamFamily extends $Family
|
||||
with $FunctionalFamilyOverride<Stream<Manga?>, int> {
|
||||
const GetMangaDetailStreamFamily._()
|
||||
GetMangaDetailStreamFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getMangaDetailStreamProvider',
|
||||
|
|
@ -80,7 +80,7 @@ final class GetMangaDetailStreamFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(getChaptersStream)
|
||||
const getChaptersStreamProvider = GetChaptersStreamFamily._();
|
||||
final getChaptersStreamProvider = GetChaptersStreamFamily._();
|
||||
|
||||
final class GetChaptersStreamProvider
|
||||
extends
|
||||
|
|
@ -90,7 +90,7 @@ final class GetChaptersStreamProvider
|
|||
Stream<List<Chapter>>
|
||||
>
|
||||
with $FutureModifier<List<Chapter>>, $StreamProvider<List<Chapter>> {
|
||||
const GetChaptersStreamProvider._({
|
||||
GetChaptersStreamProvider._({
|
||||
required GetChaptersStreamFamily super.from,
|
||||
required int super.argument,
|
||||
}) : super(
|
||||
|
|
@ -138,7 +138,7 @@ String _$getChaptersStreamHash() => r'0f03db54c5a639c4356a81e4bad50fa8a077ceac';
|
|||
|
||||
final class GetChaptersStreamFamily extends $Family
|
||||
with $FunctionalFamilyOverride<Stream<List<Chapter>>, int> {
|
||||
const GetChaptersStreamFamily._()
|
||||
GetChaptersStreamFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'getChaptersStreamProvider',
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ part of 'state_providers.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(ChaptersListState)
|
||||
const chaptersListStateProvider = ChaptersListStateProvider._();
|
||||
final chaptersListStateProvider = ChaptersListStateProvider._();
|
||||
|
||||
final class ChaptersListStateProvider
|
||||
extends $NotifierProvider<ChaptersListState, List<Chapter>> {
|
||||
const ChaptersListStateProvider._()
|
||||
ChaptersListStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -48,7 +48,6 @@ abstract class _$ChaptersListState extends $Notifier<List<Chapter>> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<List<Chapter>, List<Chapter>>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -58,16 +57,16 @@ abstract class _$ChaptersListState extends $Notifier<List<Chapter>> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(IsLongPressedState)
|
||||
const isLongPressedStateProvider = IsLongPressedStateProvider._();
|
||||
final isLongPressedStateProvider = IsLongPressedStateProvider._();
|
||||
|
||||
final class IsLongPressedStateProvider
|
||||
extends $NotifierProvider<IsLongPressedState, bool> {
|
||||
const IsLongPressedStateProvider._()
|
||||
IsLongPressedStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -102,7 +101,6 @@ abstract class _$IsLongPressedState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -112,16 +110,16 @@ abstract class _$IsLongPressedState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(IsExtendedState)
|
||||
const isExtendedStateProvider = IsExtendedStateProvider._();
|
||||
final isExtendedStateProvider = IsExtendedStateProvider._();
|
||||
|
||||
final class IsExtendedStateProvider
|
||||
extends $NotifierProvider<IsExtendedState, bool> {
|
||||
const IsExtendedStateProvider._()
|
||||
IsExtendedStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -155,7 +153,6 @@ abstract class _$IsExtendedState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -165,16 +162,16 @@ abstract class _$IsExtendedState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(SortChapterState)
|
||||
const sortChapterStateProvider = SortChapterStateFamily._();
|
||||
final sortChapterStateProvider = SortChapterStateFamily._();
|
||||
|
||||
final class SortChapterStateProvider
|
||||
extends $NotifierProvider<SortChapterState, SortChapter> {
|
||||
const SortChapterStateProvider._({
|
||||
SortChapterStateProvider._({
|
||||
required SortChapterStateFamily super.from,
|
||||
required int super.argument,
|
||||
}) : super(
|
||||
|
|
@ -229,7 +226,7 @@ final class SortChapterStateFamily extends $Family
|
|||
SortChapter,
|
||||
int
|
||||
> {
|
||||
const SortChapterStateFamily._()
|
||||
SortChapterStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'sortChapterStateProvider',
|
||||
|
|
@ -253,7 +250,6 @@ abstract class _$SortChapterState extends $Notifier<SortChapter> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(mangaId: _$args);
|
||||
final ref = this.ref as $Ref<SortChapter, SortChapter>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -263,17 +259,17 @@ abstract class _$SortChapterState extends $Notifier<SortChapter> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, () => build(mangaId: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ChapterFilterDownloadedState)
|
||||
const chapterFilterDownloadedStateProvider =
|
||||
final chapterFilterDownloadedStateProvider =
|
||||
ChapterFilterDownloadedStateFamily._();
|
||||
|
||||
final class ChapterFilterDownloadedStateProvider
|
||||
extends $NotifierProvider<ChapterFilterDownloadedState, int> {
|
||||
const ChapterFilterDownloadedStateProvider._({
|
||||
ChapterFilterDownloadedStateProvider._({
|
||||
required ChapterFilterDownloadedStateFamily super.from,
|
||||
required int super.argument,
|
||||
}) : super(
|
||||
|
|
@ -324,7 +320,7 @@ String _$chapterFilterDownloadedStateHash() =>
|
|||
final class ChapterFilterDownloadedStateFamily extends $Family
|
||||
with
|
||||
$ClassFamilyOverride<ChapterFilterDownloadedState, int, int, int, int> {
|
||||
const ChapterFilterDownloadedStateFamily._()
|
||||
ChapterFilterDownloadedStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'chapterFilterDownloadedStateProvider',
|
||||
|
|
@ -348,7 +344,6 @@ abstract class _$ChapterFilterDownloadedState extends $Notifier<int> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(mangaId: _$args);
|
||||
final ref = this.ref as $Ref<int, int>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -358,16 +353,16 @@ abstract class _$ChapterFilterDownloadedState extends $Notifier<int> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, () => build(mangaId: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ChapterFilterUnreadState)
|
||||
const chapterFilterUnreadStateProvider = ChapterFilterUnreadStateFamily._();
|
||||
final chapterFilterUnreadStateProvider = ChapterFilterUnreadStateFamily._();
|
||||
|
||||
final class ChapterFilterUnreadStateProvider
|
||||
extends $NotifierProvider<ChapterFilterUnreadState, int> {
|
||||
const ChapterFilterUnreadStateProvider._({
|
||||
ChapterFilterUnreadStateProvider._({
|
||||
required ChapterFilterUnreadStateFamily super.from,
|
||||
required int super.argument,
|
||||
}) : super(
|
||||
|
|
@ -417,7 +412,7 @@ String _$chapterFilterUnreadStateHash() =>
|
|||
|
||||
final class ChapterFilterUnreadStateFamily extends $Family
|
||||
with $ClassFamilyOverride<ChapterFilterUnreadState, int, int, int, int> {
|
||||
const ChapterFilterUnreadStateFamily._()
|
||||
ChapterFilterUnreadStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'chapterFilterUnreadStateProvider',
|
||||
|
|
@ -441,7 +436,6 @@ abstract class _$ChapterFilterUnreadState extends $Notifier<int> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(mangaId: _$args);
|
||||
final ref = this.ref as $Ref<int, int>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -451,17 +445,17 @@ abstract class _$ChapterFilterUnreadState extends $Notifier<int> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, () => build(mangaId: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ChapterFilterBookmarkedState)
|
||||
const chapterFilterBookmarkedStateProvider =
|
||||
final chapterFilterBookmarkedStateProvider =
|
||||
ChapterFilterBookmarkedStateFamily._();
|
||||
|
||||
final class ChapterFilterBookmarkedStateProvider
|
||||
extends $NotifierProvider<ChapterFilterBookmarkedState, int> {
|
||||
const ChapterFilterBookmarkedStateProvider._({
|
||||
ChapterFilterBookmarkedStateProvider._({
|
||||
required ChapterFilterBookmarkedStateFamily super.from,
|
||||
required int super.argument,
|
||||
}) : super(
|
||||
|
|
@ -512,7 +506,7 @@ String _$chapterFilterBookmarkedStateHash() =>
|
|||
final class ChapterFilterBookmarkedStateFamily extends $Family
|
||||
with
|
||||
$ClassFamilyOverride<ChapterFilterBookmarkedState, int, int, int, int> {
|
||||
const ChapterFilterBookmarkedStateFamily._()
|
||||
ChapterFilterBookmarkedStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'chapterFilterBookmarkedStateProvider',
|
||||
|
|
@ -536,7 +530,6 @@ abstract class _$ChapterFilterBookmarkedState extends $Notifier<int> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(mangaId: _$args);
|
||||
final ref = this.ref as $Ref<int, int>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -546,16 +539,16 @@ abstract class _$ChapterFilterBookmarkedState extends $Notifier<int> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, () => build(mangaId: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ChapterFilterResultState)
|
||||
const chapterFilterResultStateProvider = ChapterFilterResultStateFamily._();
|
||||
final chapterFilterResultStateProvider = ChapterFilterResultStateFamily._();
|
||||
|
||||
final class ChapterFilterResultStateProvider
|
||||
extends $NotifierProvider<ChapterFilterResultState, bool> {
|
||||
const ChapterFilterResultStateProvider._({
|
||||
ChapterFilterResultStateProvider._({
|
||||
required ChapterFilterResultStateFamily super.from,
|
||||
required Manga super.argument,
|
||||
}) : super(
|
||||
|
|
@ -612,7 +605,7 @@ final class ChapterFilterResultStateFamily extends $Family
|
|||
bool,
|
||||
Manga
|
||||
> {
|
||||
const ChapterFilterResultStateFamily._()
|
||||
ChapterFilterResultStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'chapterFilterResultStateProvider',
|
||||
|
|
@ -636,7 +629,6 @@ abstract class _$ChapterFilterResultState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(manga: _$args);
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -646,16 +638,16 @@ abstract class _$ChapterFilterResultState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, () => build(manga: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ChapterSetIsBookmarkState)
|
||||
const chapterSetIsBookmarkStateProvider = ChapterSetIsBookmarkStateFamily._();
|
||||
final chapterSetIsBookmarkStateProvider = ChapterSetIsBookmarkStateFamily._();
|
||||
|
||||
final class ChapterSetIsBookmarkStateProvider
|
||||
extends $NotifierProvider<ChapterSetIsBookmarkState, void> {
|
||||
const ChapterSetIsBookmarkStateProvider._({
|
||||
ChapterSetIsBookmarkStateProvider._({
|
||||
required ChapterSetIsBookmarkStateFamily super.from,
|
||||
required Manga super.argument,
|
||||
}) : super(
|
||||
|
|
@ -712,7 +704,7 @@ final class ChapterSetIsBookmarkStateFamily extends $Family
|
|||
void,
|
||||
Manga
|
||||
> {
|
||||
const ChapterSetIsBookmarkStateFamily._()
|
||||
ChapterSetIsBookmarkStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'chapterSetIsBookmarkStateProvider',
|
||||
|
|
@ -736,7 +728,6 @@ abstract class _$ChapterSetIsBookmarkState extends $Notifier<void> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
build(manga: _$args);
|
||||
final ref = this.ref as $Ref<void, void>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -746,16 +737,16 @@ abstract class _$ChapterSetIsBookmarkState extends $Notifier<void> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, null);
|
||||
element.handleCreate(ref, () => build(manga: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ChapterSetIsReadState)
|
||||
const chapterSetIsReadStateProvider = ChapterSetIsReadStateFamily._();
|
||||
final chapterSetIsReadStateProvider = ChapterSetIsReadStateFamily._();
|
||||
|
||||
final class ChapterSetIsReadStateProvider
|
||||
extends $NotifierProvider<ChapterSetIsReadState, void> {
|
||||
const ChapterSetIsReadStateProvider._({
|
||||
ChapterSetIsReadStateProvider._({
|
||||
required ChapterSetIsReadStateFamily super.from,
|
||||
required Manga super.argument,
|
||||
}) : super(
|
||||
|
|
@ -804,7 +795,7 @@ String _$chapterSetIsReadStateHash() =>
|
|||
|
||||
final class ChapterSetIsReadStateFamily extends $Family
|
||||
with $ClassFamilyOverride<ChapterSetIsReadState, void, void, void, Manga> {
|
||||
const ChapterSetIsReadStateFamily._()
|
||||
ChapterSetIsReadStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'chapterSetIsReadStateProvider',
|
||||
|
|
@ -828,7 +819,6 @@ abstract class _$ChapterSetIsReadState extends $Notifier<void> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
build(manga: _$args);
|
||||
final ref = this.ref as $Ref<void, void>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -838,16 +828,16 @@ abstract class _$ChapterSetIsReadState extends $Notifier<void> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, null);
|
||||
element.handleCreate(ref, () => build(manga: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ChapterSetDownloadState)
|
||||
const chapterSetDownloadStateProvider = ChapterSetDownloadStateFamily._();
|
||||
final chapterSetDownloadStateProvider = ChapterSetDownloadStateFamily._();
|
||||
|
||||
final class ChapterSetDownloadStateProvider
|
||||
extends $NotifierProvider<ChapterSetDownloadState, void> {
|
||||
const ChapterSetDownloadStateProvider._({
|
||||
ChapterSetDownloadStateProvider._({
|
||||
required ChapterSetDownloadStateFamily super.from,
|
||||
required Manga super.argument,
|
||||
}) : super(
|
||||
|
|
@ -898,7 +888,7 @@ String _$chapterSetDownloadStateHash() =>
|
|||
final class ChapterSetDownloadStateFamily extends $Family
|
||||
with
|
||||
$ClassFamilyOverride<ChapterSetDownloadState, void, void, void, Manga> {
|
||||
const ChapterSetDownloadStateFamily._()
|
||||
ChapterSetDownloadStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'chapterSetDownloadStateProvider',
|
||||
|
|
@ -922,7 +912,6 @@ abstract class _$ChapterSetDownloadState extends $Notifier<void> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
build(manga: _$args);
|
||||
final ref = this.ref as $Ref<void, void>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -932,16 +921,16 @@ abstract class _$ChapterSetDownloadState extends $Notifier<void> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, null);
|
||||
element.handleCreate(ref, () => build(manga: _$args));
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ChaptersListttState)
|
||||
const chaptersListttStateProvider = ChaptersListttStateProvider._();
|
||||
final chaptersListttStateProvider = ChaptersListttStateProvider._();
|
||||
|
||||
final class ChaptersListttStateProvider
|
||||
extends $NotifierProvider<ChaptersListttState, List<Chapter>> {
|
||||
const ChaptersListttStateProvider._()
|
||||
ChaptersListttStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -976,7 +965,6 @@ abstract class _$ChaptersListttState extends $Notifier<List<Chapter>> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<List<Chapter>, List<Chapter>>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -986,12 +974,12 @@ abstract class _$ChaptersListttState extends $Notifier<List<Chapter>> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ScanlatorsFilterState)
|
||||
const scanlatorsFilterStateProvider = ScanlatorsFilterStateFamily._();
|
||||
final scanlatorsFilterStateProvider = ScanlatorsFilterStateFamily._();
|
||||
|
||||
final class ScanlatorsFilterStateProvider
|
||||
extends
|
||||
|
|
@ -999,7 +987,7 @@ final class ScanlatorsFilterStateProvider
|
|||
ScanlatorsFilterState,
|
||||
(List<String>, List<String>, List<String>)
|
||||
> {
|
||||
const ScanlatorsFilterStateProvider._({
|
||||
ScanlatorsFilterStateProvider._({
|
||||
required ScanlatorsFilterStateFamily super.from,
|
||||
required Manga super.argument,
|
||||
}) : super(
|
||||
|
|
@ -1056,7 +1044,7 @@ final class ScanlatorsFilterStateFamily extends $Family
|
|||
(List<String>, List<String>, List<String>),
|
||||
Manga
|
||||
> {
|
||||
const ScanlatorsFilterStateFamily._()
|
||||
ScanlatorsFilterStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'scanlatorsFilterStateProvider',
|
||||
|
|
@ -1081,7 +1069,6 @@ abstract class _$ScanlatorsFilterState
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(_$args);
|
||||
final ref =
|
||||
this.ref
|
||||
as $Ref<
|
||||
|
|
@ -1099,6 +1086,6 @@ abstract class _$ScanlatorsFilterState
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, () => build(_$args));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ part of 'track_state_providers.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(TrackState)
|
||||
const trackStateProvider = TrackStateFamily._();
|
||||
final trackStateProvider = TrackStateFamily._();
|
||||
|
||||
final class TrackStateProvider extends $NotifierProvider<TrackState, Track> {
|
||||
const TrackStateProvider._({
|
||||
TrackStateProvider._({
|
||||
required TrackStateFamily super.from,
|
||||
required ({Track? track, ItemType? itemType, dynamic widgetRef})
|
||||
super.argument,
|
||||
|
|
@ -69,7 +69,7 @@ final class TrackStateFamily extends $Family
|
|||
Track,
|
||||
({Track? track, ItemType? itemType, dynamic widgetRef})
|
||||
> {
|
||||
const TrackStateFamily._()
|
||||
TrackStateFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'trackStateProvider',
|
||||
|
|
@ -106,11 +106,6 @@ abstract class _$TrackState extends $Notifier<Track> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build(
|
||||
track: _$args.track,
|
||||
itemType: _$args.itemType,
|
||||
widgetRef: _$args.widgetRef,
|
||||
);
|
||||
final ref = this.ref as $Ref<Track, Track>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -120,17 +115,24 @@ abstract class _$TrackState extends $Notifier<Track> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(
|
||||
ref,
|
||||
() => build(
|
||||
track: _$args.track,
|
||||
itemType: _$args.itemType,
|
||||
widgetRef: _$args.widgetRef,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(LastTrackerLibraryLocationState)
|
||||
const lastTrackerLibraryLocationStateProvider =
|
||||
final lastTrackerLibraryLocationStateProvider =
|
||||
LastTrackerLibraryLocationStateProvider._();
|
||||
|
||||
final class LastTrackerLibraryLocationStateProvider
|
||||
extends $NotifierProvider<LastTrackerLibraryLocationState, (int, bool)> {
|
||||
const LastTrackerLibraryLocationStateProvider._()
|
||||
LastTrackerLibraryLocationStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -166,7 +168,6 @@ abstract class _$LastTrackerLibraryLocationState
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<(int, bool), (int, bool)>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -176,6 +177,6 @@ abstract class _$LastTrackerLibraryLocationState
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,34 +35,29 @@ Future<dynamic> updateMangaDetail(
|
|||
|
||||
final genre =
|
||||
getManga.genre
|
||||
?.map((e) => e.toString().trim().trimLeft().trimRight())
|
||||
?.map((e) => e.toString().trim())
|
||||
.toList()
|
||||
.toSet()
|
||||
.toList() ??
|
||||
[];
|
||||
final tempName = getManga.name?.trim().trimLeft().trimRight();
|
||||
final tempLink = getManga.link?.trim().trimLeft().trimRight();
|
||||
final imgUrl = getManga.imageUrl ?? manga.imageUrl;
|
||||
|
||||
final imgUrl = getManga.imageUrl.trimmedOrDefault(manga.imageUrl);
|
||||
manga
|
||||
..imageUrl = imgUrl == null
|
||||
? null
|
||||
: imgUrl.startsWith('http')
|
||||
? imgUrl
|
||||
: '${source.baseUrl ?? ''}/${imgUrl.getUrlWithoutDomain}'
|
||||
..name = tempName != null && tempName.isNotEmpty ? tempName : manga.name
|
||||
..name = getManga.name.trimmedOrDefault(manga.name)
|
||||
..genre = (genre.isEmpty ? null : genre) ?? manga.genre ?? []
|
||||
..author =
|
||||
getManga.author?.trim().trimLeft().trimRight() ?? manga.author ?? ""
|
||||
..artist =
|
||||
getManga.artist?.trim().trimLeft().trimRight() ?? manga.artist ?? ""
|
||||
..author = getManga.author.trimmedOrDefault(manga.author) ?? ""
|
||||
..artist = getManga.artist.trimmedOrDefault(manga.artist) ?? ""
|
||||
..status = getManga.status == Status.unknown
|
||||
? manga.status
|
||||
: getManga.status ?? Status.unknown
|
||||
..description =
|
||||
getManga.description?.trim().trimLeft().trimRight() ??
|
||||
manga.description ??
|
||||
""
|
||||
..link = tempLink != null && tempLink.isNotEmpty ? tempLink : manga.link
|
||||
getManga.description.trimmedOrDefault(manga.description) ?? ""
|
||||
..link = getManga.link.trimmedOrDefault(manga.link)
|
||||
..source = manga.source
|
||||
..lang = manga.lang
|
||||
..itemType = source.itemType
|
||||
|
|
@ -85,7 +80,7 @@ Future<dynamic> updateMangaDetail(
|
|||
for (var i = 0; i < newChapsIndex; i++) {
|
||||
final chapter = Chapter(
|
||||
name: chaps[i].name!,
|
||||
url: chaps[i].url!.trim().trimLeft().trimRight(),
|
||||
url: chaps[i].url!.trim(),
|
||||
dateUpload: chaps[i].dateUpload == null
|
||||
? DateTime.now().millisecondsSinceEpoch.toString()
|
||||
: chaps[i].dateUpload.toString(),
|
||||
|
|
@ -173,3 +168,12 @@ Future<dynamic> updateMangaDetail(
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
extension DefaultValueExtension on String? {
|
||||
String? trimmedOrDefault(String? defaultValue) {
|
||||
if (this?.trim().isNotEmpty ?? false) {
|
||||
return this!.trim();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ part of 'update_manga_detail_providers.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(updateMangaDetail)
|
||||
const updateMangaDetailProvider = UpdateMangaDetailFamily._();
|
||||
final updateMangaDetailProvider = UpdateMangaDetailFamily._();
|
||||
|
||||
final class UpdateMangaDetailProvider
|
||||
extends $FunctionalProvider<AsyncValue<dynamic>, dynamic, FutureOr<dynamic>>
|
||||
with $FutureModifier<dynamic>, $FutureProvider<dynamic> {
|
||||
const UpdateMangaDetailProvider._({
|
||||
UpdateMangaDetailProvider._({
|
||||
required UpdateMangaDetailFamily super.from,
|
||||
required ({int? mangaId, bool isInit, bool showToast}) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -64,7 +64,7 @@ final class UpdateMangaDetailProvider
|
|||
}
|
||||
}
|
||||
|
||||
String _$updateMangaDetailHash() => r'ac2b3fcd446d50a81ad647015e3010c2309f3385';
|
||||
String _$updateMangaDetailHash() => r'37da5f23f30126d15cedfaf42087f9ce11c3fc26';
|
||||
|
||||
final class UpdateMangaDetailFamily extends $Family
|
||||
with
|
||||
|
|
@ -72,7 +72,7 @@ final class UpdateMangaDetailFamily extends $Family
|
|||
FutureOr<dynamic>,
|
||||
({int? mangaId, bool isInit, bool showToast})
|
||||
> {
|
||||
const UpdateMangaDetailFamily._()
|
||||
UpdateMangaDetailFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'updateMangaDetailProvider',
|
||||
|
|
|
|||
|
|
@ -38,15 +38,17 @@ class ChapterListTileWidget extends ConsumerWidget {
|
|||
onLongPress: () => _handleInteraction(ref),
|
||||
onSecondaryTap: () => _handleInteraction(ref),
|
||||
child: ListTile(
|
||||
minLeadingWidth: 3,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 15),
|
||||
minLeadingWidth: 0,
|
||||
horizontalTitleGap: 13,
|
||||
leading: Container(
|
||||
width: 3,
|
||||
height: 25,
|
||||
width: 2,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: chapter.isRead!
|
||||
? Colors.grey.withValues(alpha: 0.3)
|
||||
: context.primaryColor,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
tileColor: (chapter.isFiller ?? false)
|
||||
|
|
@ -62,13 +64,13 @@ class ChapterListTileWidget extends ConsumerWidget {
|
|||
: Colors.white,
|
||||
onTap: () async => _handleInteraction(ref, context),
|
||||
title: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (chapter.thumbnailUrl != null)
|
||||
_thumbnailPreview(context, chapter.thumbnailUrl),
|
||||
chapter.isBookmarked!
|
||||
? Icon(Icons.bookmark, size: 16, color: context.primaryColor)
|
||||
: Container(),
|
||||
: SizedBox.shrink(),
|
||||
chapter.description != null
|
||||
? Flexible(
|
||||
child: Column(
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ part of 'convert_to_cbz.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(convertToCBZ)
|
||||
const convertToCBZProvider = ConvertToCBZFamily._();
|
||||
final convertToCBZProvider = ConvertToCBZFamily._();
|
||||
|
||||
final class ConvertToCBZProvider
|
||||
extends
|
||||
|
|
@ -20,7 +20,7 @@ final class ConvertToCBZProvider
|
|||
FutureOr<List<String>>
|
||||
>
|
||||
with $FutureModifier<List<String>>, $FutureProvider<List<String>> {
|
||||
const ConvertToCBZProvider._({
|
||||
ConvertToCBZProvider._({
|
||||
required ConvertToCBZFamily super.from,
|
||||
required (String, String, String, List<String>) super.argument,
|
||||
}) : super(
|
||||
|
|
@ -78,7 +78,7 @@ final class ConvertToCBZFamily extends $Family
|
|||
FutureOr<List<String>>,
|
||||
(String, String, String, List<String>)
|
||||
> {
|
||||
const ConvertToCBZFamily._()
|
||||
ConvertToCBZFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'convertToCBZProvider',
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ Future<void> downloadChapter(
|
|||
if (!file.existsSync()) {
|
||||
pages.add(
|
||||
PageUrl(
|
||||
page.url.trim().trimLeft().trimRight(),
|
||||
page.url.trim(),
|
||||
headers: pageHeaders,
|
||||
fileName: p.join(
|
||||
chapterDirectory.path,
|
||||
|
|
@ -325,7 +325,7 @@ Future<void> downloadChapter(
|
|||
if (!file.existsSync()) {
|
||||
pages.add(
|
||||
PageUrl(
|
||||
page.url.trim().trimLeft().trimRight(),
|
||||
page.url.trim(),
|
||||
headers: pageHeaders,
|
||||
fileName: p.join(mangaMainDirectory.path, "$chapterName.mp4"),
|
||||
),
|
||||
|
|
@ -406,6 +406,7 @@ Future<void> processDownloads(Ref ref, {bool? useWifi}) async {
|
|||
final downloadItem = ongoingDownloads[index++];
|
||||
final chapter = downloadItem.chapter.value!;
|
||||
chapter.cancelDownloads(downloadItem.id);
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
ref.read(
|
||||
downloadChapterProvider(
|
||||
chapter: chapter,
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ part of 'download_provider.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(addDownloadToQueue)
|
||||
const addDownloadToQueueProvider = AddDownloadToQueueFamily._();
|
||||
final addDownloadToQueueProvider = AddDownloadToQueueFamily._();
|
||||
|
||||
final class AddDownloadToQueueProvider
|
||||
extends $FunctionalProvider<AsyncValue<void>, void, FutureOr<void>>
|
||||
with $FutureModifier<void>, $FutureProvider<void> {
|
||||
const AddDownloadToQueueProvider._({
|
||||
AddDownloadToQueueProvider._({
|
||||
required AddDownloadToQueueFamily super.from,
|
||||
required Chapter super.argument,
|
||||
}) : super(
|
||||
|
|
@ -63,7 +63,7 @@ String _$addDownloadToQueueHash() =>
|
|||
|
||||
final class AddDownloadToQueueFamily extends $Family
|
||||
with $FunctionalFamilyOverride<FutureOr<void>, Chapter> {
|
||||
const AddDownloadToQueueFamily._()
|
||||
AddDownloadToQueueFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'addDownloadToQueueProvider',
|
||||
|
|
@ -80,12 +80,12 @@ final class AddDownloadToQueueFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(downloadChapter)
|
||||
const downloadChapterProvider = DownloadChapterFamily._();
|
||||
final downloadChapterProvider = DownloadChapterFamily._();
|
||||
|
||||
final class DownloadChapterProvider
|
||||
extends $FunctionalProvider<AsyncValue<void>, void, FutureOr<void>>
|
||||
with $FutureModifier<void>, $FutureProvider<void> {
|
||||
const DownloadChapterProvider._({
|
||||
DownloadChapterProvider._({
|
||||
required DownloadChapterFamily super.from,
|
||||
required ({Chapter chapter, bool? useWifi, VoidCallback? callback})
|
||||
super.argument,
|
||||
|
|
@ -136,7 +136,7 @@ final class DownloadChapterProvider
|
|||
}
|
||||
}
|
||||
|
||||
String _$downloadChapterHash() => r'0eb04602246bb3c4dcc88397d97039dea3047cc6';
|
||||
String _$downloadChapterHash() => r'c503cef46aa7083316b023400f0aa470ae3a3bc4';
|
||||
|
||||
final class DownloadChapterFamily extends $Family
|
||||
with
|
||||
|
|
@ -144,7 +144,7 @@ final class DownloadChapterFamily extends $Family
|
|||
FutureOr<void>,
|
||||
({Chapter chapter, bool? useWifi, VoidCallback? callback})
|
||||
> {
|
||||
const DownloadChapterFamily._()
|
||||
DownloadChapterFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'downloadChapterProvider',
|
||||
|
|
@ -167,12 +167,12 @@ final class DownloadChapterFamily extends $Family
|
|||
}
|
||||
|
||||
@ProviderFor(processDownloads)
|
||||
const processDownloadsProvider = ProcessDownloadsFamily._();
|
||||
final processDownloadsProvider = ProcessDownloadsFamily._();
|
||||
|
||||
final class ProcessDownloadsProvider
|
||||
extends $FunctionalProvider<AsyncValue<void>, void, FutureOr<void>>
|
||||
with $FutureModifier<void>, $FutureProvider<void> {
|
||||
const ProcessDownloadsProvider._({
|
||||
ProcessDownloadsProvider._({
|
||||
required ProcessDownloadsFamily super.from,
|
||||
required bool? super.argument,
|
||||
}) : super(
|
||||
|
|
@ -215,11 +215,11 @@ final class ProcessDownloadsProvider
|
|||
}
|
||||
}
|
||||
|
||||
String _$processDownloadsHash() => r'caebad3bb681d7b38de4d09325310fc08bc1cd0a';
|
||||
String _$processDownloadsHash() => r'36903a1ca0140ef7d55aa68ee34d8c74573e8e71';
|
||||
|
||||
final class ProcessDownloadsFamily extends $Family
|
||||
with $FunctionalFamilyOverride<FutureOr<void>, bool?> {
|
||||
const ProcessDownloadsFamily._()
|
||||
ProcessDownloadsFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'processDownloadsProvider',
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import 'package:mangayomi/modules/manga/home/widget/mangas_card_selector.dart';
|
|||
import 'package:mangayomi/modules/widgets/gridview_widget.dart';
|
||||
import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart';
|
||||
import 'package:mangayomi/utils/global_style.dart';
|
||||
import 'package:mangayomi/utils/item_type_localization.dart';
|
||||
import 'package:marquee/marquee.dart';
|
||||
import 'package:super_sliver_list/super_sliver_list.dart';
|
||||
|
||||
|
|
@ -167,11 +168,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
Text(
|
||||
!isLocal
|
||||
? "${source.name}"
|
||||
: "${context.l10n.local_source} ${source.itemType == ItemType.manga
|
||||
? context.l10n.manga
|
||||
: source.itemType == ItemType.anime
|
||||
? context.l10n.anime
|
||||
: context.l10n.novel}",
|
||||
: "${context.l10n.local_source} ${source.itemType.localized(context.l10n)}",
|
||||
),
|
||||
source.notes != null && source.notes!.isNotEmpty
|
||||
? SizedBox(
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ part of 'state_provider.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(MangaHomeDisplayTypeState)
|
||||
const mangaHomeDisplayTypeStateProvider = MangaHomeDisplayTypeStateProvider._();
|
||||
final mangaHomeDisplayTypeStateProvider = MangaHomeDisplayTypeStateProvider._();
|
||||
|
||||
final class MangaHomeDisplayTypeStateProvider
|
||||
extends $NotifierProvider<MangaHomeDisplayTypeState, DisplayType> {
|
||||
const MangaHomeDisplayTypeStateProvider._()
|
||||
MangaHomeDisplayTypeStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -49,7 +49,6 @@ abstract class _$MangaHomeDisplayTypeState extends $Notifier<DisplayType> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<DisplayType, DisplayType>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -59,6 +58,6 @@ abstract class _$MangaHomeDisplayTypeState extends $Notifier<DisplayType> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,309 +0,0 @@
|
|||
import 'package:extended_image/extended_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/image_view_paged.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/circular_progress_indicator_animate_rotate.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/transition_view_paged.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/reader_screen.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:photo_view/photo_view_gallery.dart';
|
||||
|
||||
class DoubleColummView extends StatefulWidget {
|
||||
final List<UChapDataPreload?> datas;
|
||||
final Function(UChapDataPreload datas) onLongPressData;
|
||||
final BackgroundColor backgroundColor;
|
||||
final Function(bool) isFailedToLoadImage;
|
||||
const DoubleColummView({
|
||||
super.key,
|
||||
required this.datas,
|
||||
required this.onLongPressData,
|
||||
required this.backgroundColor,
|
||||
required this.isFailedToLoadImage,
|
||||
});
|
||||
|
||||
@override
|
||||
State<DoubleColummView> createState() => _DoubleColummViewState();
|
||||
}
|
||||
|
||||
class _DoubleColummViewState extends State<DoubleColummView>
|
||||
with TickerProviderStateMixin {
|
||||
late AnimationController _scaleAnimationController;
|
||||
late Animation<double> _animation;
|
||||
Alignment _scalePosition = Alignment.center;
|
||||
final PhotoViewController _photoViewController = PhotoViewController();
|
||||
final PhotoViewScaleStateController _photoViewScaleStateController =
|
||||
PhotoViewScaleStateController();
|
||||
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);
|
||||
}
|
||||
|
||||
void _onScaleEnd(
|
||||
BuildContext context,
|
||||
ScaleEndDetails details,
|
||||
PhotoViewControllerValue controllerValue,
|
||||
) {
|
||||
if (controllerValue.scale! < 1) {
|
||||
_photoViewScaleStateController.reset();
|
||||
}
|
||||
}
|
||||
|
||||
double get pixelRatio => View.of(context).devicePixelRatio;
|
||||
Size get size => View.of(context).physicalSize / pixelRatio;
|
||||
Alignment _computeAlignmentByTapOffset(Offset offset) {
|
||||
return Alignment(
|
||||
(offset.dx - size.width / 2) / (size.width / 2),
|
||||
(offset.dy - size.height / 2) / (size.height / 2),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_scaleAnimationController = AnimationController(
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scaleAnimationController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _toggleScale(Offset tapPosition) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
if (_scaleAnimationController.isAnimating) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_photoViewController.scale == 1.0) {
|
||||
_scalePosition = _computeAlignmentByTapOffset(tapPosition);
|
||||
|
||||
if (_scaleAnimationController.isCompleted) {
|
||||
_scaleAnimationController.reset();
|
||||
}
|
||||
|
||||
_scaleAnimationController.forward();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_photoViewController.scale == 2.0) {
|
||||
_scaleAnimationController.reverse();
|
||||
return;
|
||||
}
|
||||
|
||||
_photoViewScaleStateController.reset();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.datas[0]?.isTransitionPage ?? false) {
|
||||
return TransitionViewPaged(data: widget.datas[0]!);
|
||||
}
|
||||
if (widget.datas.length > 1 &&
|
||||
(widget.datas[1]?.isTransitionPage ?? false)) {
|
||||
return TransitionViewPaged(data: widget.datas[1]!);
|
||||
}
|
||||
|
||||
return PhotoViewGallery.builder(
|
||||
backgroundDecoration: const BoxDecoration(color: Colors.transparent),
|
||||
itemCount: 1,
|
||||
builder: (context, _) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return PhotoViewGalleryPageOptions.customChild(
|
||||
controller: _photoViewController,
|
||||
scaleStateController: _photoViewScaleStateController,
|
||||
basePosition: _scalePosition,
|
||||
onScaleEnd: _onScaleEnd,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onDoubleTapDown: (TapDownDetails details) {
|
||||
_toggleScale(details.globalPosition);
|
||||
},
|
||||
onDoubleTap: () {},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (widget.datas[0] != null)
|
||||
Flexible(
|
||||
child: ImageViewPaged(
|
||||
data: widget.datas[0]!,
|
||||
loadStateChanged: (state) {
|
||||
if (state.extendedImageLoadState == LoadState.loading) {
|
||||
final ImageChunkEvent? loadingProgress =
|
||||
state.loadingProgress;
|
||||
final double progress =
|
||||
loadingProgress?.expectedTotalBytes != null
|
||||
? loadingProgress!.cumulativeBytesLoaded /
|
||||
loadingProgress.expectedTotalBytes!
|
||||
: 0;
|
||||
return Container(
|
||||
color: getBackgroundColor(widget.backgroundColor),
|
||||
height: context.height(0.8),
|
||||
child: CircularProgressIndicatorAnimateRotate(
|
||||
progress: progress,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (state.extendedImageLoadState ==
|
||||
LoadState.completed) {
|
||||
widget.isFailedToLoadImage(false);
|
||||
return Image(image: state.imageProvider);
|
||||
}
|
||||
if (state.extendedImageLoadState == LoadState.failed) {
|
||||
widget.isFailedToLoadImage(true);
|
||||
return Container(
|
||||
color: getBackgroundColor(widget.backgroundColor),
|
||||
height: context.height(0.8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
l10n.image_loading_error,
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: 0.7),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: GestureDetector(
|
||||
onLongPress: () {
|
||||
state.reLoadImage();
|
||||
widget.isFailedToLoadImage(false);
|
||||
},
|
||||
onTap: () {
|
||||
state.reLoadImage();
|
||||
widget.isFailedToLoadImage(false);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.primaryColor,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 16,
|
||||
),
|
||||
child: Text(l10n.retry),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onLongPressData: (datas) =>
|
||||
widget.onLongPressData.call(datas),
|
||||
),
|
||||
),
|
||||
// if (widget.datas[1] != null) const SizedBox(width: 10),
|
||||
if (widget.datas[1] != null)
|
||||
Flexible(
|
||||
child: ImageViewPaged(
|
||||
data: widget.datas[1]!,
|
||||
loadStateChanged: (state) {
|
||||
if (state.extendedImageLoadState == LoadState.loading) {
|
||||
final ImageChunkEvent? loadingProgress =
|
||||
state.loadingProgress;
|
||||
final double progress =
|
||||
loadingProgress?.expectedTotalBytes != null
|
||||
? loadingProgress!.cumulativeBytesLoaded /
|
||||
loadingProgress.expectedTotalBytes!
|
||||
: 0;
|
||||
return Container(
|
||||
color: getBackgroundColor(widget.backgroundColor),
|
||||
height: context.height(0.8),
|
||||
child: CircularProgressIndicatorAnimateRotate(
|
||||
progress: progress,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (state.extendedImageLoadState ==
|
||||
LoadState.completed) {
|
||||
widget.isFailedToLoadImage(false);
|
||||
return Image(image: state.imageProvider);
|
||||
}
|
||||
if (state.extendedImageLoadState == LoadState.failed) {
|
||||
widget.isFailedToLoadImage(true);
|
||||
return Container(
|
||||
color: getBackgroundColor(widget.backgroundColor),
|
||||
height: context.height(0.8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
l10n.image_loading_error,
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: 0.7),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: GestureDetector(
|
||||
onLongPress: () {
|
||||
state.reLoadImage();
|
||||
widget.isFailedToLoadImage(false);
|
||||
},
|
||||
onTap: () {
|
||||
state.reLoadImage();
|
||||
widget.isFailedToLoadImage(false);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.primaryColor,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 16,
|
||||
),
|
||||
child: Text(l10n.retry),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onLongPressData: (datas) =>
|
||||
widget.onLongPressData.call(datas),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
import 'package:extended_image/extended_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/image_view_paged.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/circular_progress_indicator_animate_rotate.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/transition_view_vertical.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/reader_screen.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
|
||||
class DoubleColummVerticalView extends StatelessWidget {
|
||||
final List<UChapDataPreload?> datas;
|
||||
final Function(UChapDataPreload datas) onLongPressData;
|
||||
final BackgroundColor backgroundColor;
|
||||
final Function(bool) isFailedToLoadImage;
|
||||
const DoubleColummVerticalView({
|
||||
super.key,
|
||||
required this.datas,
|
||||
required this.onLongPressData,
|
||||
required this.backgroundColor,
|
||||
required this.isFailedToLoadImage,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
|
||||
if (datas[0]?.isTransitionPage ?? false) {
|
||||
return TransitionViewVertical(data: datas[0]!);
|
||||
}
|
||||
if (datas.length > 1 && (datas[1]?.isTransitionPage ?? false)) {
|
||||
return TransitionViewVertical(data: datas[1]!);
|
||||
}
|
||||
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (datas[0]?.index == 0)
|
||||
SizedBox(height: MediaQuery.of(context).padding.top),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (datas[0] != null)
|
||||
Flexible(
|
||||
child: ImageViewPaged(
|
||||
data: datas[0]!,
|
||||
loadStateChanged: (state) {
|
||||
if (state.extendedImageLoadState == LoadState.loading) {
|
||||
final ImageChunkEvent? loadingProgress =
|
||||
state.loadingProgress;
|
||||
final double progress =
|
||||
loadingProgress?.expectedTotalBytes != null
|
||||
? loadingProgress!.cumulativeBytesLoaded /
|
||||
loadingProgress.expectedTotalBytes!
|
||||
: 0;
|
||||
return Container(
|
||||
color: getBackgroundColor(backgroundColor),
|
||||
height: context.height(0.8),
|
||||
child: CircularProgressIndicatorAnimateRotate(
|
||||
progress: progress,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (state.extendedImageLoadState == LoadState.completed) {
|
||||
isFailedToLoadImage(false);
|
||||
return Image(image: state.imageProvider);
|
||||
}
|
||||
if (state.extendedImageLoadState == LoadState.failed) {
|
||||
isFailedToLoadImage(true);
|
||||
return Container(
|
||||
color: getBackgroundColor(backgroundColor),
|
||||
height: context.height(0.8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
l10n.image_loading_error,
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: 0.7),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: GestureDetector(
|
||||
onLongPress: () {
|
||||
state.reLoadImage();
|
||||
isFailedToLoadImage(false);
|
||||
},
|
||||
onTap: () {
|
||||
state.reLoadImage();
|
||||
isFailedToLoadImage(false);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.primaryColor,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 16,
|
||||
),
|
||||
child: Text(l10n.retry),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onLongPressData: (datas) => onLongPressData.call(datas),
|
||||
),
|
||||
),
|
||||
// if (datas[1] != null) const SizedBox(width: 10),
|
||||
if (datas[1] != null)
|
||||
Flexible(
|
||||
child: ImageViewPaged(
|
||||
data: datas[1]!,
|
||||
loadStateChanged: (state) {
|
||||
if (state.extendedImageLoadState == LoadState.loading) {
|
||||
final ImageChunkEvent? loadingProgress =
|
||||
state.loadingProgress;
|
||||
final double progress =
|
||||
loadingProgress?.expectedTotalBytes != null
|
||||
? loadingProgress!.cumulativeBytesLoaded /
|
||||
loadingProgress.expectedTotalBytes!
|
||||
: 0;
|
||||
return Container(
|
||||
color: getBackgroundColor(backgroundColor),
|
||||
height: context.height(0.8),
|
||||
child: CircularProgressIndicatorAnimateRotate(
|
||||
progress: progress,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (state.extendedImageLoadState == LoadState.completed) {
|
||||
isFailedToLoadImage(false);
|
||||
return Image(image: state.imageProvider);
|
||||
}
|
||||
if (state.extendedImageLoadState == LoadState.failed) {
|
||||
isFailedToLoadImage(true);
|
||||
return Container(
|
||||
color: getBackgroundColor(backgroundColor),
|
||||
height: context.height(0.8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
l10n.image_loading_error,
|
||||
style: TextStyle(
|
||||
color: Colors.white.withValues(alpha: 0.7),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: GestureDetector(
|
||||
onLongPress: () {
|
||||
state.reLoadImage();
|
||||
isFailedToLoadImage(false);
|
||||
},
|
||||
onTap: () {
|
||||
state.reLoadImage();
|
||||
isFailedToLoadImage(false);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.primaryColor,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 16,
|
||||
),
|
||||
child: Text(l10n.retry),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onLongPressData: (datas) => onLongPressData.call(datas),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/double_columm_view_vertical.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/double_page_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/image_view_vertical.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/transition_view_vertical.dart';
|
||||
|
|
@ -134,10 +134,10 @@ class ImageViewWebtoon extends StatelessWidget {
|
|||
behavior: HitTestBehavior.translucent,
|
||||
onDoubleTapDown: (details) => onDoubleTapDown(details.globalPosition),
|
||||
onDoubleTap: onDoubleTap,
|
||||
child: DoubleColummVerticalView(
|
||||
datas: datas,
|
||||
child: DoublePageView.vertical(
|
||||
pages: datas,
|
||||
backgroundColor: backgroundColor,
|
||||
isFailedToLoadImage: onFailedToLoadImage,
|
||||
onFailedToLoadImage: onFailedToLoadImage,
|
||||
onLongPressData: onLongPressData,
|
||||
),
|
||||
);
|
||||
|
|
|
|||
230
lib/modules/manga/reader/managers/chapter_preload_manager.dart
Normal file
230
lib/modules/manga/reader/managers/chapter_preload_manager.dart
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/services/get_chapter_pages.dart';
|
||||
|
||||
/// Manages the preloading and memory of chapters in the manga reader.
|
||||
class ChapterPreloadManager {
|
||||
/// The list of preloaded chapter data
|
||||
final List<UChapDataPreload> _pages = [];
|
||||
|
||||
/// Set of chapter IDs currently in memory
|
||||
final Set<String> _loadedChapterIds = {};
|
||||
|
||||
/// Queue of chapter IDs in order of loading (for LRU eviction)
|
||||
final Queue<String> _chapterLoadOrder = Queue();
|
||||
|
||||
/// Current reading index
|
||||
int _currentIndex = 0;
|
||||
|
||||
/// Flag to prevent concurrent preloading
|
||||
bool _isPreloading = false;
|
||||
|
||||
/// Callbacks
|
||||
void Function()? onPagesUpdated;
|
||||
|
||||
/// Gets the list of pages (read-only)
|
||||
List<UChapDataPreload> get pages => List.unmodifiable(_pages);
|
||||
|
||||
/// Gets the current number of pages
|
||||
int get pageCount => _pages.length;
|
||||
|
||||
/// Gets the current index
|
||||
int get currentIndex => _currentIndex;
|
||||
|
||||
/// Gets the loaded chapter count
|
||||
int get loadedChapterCount => _loadedChapterIds.length;
|
||||
|
||||
/// Sets the current reading index
|
||||
set currentIndex(int value) {
|
||||
if (value >= 0 && value < _pages.length) {
|
||||
_currentIndex = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// Initializes the manager with the first chapter's pages.
|
||||
void initialize(List<UChapDataPreload> initialPages, int startIndex) {
|
||||
_pages.clear();
|
||||
_loadedChapterIds.clear();
|
||||
_chapterLoadOrder.clear();
|
||||
|
||||
_pages.addAll(initialPages);
|
||||
_currentIndex = startIndex;
|
||||
|
||||
// Track the initial chapter
|
||||
if (initialPages.isNotEmpty) {
|
||||
final chapterId = _getChapterIdentifier(initialPages.first.chapter);
|
||||
if (chapterId != null) {
|
||||
_loadedChapterIds.add(chapterId);
|
||||
_chapterLoadOrder.add(chapterId);
|
||||
}
|
||||
}
|
||||
|
||||
if (kDebugMode) {
|
||||
debugPrint(
|
||||
'[ChapterPreload] Initialized with ${initialPages.length} pages',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a transition page between chapters.
|
||||
UChapDataPreload createTransitionPage({
|
||||
required Chapter currentChapter,
|
||||
required Chapter? nextChapter,
|
||||
required String mangaName,
|
||||
bool isLastChapter = false,
|
||||
}) {
|
||||
return UChapDataPreload.transition(
|
||||
currentChapter: currentChapter,
|
||||
nextChapter: nextChapter,
|
||||
mangaName: mangaName,
|
||||
pageIndex: _pages.length,
|
||||
isLastChapter: isLastChapter,
|
||||
);
|
||||
}
|
||||
|
||||
/// Preloads the next chapter's pages.
|
||||
///
|
||||
/// Returns true if preloading was successful, false otherwise.
|
||||
Future<bool> preloadNextChapter(
|
||||
GetChapterPagesModel chapterData,
|
||||
Chapter currentChapter,
|
||||
) async {
|
||||
if (_isPreloading) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('[ChapterPreload] Already preloading, skipping');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
_isPreloading = true;
|
||||
|
||||
try {
|
||||
if (chapterData.uChapDataPreload.isEmpty) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('[ChapterPreload] No pages in chapter data');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final firstPage = chapterData.uChapDataPreload.first;
|
||||
if (firstPage.chapter == null) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('[ChapterPreload] No chapter in first page');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final chapterId = _getChapterIdentifier(firstPage.chapter);
|
||||
if (chapterId != null && _loadedChapterIds.contains(chapterId)) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('[ChapterPreload] Chapter already loaded: $chapterId');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create transition page
|
||||
final transitionPage = createTransitionPage(
|
||||
currentChapter: currentChapter,
|
||||
nextChapter: firstPage.chapter,
|
||||
mangaName: currentChapter.manga.value?.name ?? '',
|
||||
);
|
||||
|
||||
// Update page indices for new pages
|
||||
final startIndex = _pages.length + 1;
|
||||
final newPages = chapterData.uChapDataPreload.asMap().entries.map((
|
||||
entry,
|
||||
) {
|
||||
return entry.value..pageIndex = startIndex + entry.key;
|
||||
}).toList();
|
||||
|
||||
// Add to pages list
|
||||
_pages.add(transitionPage);
|
||||
_pages.addAll(newPages);
|
||||
|
||||
// Track the new chapter
|
||||
if (chapterId != null) {
|
||||
_loadedChapterIds.add(chapterId);
|
||||
_chapterLoadOrder.add(chapterId);
|
||||
}
|
||||
|
||||
// Notify listeners
|
||||
onPagesUpdated?.call();
|
||||
|
||||
if (kDebugMode) {
|
||||
debugPrint(
|
||||
'[ChapterPreload] Added ${newPages.length} pages from next chapter',
|
||||
);
|
||||
debugPrint(
|
||||
'[ChapterPreload] Total pages: ${_pages.length}, Chapters: ${_loadedChapterIds.length}',
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
} finally {
|
||||
_isPreloading = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a "last chapter" transition page.
|
||||
bool addLastChapterTransition(Chapter chapter) {
|
||||
// Check if already added
|
||||
if (_pages.isNotEmpty && (_pages.last.isLastChapter ?? false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final transitionPage = createTransitionPage(
|
||||
currentChapter: chapter,
|
||||
nextChapter: null,
|
||||
mangaName: chapter.manga.value?.name ?? '',
|
||||
isLastChapter: true,
|
||||
);
|
||||
|
||||
_pages.add(transitionPage);
|
||||
onPagesUpdated?.call();
|
||||
|
||||
if (kDebugMode) {
|
||||
debugPrint('[ChapterPreload] Added last chapter transition');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Updates the cropImage for a page at the given index.
|
||||
void updatePageCropImage(int index, Uint8List? cropImage) {
|
||||
if (index >= 0 && index < _pages.length) {
|
||||
_pages[index].cropImage = cropImage;
|
||||
onPagesUpdated?.call();
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a unique identifier for a chapter.
|
||||
String? _getChapterIdentifier(Chapter? chapter) {
|
||||
if (chapter == null) return null;
|
||||
|
||||
final url = chapter.url?.trim() ?? '';
|
||||
final archivePath = chapter.archivePath?.trim() ?? '';
|
||||
|
||||
if (url.isNotEmpty) return 'url:$url';
|
||||
if (archivePath.isNotEmpty) return 'archive:$archivePath';
|
||||
|
||||
return 'id:${chapter.id}';
|
||||
}
|
||||
|
||||
/// Disposes of all resources.
|
||||
Future<void> dispose() async {
|
||||
// Clear pages
|
||||
_pages.clear();
|
||||
_loadedChapterIds.clear();
|
||||
_chapterLoadOrder.clear();
|
||||
|
||||
// Clear callbacks
|
||||
onPagesUpdated = null;
|
||||
|
||||
if (kDebugMode) {
|
||||
debugPrint('[ChapterPreload] Disposed');
|
||||
}
|
||||
}
|
||||
}
|
||||
212
lib/modules/manga/reader/mixins/reader_gestures.dart
Normal file
212
lib/modules/manga/reader/mixins/reader_gestures.dart
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
/// Widget providing horizontal tap zones for reader navigation.
|
||||
class HorizontalTapZones extends StatelessWidget {
|
||||
/// Callback for left region tap.
|
||||
final VoidCallback onLeftTap;
|
||||
|
||||
/// Callback for center region tap.
|
||||
final VoidCallback onCenterTap;
|
||||
|
||||
/// Callback for right region tap.
|
||||
final VoidCallback onRightTap;
|
||||
|
||||
/// Callback for double-tap with position.
|
||||
final void Function(Offset position)? onDoubleTap;
|
||||
|
||||
/// Whether to show overlay for failed images.
|
||||
final bool showFailedOverlay;
|
||||
|
||||
/// Widget to show when image failed to load.
|
||||
final Widget? failedWidget;
|
||||
|
||||
const HorizontalTapZones({
|
||||
super.key,
|
||||
required this.onLeftTap,
|
||||
required this.onCenterTap,
|
||||
required this.onRightTap,
|
||||
this.onDoubleTap,
|
||||
this.showFailedOverlay = false,
|
||||
this.failedWidget,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
// Left region (2 flex)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _TapZone(onTap: onLeftTap, onDoubleTap: onDoubleTap),
|
||||
),
|
||||
// Center region (2 flex)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: showFailedOverlay && failedWidget != null
|
||||
? failedWidget!
|
||||
: _TapZone(onTap: onCenterTap, onDoubleTap: onDoubleTap),
|
||||
),
|
||||
// Right region (2 flex)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _TapZone(onTap: onRightTap, onDoubleTap: onDoubleTap),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Widget providing vertical tap zones for reader navigation.
|
||||
class VerticalTapZones extends StatelessWidget {
|
||||
/// Callback for top region tap.
|
||||
final VoidCallback onTopTap;
|
||||
|
||||
/// Callback for center region tap.
|
||||
final VoidCallback onCenterTap;
|
||||
|
||||
/// Callback for bottom region tap.
|
||||
final VoidCallback onBottomTap;
|
||||
|
||||
/// Callback for double-tap with position.
|
||||
final void Function(Offset position)? onDoubleTap;
|
||||
|
||||
const VerticalTapZones({
|
||||
super.key,
|
||||
required this.onTopTap,
|
||||
required this.onCenterTap,
|
||||
required this.onBottomTap,
|
||||
this.onDoubleTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// Top region (2 flex)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _TapZone(onTap: onTopTap, onDoubleTap: onDoubleTap),
|
||||
),
|
||||
// Center region (5 flex) - larger for viewing
|
||||
const Expanded(flex: 5, child: SizedBox.shrink()),
|
||||
// Bottom region (2 flex)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _TapZone(onTap: onBottomTap, onDoubleTap: onDoubleTap),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TapZone extends StatelessWidget {
|
||||
final VoidCallback onTap;
|
||||
final void Function(Offset position)? onDoubleTap;
|
||||
|
||||
const _TapZone({required this.onTap, this.onDoubleTap});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: onTap,
|
||||
onDoubleTapDown: onDoubleTap != null
|
||||
? (details) => onDoubleTap!(details.globalPosition)
|
||||
: null,
|
||||
onDoubleTap: onDoubleTap != null ? () {} : null,
|
||||
onSecondaryTapDown: onDoubleTap != null
|
||||
? (details) => onDoubleTap!(details.globalPosition)
|
||||
: null,
|
||||
onSecondaryTap: onDoubleTap != null ? () {} : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for keyboard shortcuts in the reader.
|
||||
class ReaderKeyboardHandler {
|
||||
final VoidCallback? onEscape;
|
||||
final VoidCallback? onFullScreen;
|
||||
final VoidCallback? onPreviousPage;
|
||||
final VoidCallback? onNextPage;
|
||||
final VoidCallback? onNextChapter;
|
||||
final VoidCallback? onPreviousChapter;
|
||||
|
||||
const ReaderKeyboardHandler({
|
||||
this.onEscape,
|
||||
this.onFullScreen,
|
||||
this.onPreviousPage,
|
||||
this.onNextPage,
|
||||
this.onNextChapter,
|
||||
this.onPreviousChapter,
|
||||
});
|
||||
|
||||
/// Handles a key event and returns true if it was handled.
|
||||
bool handleKeyEvent(KeyEvent event, {bool isReverseHorizontal = false}) {
|
||||
if (event is! KeyDownEvent) return false;
|
||||
switch (event.logicalKey) {
|
||||
case LogicalKeyboardKey.f11:
|
||||
onFullScreen?.call();
|
||||
return true;
|
||||
|
||||
case LogicalKeyboardKey.escape:
|
||||
case LogicalKeyboardKey.backspace:
|
||||
onEscape?.call();
|
||||
return true;
|
||||
|
||||
case LogicalKeyboardKey.arrowUp:
|
||||
onPreviousPage?.call();
|
||||
return true;
|
||||
|
||||
case LogicalKeyboardKey.arrowDown:
|
||||
onNextPage?.call();
|
||||
return true;
|
||||
|
||||
case LogicalKeyboardKey.arrowLeft:
|
||||
if (isReverseHorizontal) {
|
||||
onNextPage?.call();
|
||||
} else {
|
||||
onPreviousPage?.call();
|
||||
}
|
||||
return true;
|
||||
|
||||
case LogicalKeyboardKey.arrowRight:
|
||||
if (isReverseHorizontal) {
|
||||
onPreviousPage?.call();
|
||||
} else {
|
||||
onNextPage?.call();
|
||||
}
|
||||
return true;
|
||||
|
||||
case LogicalKeyboardKey.keyN:
|
||||
case LogicalKeyboardKey.pageDown:
|
||||
case LogicalKeyboardKey.shiftRight:
|
||||
onNextChapter?.call();
|
||||
return true;
|
||||
|
||||
case LogicalKeyboardKey.keyP:
|
||||
case LogicalKeyboardKey.pageUp:
|
||||
case LogicalKeyboardKey.shiftLeft:
|
||||
onPreviousChapter?.call();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a KeyboardListener widget with this handler.
|
||||
Widget wrapWithKeyboardListener({
|
||||
required Widget child,
|
||||
bool isReverseHorizontal = false,
|
||||
FocusNode? focusNode,
|
||||
}) {
|
||||
return KeyboardListener(
|
||||
autofocus: true,
|
||||
focusNode: focusNode ?? FocusNode(),
|
||||
onKeyEvent: (event) =>
|
||||
handleKeyEvent(event, isReverseHorizontal: isReverseHorizontal),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
105
lib/modules/manga/reader/mixins/reader_memory_management.dart
Normal file
105
lib/modules/manga/reader/mixins/reader_memory_management.dart
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/managers/chapter_preload_manager.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/services/get_chapter_pages.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
||||
mixin ReaderMemoryManagement {
|
||||
/// The preload manager that handles memory-bounded chapter caching.
|
||||
late final ChapterPreloadManager _preloadManager = ChapterPreloadManager();
|
||||
|
||||
/// Whether the preload manager has been initialized.
|
||||
bool _isPreloadManagerInitialized = false;
|
||||
|
||||
/// Gets the preload manager.
|
||||
ChapterPreloadManager get preloadManager => _preloadManager;
|
||||
|
||||
/// Gets all currently loaded pages.
|
||||
List<UChapDataPreload> get pages => _preloadManager.pages;
|
||||
|
||||
/// Gets the total page count.
|
||||
int get pageCount => _preloadManager.pageCount;
|
||||
|
||||
/// Gets the current page index.
|
||||
int get currentPageIndex => _preloadManager.currentIndex;
|
||||
|
||||
/// Sets the current page index.
|
||||
set currentPageIndex(int value) {
|
||||
_preloadManager.currentIndex = value;
|
||||
}
|
||||
|
||||
/// Initializes the preload manager with initial chapter data.
|
||||
///
|
||||
/// [chapterData] - The initial chapter pages to load.
|
||||
/// [startIndex] - The initial page index (default: 0).
|
||||
/// [onPagesUpdated] - Callback when pages are added/removed.
|
||||
/// [onIndexAdjusted] - Callback when current index needs adjustment.
|
||||
void initializePreloadManager(
|
||||
GetChapterPagesModel chapterData, {
|
||||
int startIndex = 0,
|
||||
VoidCallback? onPagesUpdated,
|
||||
}) {
|
||||
if (_isPreloadManagerInitialized) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('[ReaderMemoryManagement] Already initialized, skipping');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_preloadManager.onPagesUpdated = onPagesUpdated;
|
||||
|
||||
_preloadManager.initialize(chapterData.uChapDataPreload, startIndex);
|
||||
|
||||
_isPreloadManagerInitialized = true;
|
||||
|
||||
if (kDebugMode) {
|
||||
debugPrint(
|
||||
'[ReaderMemoryManagement] Initialized with ${chapterData.uChapDataPreload.length} pages',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Preloads the next chapter with automatic memory management.
|
||||
///
|
||||
/// Unlike the old implementation, this method will automatically
|
||||
/// evict old chapters when the limit is reached.
|
||||
///
|
||||
/// [chapterData] - The chapter data to preload.
|
||||
/// [currentChapter] - The current chapter (for transition page).
|
||||
///
|
||||
/// Returns a Future that completes with `true` if the chapter was preloaded,
|
||||
/// `false` if it was already loaded or if preloading failed.
|
||||
Future<bool> preloadNextChapter(
|
||||
GetChapterPagesModel chapterData,
|
||||
Chapter currentChapter,
|
||||
) async {
|
||||
return await _preloadManager.preloadNextChapter(
|
||||
chapterData,
|
||||
currentChapter,
|
||||
);
|
||||
}
|
||||
|
||||
/// Adds a "last chapter" transition page.
|
||||
///
|
||||
/// Returns `true` if added successfully, `false` if already added.
|
||||
bool addLastChapterTransition(Chapter chapter) {
|
||||
return _preloadManager.addLastChapterTransition(chapter);
|
||||
}
|
||||
|
||||
/// Updates the cropImage for a page at the given index.
|
||||
void updatePageCropImage(int index, Uint8List? cropImage) {
|
||||
_preloadManager.updatePageCropImage(index, cropImage);
|
||||
}
|
||||
|
||||
/// Disposes the preload manager and clears all cached data.
|
||||
Future<void> disposePreloadManager() async {
|
||||
if (!_isPreloadManagerInitialized) return;
|
||||
|
||||
await _preloadManager.dispose();
|
||||
_isPreloadManagerInitialized = false;
|
||||
|
||||
if (kDebugMode) {
|
||||
debugPrint('[ReaderMemoryManagement] Disposed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,11 +10,11 @@ part of 'color_filter_provider.dart';
|
|||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(CustomColorFilterState)
|
||||
const customColorFilterStateProvider = CustomColorFilterStateProvider._();
|
||||
final customColorFilterStateProvider = CustomColorFilterStateProvider._();
|
||||
|
||||
final class CustomColorFilterStateProvider
|
||||
extends $NotifierProvider<CustomColorFilterState, CustomColorFilter?> {
|
||||
const CustomColorFilterStateProvider._()
|
||||
CustomColorFilterStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -49,7 +49,6 @@ abstract class _$CustomColorFilterState extends $Notifier<CustomColorFilter?> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<CustomColorFilter?, CustomColorFilter?>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -59,17 +58,17 @@ abstract class _$CustomColorFilterState extends $Notifier<CustomColorFilter?> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(EnableCustomColorFilterState)
|
||||
const enableCustomColorFilterStateProvider =
|
||||
final enableCustomColorFilterStateProvider =
|
||||
EnableCustomColorFilterStateProvider._();
|
||||
|
||||
final class EnableCustomColorFilterStateProvider
|
||||
extends $NotifierProvider<EnableCustomColorFilterState, bool> {
|
||||
const EnableCustomColorFilterStateProvider._()
|
||||
EnableCustomColorFilterStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -104,7 +103,6 @@ abstract class _$EnableCustomColorFilterState extends $Notifier<bool> {
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<bool, bool>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -114,16 +112,16 @@ abstract class _$EnableCustomColorFilterState extends $Notifier<bool> {
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
||||
@ProviderFor(ColorFilterBlendModeState)
|
||||
const colorFilterBlendModeStateProvider = ColorFilterBlendModeStateProvider._();
|
||||
final colorFilterBlendModeStateProvider = ColorFilterBlendModeStateProvider._();
|
||||
|
||||
final class ColorFilterBlendModeStateProvider
|
||||
extends $NotifierProvider<ColorFilterBlendModeState, ColorFilterBlendMode> {
|
||||
const ColorFilterBlendModeStateProvider._()
|
||||
ColorFilterBlendModeStateProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
|
|
@ -159,7 +157,6 @@ abstract class _$ColorFilterBlendModeState
|
|||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<ColorFilterBlendMode, ColorFilterBlendMode>;
|
||||
final element =
|
||||
ref.element
|
||||
|
|
@ -169,6 +166,6 @@ abstract class _$ColorFilterBlendModeState
|
|||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
element.handleCreate(ref, build);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import 'package:mangayomi/utils/extensions/others.dart';
|
|||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'crop_borders_provider.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
@Riverpod(keepAlive: false)
|
||||
Future<Uint8List?> cropBorders(
|
||||
Ref ref, {
|
||||
required UChapDataPreload data,
|
||||
|
|
@ -68,8 +68,7 @@ class ImageCropIsolate {
|
|||
|
||||
final receivePort = ReceivePort();
|
||||
mainSendPort.send(receivePort.sendPort);
|
||||
|
||||
await for (var message in receivePort) {
|
||||
receivePort.listen((message) async {
|
||||
if (message is Map<String, dynamic>) {
|
||||
try {
|
||||
final imageBytes = message['imageBytes'] as Uint8List;
|
||||
|
|
@ -84,9 +83,9 @@ class ImageCropIsolate {
|
|||
}
|
||||
} else if (message == 'dispose') {
|
||||
RustLib.dispose();
|
||||
break;
|
||||
receivePort.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<Uint8List?> process(Uint8List imageBytes) async {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue