mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
Compare commits
4 Commits
ce0d10aeb2
...
d308c2ac60
Author | SHA1 | Date | |
---|---|---|---|
d308c2ac60 | |||
ac13807ef4 | |||
38a5b2b8cf | |||
3a7c8d5e38 |
@@ -409,7 +409,9 @@
|
|||||||
"Export logs": "导出日志",
|
"Export logs": "导出日志",
|
||||||
"Clear specific reader settings for all comics": "清除所有漫画的特殊阅读设置",
|
"Clear specific reader settings for all comics": "清除所有漫画的特殊阅读设置",
|
||||||
"Clear specific reader settings for this comic": "清除该漫画的特殊阅读设置",
|
"Clear specific reader settings for this comic": "清除该漫画的特殊阅读设置",
|
||||||
"Enable comic specific settings": "为每本漫画保存特定设置"
|
"Enable comic specific settings": "启用此漫画特定设置",
|
||||||
|
"Ignore Certificate Errors": "忽略证书错误",
|
||||||
|
"Mouse scroll speed": "鼠标滚动速度"
|
||||||
},
|
},
|
||||||
"zh_TW": {
|
"zh_TW": {
|
||||||
"Home": "首頁",
|
"Home": "首頁",
|
||||||
@@ -821,6 +823,8 @@
|
|||||||
"Export logs": "匯出日誌",
|
"Export logs": "匯出日誌",
|
||||||
"Clear specific reader settings for all comics": "清除所有漫畫的特殊閱讀設定",
|
"Clear specific reader settings for all comics": "清除所有漫畫的特殊閱讀設定",
|
||||||
"Clear specific reader settings for this comic": "清除該漫畫的特殊閱讀設定",
|
"Clear specific reader settings for this comic": "清除該漫畫的特殊閱讀設定",
|
||||||
"Enable comic specific settings": "為每本漫畫保存特定設定"
|
"Enable comic specific settings": "啟用此漫畫特定設定",
|
||||||
|
"Ignore Certificate Errors": "忽略證書錯誤",
|
||||||
|
"Mouse scroll speed": "滑鼠滾動速度"
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -152,7 +152,6 @@ class Settings with ChangeNotifier {
|
|||||||
'blockedWords': [],
|
'blockedWords': [],
|
||||||
'defaultSearchTarget': null,
|
'defaultSearchTarget': null,
|
||||||
'autoPageTurningInterval': 5, // in seconds
|
'autoPageTurningInterval': 5, // in seconds
|
||||||
'enableComicSpecificSettings': false,
|
|
||||||
'readerMode': 'galleryLeftToRight', // values of [ReaderMode]
|
'readerMode': 'galleryLeftToRight', // values of [ReaderMode]
|
||||||
'readerScreenPicNumberForLandscape': 1, // 1 - 5
|
'readerScreenPicNumberForLandscape': 1, // 1 - 5
|
||||||
'readerScreenPicNumberForPortrait': 1, // 1 - 5
|
'readerScreenPicNumberForPortrait': 1, // 1 - 5
|
||||||
@@ -191,6 +190,8 @@ class Settings with ChangeNotifier {
|
|||||||
'reverseChapterOrder': false,
|
'reverseChapterOrder': false,
|
||||||
'showSystemStatusBar': false,
|
'showSystemStatusBar': false,
|
||||||
'comicSpecificSettings': <String, Map<String, dynamic>>{},
|
'comicSpecificSettings': <String, Map<String, dynamic>>{},
|
||||||
|
'ignoreBadCertificate': false,
|
||||||
|
'readerScrollSpeed': 1.0, // 0.5 - 3.0
|
||||||
};
|
};
|
||||||
|
|
||||||
operator [](String key) {
|
operator [](String key) {
|
||||||
@@ -204,18 +205,19 @@ class Settings with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool haveComicSpecificSettings(String comicId, String sourceKey, String key) {
|
void setEnabledComicSpecificSettings(String comicId, String sourceKey, bool enabled) {
|
||||||
return _data['comicSpecificSettings']?["$comicId@$sourceKey"]?.containsKey(
|
setReaderSetting(comicId, sourceKey, "enabled", enabled);
|
||||||
key,
|
}
|
||||||
) ??
|
|
||||||
false;
|
bool isComicSpecificSettingsEnabled(String? comicId, String? sourceKey) {
|
||||||
|
if (comicId == null || sourceKey == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _data['comicSpecificSettings']["$comicId@$sourceKey"]?["enabled"] == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic getReaderSetting(String comicId, String sourceKey, String key) {
|
dynamic getReaderSetting(String comicId, String sourceKey, String key) {
|
||||||
if (key == 'enableComicSpecificSettings') {
|
if (!isComicSpecificSettingsEnabled(comicId, sourceKey)) {
|
||||||
return _data['enableComicSpecificSettings'];
|
|
||||||
}
|
|
||||||
if (_data['enableComicSpecificSettings'] == false) {
|
|
||||||
return _data[key];
|
return _data[key];
|
||||||
}
|
}
|
||||||
return _data['comicSpecificSettings']["$comicId@$sourceKey"]?[key] ??
|
return _data['comicSpecificSettings']["$comicId@$sourceKey"]?[key] ??
|
||||||
@@ -228,16 +230,6 @@ class Settings with ChangeNotifier {
|
|||||||
String key,
|
String key,
|
||||||
dynamic value,
|
dynamic value,
|
||||||
) {
|
) {
|
||||||
if (key == 'enableComicSpecificSettings') {
|
|
||||||
_data['enableComicSpecificSettings'] = value;
|
|
||||||
notifyListeners();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_data['enableComicSpecificSettings'] == false) {
|
|
||||||
_data[key] = value;
|
|
||||||
notifyListeners();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(_data['comicSpecificSettings'] as Map<String, dynamic>).putIfAbsent(
|
(_data['comicSpecificSettings'] as Map<String, dynamic>).putIfAbsent(
|
||||||
"$comicId@$sourceKey",
|
"$comicId@$sourceKey",
|
||||||
() => <String, dynamic>{},
|
() => <String, dynamic>{},
|
||||||
@@ -245,16 +237,8 @@ class Settings with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetComicReaderSettings(String comicId, String sourceKey) {
|
void resetComicReaderSettings(String key) {
|
||||||
final allComicSettings = _data['comicSpecificSettings'] as Map;
|
(_data['comicSpecificSettings'] as Map).remove(key);
|
||||||
if (allComicSettings.containsKey("$comicId@$sourceKey")) {
|
|
||||||
allComicSettings.remove("$comicId@$sourceKey");
|
|
||||||
}
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetAllComicReaderSettings() {
|
|
||||||
_data['comicSpecificSettings'] = <String, Map<String, dynamic>>{};
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -173,6 +173,7 @@ class RHttpAdapter implements HttpClientAdapter {
|
|||||||
dnsSettings: rhttp.DnsSettings.static(overrides: _getOverrides()),
|
dnsSettings: rhttp.DnsSettings.static(overrides: _getOverrides()),
|
||||||
tlsSettings: rhttp.TlsSettings(
|
tlsSettings: rhttp.TlsSettings(
|
||||||
sni: appdata.settings['sni'] != false,
|
sni: appdata.settings['sni'] != false,
|
||||||
|
verifyCertificates: appdata.settings['ignoreBadCertificate'] != true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -131,11 +131,11 @@ class _ReaderGestureDetectorState extends AutomaticGlobalState<_ReaderGestureDet
|
|||||||
}
|
}
|
||||||
if (context.reader.mode.key.startsWith('gallery')) {
|
if (context.reader.mode.key.startsWith('gallery')) {
|
||||||
if (forward) {
|
if (forward) {
|
||||||
if (!context.reader.toNextPage(reader.cid, reader.type) && !context.reader.isLastChapterOfGroup) {
|
if (!context.reader.toNextPage() && !context.reader.isLastChapterOfGroup) {
|
||||||
context.reader.toNextChapter();
|
context.reader.toNextChapter();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!context.reader.toPrevPage(reader.cid, reader.type) && !context.reader.isFirstChapterOfGroup) {
|
if (!context.reader.toPrevPage() && !context.reader.isFirstChapterOfGroup) {
|
||||||
context.reader.toPrevChapter();
|
context.reader.toPrevChapter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,12 +209,12 @@ class _ReaderGestureDetectorState extends AutomaticGlobalState<_ReaderGestureDet
|
|||||||
isBottom = true;
|
isBottom = true;
|
||||||
}
|
}
|
||||||
bool isCenter = false;
|
bool isCenter = false;
|
||||||
var prev = () => context.reader.toPrevPage(context.reader.cid, context.reader.type);
|
var prev = () => context.reader.toPrevPage();
|
||||||
var next = () => context.reader.toNextPage(context.reader.cid, context.reader.type);
|
var next = () => context.reader.toNextPage();
|
||||||
if (appdata.settings.getReaderSetting(
|
if (appdata.settings.getReaderSetting(
|
||||||
reader.cid, reader.type.sourceKey, 'reverseTapToTurnPages')) {
|
reader.cid, reader.type.sourceKey, 'reverseTapToTurnPages')) {
|
||||||
prev = () => context.reader.toNextPage(context.reader.cid, context.reader.type);
|
prev = () => context.reader.toNextPage();
|
||||||
next = () => context.reader.toPrevPage(context.reader.cid, context.reader.type);
|
next = () => context.reader.toPrevPage();
|
||||||
}
|
}
|
||||||
switch (context.reader.mode) {
|
switch (context.reader.mode) {
|
||||||
case ReaderMode.galleryLeftToRight:
|
case ReaderMode.galleryLeftToRight:
|
||||||
|
@@ -138,14 +138,14 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
/// [totalPages] is the total number of pages in the current chapter.
|
/// [totalPages] is the total number of pages in the current chapter.
|
||||||
/// More than one images can be displayed on one page.
|
/// More than one images can be displayed on one page.
|
||||||
int get totalPages {
|
int get totalPages {
|
||||||
if (!reader.showSingleImageOnFirstPage(reader.cid, reader.type)) {
|
if (!reader.showSingleImageOnFirstPage()) {
|
||||||
return (reader.images!.length /
|
return (reader.images!.length /
|
||||||
reader.imagesPerPage(reader.cid, reader.type))
|
reader.imagesPerPage())
|
||||||
.ceil();
|
.ceil();
|
||||||
} else {
|
} else {
|
||||||
return 1 +
|
return 1 +
|
||||||
((reader.images!.length - 1) /
|
((reader.images!.length - 1) /
|
||||||
reader.imagesPerPage(reader.cid, reader.type))
|
reader.imagesPerPage())
|
||||||
.ceil();
|
.ceil();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,8 +169,8 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
|
|
||||||
/// Get the range of images for the given page. [page] is 1-based.
|
/// Get the range of images for the given page. [page] is 1-based.
|
||||||
(int start, int end) getPageImagesRange(int page) {
|
(int start, int end) getPageImagesRange(int page) {
|
||||||
var imagesPerPage = reader.imagesPerPage(reader.cid, reader.type);
|
var imagesPerPage = reader.imagesPerPage();
|
||||||
if (reader.showSingleImageOnFirstPage(reader.cid, reader.type)) {
|
if (reader.showSingleImageOnFirstPage()) {
|
||||||
if (page == 1) {
|
if (page == 1) {
|
||||||
return (0, 1);
|
return (0, 1);
|
||||||
} else {
|
} else {
|
||||||
@@ -259,7 +259,7 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
|
|
||||||
photoViewControllers[index] ??= PhotoViewController();
|
photoViewControllers[index] ??= PhotoViewController();
|
||||||
|
|
||||||
if (reader.imagesPerPage(reader.cid, reader.type) == 1 ||
|
if (reader.imagesPerPage() == 1 ||
|
||||||
pageImages.length == 1) {
|
pageImages.length == 1) {
|
||||||
return PhotoViewGalleryPageOptions(
|
return PhotoViewGalleryPageOptions(
|
||||||
filterQuality: FilterQuality.medium,
|
filterQuality: FilterQuality.medium,
|
||||||
@@ -301,11 +301,11 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
onPageChanged: (i) {
|
onPageChanged: (i) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
if (reader.isFirstChapterOfGroup || !reader.toPrevChapter()) {
|
if (reader.isFirstChapterOfGroup || !reader.toPrevChapter()) {
|
||||||
reader.toPage(reader.cid, reader.type, 1);
|
reader.toPage(1);
|
||||||
}
|
}
|
||||||
} else if (i == totalPages + 1) {
|
} else if (i == totalPages + 1) {
|
||||||
if (reader.isLastChapterOfGroup || !reader.toNextChapter()) {
|
if (reader.isLastChapterOfGroup || !reader.toNextChapter()) {
|
||||||
reader.toPage(reader.cid, reader.type, totalPages);
|
reader.toPage(totalPages);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reader.setPage(i);
|
reader.setPage(i);
|
||||||
@@ -485,9 +485,9 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
keyRepeatTimer = null;
|
keyRepeatTimer = null;
|
||||||
}
|
}
|
||||||
if (forward == true) {
|
if (forward == true) {
|
||||||
reader.toPage(reader.cid, reader.type, reader.page + 1);
|
reader.toPage(reader.page + 1);
|
||||||
} else if (forward == false) {
|
} else if (forward == false) {
|
||||||
reader.toPage(reader.cid, reader.type, reader.page - 1);
|
reader.toPage(reader.page - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event is KeyRepeatEvent && keyRepeatTimer == null) {
|
if (event is KeyRepeatEvent && keyRepeatTimer == null) {
|
||||||
@@ -500,9 +500,9 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
timer.cancel();
|
timer.cancel();
|
||||||
return;
|
return;
|
||||||
} else if (forward == true) {
|
} else if (forward == true) {
|
||||||
reader.toPage(reader.cid, reader.type, reader.page + 1);
|
reader.toPage(reader.page + 1);
|
||||||
} else if (forward == false) {
|
} else if (forward == false) {
|
||||||
reader.toPage(reader.cid, reader.type, reader.page - 1);
|
reader.toPage(reader.page - 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -534,7 +534,7 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
@override
|
@override
|
||||||
String? getImageKeyByOffset(Offset offset) {
|
String? getImageKeyByOffset(Offset offset) {
|
||||||
String? imageKey;
|
String? imageKey;
|
||||||
if (reader.imagesPerPage(reader.cid, reader.type) == 1) {
|
if (reader.imagesPerPage() == 1) {
|
||||||
imageKey = reader.images![reader.page - 1];
|
imageKey = reader.images![reader.page - 1];
|
||||||
} else {
|
} else {
|
||||||
for (var imageState in imageStates) {
|
for (var imageState in imageStates) {
|
||||||
@@ -638,27 +638,52 @@ class _ContinuousModeState extends State<_ContinuousMode>
|
|||||||
cacheImages(page);
|
cacheImages(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
double? futurePosition;
|
double? _futurePosition;
|
||||||
|
|
||||||
void smoothTo(double offset) {
|
void smoothTo(double offset) {
|
||||||
futurePosition ??= scrollController.offset;
|
if (HardwareKeyboard.instance.isShiftPressed) {
|
||||||
if (futurePosition! > scrollController.position.maxScrollExtent &&
|
|
||||||
offset > 0) {
|
|
||||||
return;
|
|
||||||
} else if (futurePosition! < scrollController.position.minScrollExtent &&
|
|
||||||
offset < 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
futurePosition = futurePosition! + offset * 1.2;
|
var currentLocation = scrollController.position.pixels;
|
||||||
futurePosition = futurePosition!.clamp(
|
var old = _futurePosition;
|
||||||
|
_futurePosition ??= currentLocation;
|
||||||
|
double k = (_futurePosition! - currentLocation).abs() / 1600 + 1;
|
||||||
|
final customSpeed = appdata.settings.getReaderSetting(
|
||||||
|
context.reader.cid,
|
||||||
|
context.reader.type.sourceKey,
|
||||||
|
"readerScrollSpeed",
|
||||||
|
);
|
||||||
|
if (customSpeed is num) {
|
||||||
|
k *= customSpeed;
|
||||||
|
}
|
||||||
|
_futurePosition = _futurePosition! + offset * k;
|
||||||
|
var beforeOffset = (_futurePosition! - currentLocation).abs();
|
||||||
|
_futurePosition = _futurePosition!.clamp(
|
||||||
scrollController.position.minScrollExtent,
|
scrollController.position.minScrollExtent,
|
||||||
scrollController.position.maxScrollExtent,
|
scrollController.position.maxScrollExtent,
|
||||||
);
|
);
|
||||||
scrollController.animateTo(
|
var afterOffset = (_futurePosition! - currentLocation).abs();
|
||||||
futurePosition!,
|
if (_futurePosition == old) return;
|
||||||
duration: const Duration(milliseconds: 200),
|
var target = _futurePosition!;
|
||||||
|
var duration = const Duration(milliseconds: 160);
|
||||||
|
if (afterOffset < beforeOffset) {
|
||||||
|
duration = duration * (afterOffset / beforeOffset);
|
||||||
|
if (duration < Duration(milliseconds: 10)) {
|
||||||
|
duration = Duration(milliseconds: 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scrollController
|
||||||
|
.animateTo(
|
||||||
|
_futurePosition!,
|
||||||
|
duration: duration,
|
||||||
curve: Curves.linear,
|
curve: Curves.linear,
|
||||||
);
|
)
|
||||||
|
.then((_) {
|
||||||
|
var current = scrollController.position.pixels;
|
||||||
|
if (current == target && current == _futurePosition) {
|
||||||
|
_futurePosition = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void onPointerSignal(PointerSignalEvent event) {
|
void onPointerSignal(PointerSignalEvent event) {
|
||||||
@@ -787,7 +812,7 @@ class _ContinuousModeState extends State<_ContinuousMode>
|
|||||||
disableScroll = true;
|
disableScroll = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
futurePosition = null;
|
_futurePosition = null;
|
||||||
if (_isMouseScrolling) {
|
if (_isMouseScrolling) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isMouseScrolling = false;
|
_isMouseScrolling = false;
|
||||||
@@ -1009,7 +1034,7 @@ class _ContinuousModeState extends State<_ContinuousMode>
|
|||||||
@override
|
@override
|
||||||
void toPage(int page) {
|
void toPage(int page) {
|
||||||
itemScrollController.jumpTo(index: page);
|
itemScrollController.jumpTo(index: page);
|
||||||
futurePosition = null;
|
_futurePosition = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -115,15 +115,17 @@ class _ReaderState extends State<Reader>
|
|||||||
if (images == null) {
|
if (images == null) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!showSingleImageOnFirstPage(cid, type)) {
|
if (!showSingleImageOnFirstPage()) {
|
||||||
return (images!.length / imagesPerPage(cid, type)).ceil();
|
return (images!.length / imagesPerPage()).ceil();
|
||||||
} else {
|
} else {
|
||||||
return 1 + ((images!.length - 1) / imagesPerPage(cid, type)).ceil();
|
return 1 + ((images!.length - 1) / imagesPerPage()).ceil();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
ComicType get type => widget.type;
|
ComicType get type => widget.type;
|
||||||
|
|
||||||
|
@override
|
||||||
String get cid => widget.cid;
|
String get cid => widget.cid;
|
||||||
|
|
||||||
String get eid => widget.chapters?.ids.elementAtOrNull(chapter - 1) ?? '0';
|
String get eid => widget.chapters?.ids.elementAtOrNull(chapter - 1) ?? '0';
|
||||||
@@ -169,7 +171,7 @@ class _ReaderState extends State<Reader>
|
|||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
||||||
}
|
}
|
||||||
if (appdata.settings.getReaderSetting(cid, type.sourceKey, 'enableTurnPageByVolumeKey')) {
|
if (appdata.settings.getReaderSetting(cid, type.sourceKey, 'enableTurnPageByVolumeKey')) {
|
||||||
handleVolumeEvent(cid, type);
|
handleVolumeEvent();
|
||||||
}
|
}
|
||||||
setImageCacheSize();
|
setImageCacheSize();
|
||||||
Future.delayed(const Duration(milliseconds: 200), () {
|
Future.delayed(const Duration(milliseconds: 200), () {
|
||||||
@@ -184,11 +186,11 @@ class _ReaderState extends State<Reader>
|
|||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
if (!_isInitialized) {
|
if (!_isInitialized) {
|
||||||
initImagesPerPage(cid, type, widget.initialPage ?? 1);
|
initImagesPerPage(widget.initialPage ?? 1);
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
} else {
|
} else {
|
||||||
// For orientation changed
|
// For orientation changed
|
||||||
_checkImagesPerPageChange(cid, type);
|
_checkImagesPerPageChange();
|
||||||
}
|
}
|
||||||
initReaderWindow();
|
initReaderWindow();
|
||||||
}
|
}
|
||||||
@@ -230,7 +232,7 @@ class _ReaderState extends State<Reader>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
_checkImagesPerPageChange(cid, type);
|
_checkImagesPerPageChange();
|
||||||
return KeyboardListener(
|
return KeyboardListener(
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@@ -275,13 +277,13 @@ class _ReaderState extends State<Reader>
|
|||||||
history!.page = images?.length ?? 1;
|
history!.page = images?.length ?? 1;
|
||||||
} else {
|
} else {
|
||||||
/// Record the first image of the page
|
/// Record the first image of the page
|
||||||
if (!showSingleImageOnFirstPage(cid, type) || imagesPerPage(cid, type) == 1) {
|
if (!showSingleImageOnFirstPage() || imagesPerPage() == 1) {
|
||||||
history!.page = (page - 1) * imagesPerPage(cid, type) + 1;
|
history!.page = (page - 1) * imagesPerPage() + 1;
|
||||||
} else {
|
} else {
|
||||||
if (page == 1) {
|
if (page == 1) {
|
||||||
history!.page = 1;
|
history!.page = 1;
|
||||||
} else {
|
} else {
|
||||||
history!.page = (page - 2) * imagesPerPage(cid, type) + 2;
|
history!.page = (page - 2) * imagesPerPage() + 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,23 +366,27 @@ abstract mixin class _ImagePerPageHandler {
|
|||||||
|
|
||||||
ReaderMode get mode;
|
ReaderMode get mode;
|
||||||
|
|
||||||
void initImagesPerPage(String cid, ComicType type, int initialPage) {
|
String get cid;
|
||||||
_lastImagesPerPage = imagesPerPage(cid, type);
|
|
||||||
|
ComicType get type;
|
||||||
|
|
||||||
|
void initImagesPerPage(int initialPage) {
|
||||||
|
_lastImagesPerPage = imagesPerPage();
|
||||||
_lastOrientation = isPortrait;
|
_lastOrientation = isPortrait;
|
||||||
if (imagesPerPage(cid, type) != 1) {
|
if (imagesPerPage() != 1) {
|
||||||
if (showSingleImageOnFirstPage(cid, type)) {
|
if (showSingleImageOnFirstPage()) {
|
||||||
page = ((initialPage - 1) / imagesPerPage(cid, type)).ceil() + 1;
|
page = ((initialPage - 1) / imagesPerPage()).ceil() + 1;
|
||||||
} else {
|
} else {
|
||||||
page = (initialPage / imagesPerPage(cid, type)).ceil();
|
page = (initialPage / imagesPerPage()).ceil();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool showSingleImageOnFirstPage(String cid, ComicType type) =>
|
bool showSingleImageOnFirstPage() =>
|
||||||
appdata.settings.getReaderSetting(cid, type.sourceKey, 'showSingleImageOnFirstPage');
|
appdata.settings.getReaderSetting(cid, type.sourceKey, 'showSingleImageOnFirstPage');
|
||||||
|
|
||||||
/// The number of images displayed on one screen
|
/// The number of images displayed on one screen
|
||||||
int imagesPerPage(String cid, ComicType type) {
|
int imagesPerPage() {
|
||||||
if (mode.isContinuous) return 1;
|
if (mode.isContinuous) return 1;
|
||||||
if (isPortrait) {
|
if (isPortrait) {
|
||||||
return appdata.settings.getReaderSetting(cid, type.sourceKey, 'readerScreenPicNumberForPortrait') ?? 1;
|
return appdata.settings.getReaderSetting(cid, type.sourceKey, 'readerScreenPicNumberForPortrait') ?? 1;
|
||||||
@@ -390,23 +396,21 @@ abstract mixin class _ImagePerPageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the number of images per page has changed
|
/// Check if the number of images per page has changed
|
||||||
void _checkImagesPerPageChange(String cid, ComicType type) {
|
void _checkImagesPerPageChange() {
|
||||||
int currentImagesPerPage = imagesPerPage(cid, type);
|
int currentImagesPerPage = imagesPerPage();
|
||||||
bool currentOrientation = isPortrait;
|
bool currentOrientation = isPortrait;
|
||||||
|
|
||||||
if (_lastImagesPerPage != currentImagesPerPage || _lastOrientation != currentOrientation) {
|
if (_lastImagesPerPage != currentImagesPerPage || _lastOrientation != currentOrientation) {
|
||||||
_adjustPageForImagesPerPageChange(
|
_adjustPageForImagesPerPageChange(_lastImagesPerPage, currentImagesPerPage);
|
||||||
cid, type, _lastImagesPerPage, currentImagesPerPage);
|
|
||||||
_lastImagesPerPage = currentImagesPerPage;
|
_lastImagesPerPage = currentImagesPerPage;
|
||||||
_lastOrientation = currentOrientation;
|
_lastOrientation = currentOrientation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adjust the page number when the number of images per page changes
|
/// Adjust the page number when the number of images per page changes
|
||||||
void _adjustPageForImagesPerPageChange(
|
void _adjustPageForImagesPerPageChange(int oldImagesPerPage, int newImagesPerPage) {
|
||||||
String cid, ComicType type, int oldImagesPerPage, int newImagesPerPage) {
|
|
||||||
int previousImageIndex = 1;
|
int previousImageIndex = 1;
|
||||||
if (!showSingleImageOnFirstPage(cid, type) || oldImagesPerPage == 1) {
|
if (!showSingleImageOnFirstPage() || oldImagesPerPage == 1) {
|
||||||
previousImageIndex = (page - 1) * oldImagesPerPage + 1;
|
previousImageIndex = (page - 1) * oldImagesPerPage + 1;
|
||||||
} else {
|
} else {
|
||||||
if (page == 1) {
|
if (page == 1) {
|
||||||
@@ -418,7 +422,7 @@ abstract mixin class _ImagePerPageHandler {
|
|||||||
|
|
||||||
int newPage;
|
int newPage;
|
||||||
if (newImagesPerPage != 1) {
|
if (newImagesPerPage != 1) {
|
||||||
if (showSingleImageOnFirstPage(cid, type)) {
|
if (showSingleImageOnFirstPage()) {
|
||||||
newPage = ((previousImageIndex - 1) / newImagesPerPage).ceil() + 1;
|
newPage = ((previousImageIndex - 1) / newImagesPerPage).ceil() + 1;
|
||||||
} else {
|
} else {
|
||||||
newPage = (previousImageIndex / newImagesPerPage).ceil();
|
newPage = (previousImageIndex / newImagesPerPage).ceil();
|
||||||
@@ -432,9 +436,9 @@ abstract mixin class _ImagePerPageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract mixin class _VolumeListener {
|
abstract mixin class _VolumeListener {
|
||||||
bool toNextPage(String cid, ComicType type);
|
bool toNextPage();
|
||||||
|
|
||||||
bool toPrevPage(String cid, ComicType type);
|
bool toPrevPage();
|
||||||
|
|
||||||
bool toNextChapter();
|
bool toNextChapter();
|
||||||
|
|
||||||
@@ -442,19 +446,19 @@ abstract mixin class _VolumeListener {
|
|||||||
|
|
||||||
VolumeListener? volumeListener;
|
VolumeListener? volumeListener;
|
||||||
|
|
||||||
void onDown(String cid, ComicType type) {
|
void onDown() {
|
||||||
if (!toNextPage(cid, type)) {
|
if (!toNextPage()) {
|
||||||
toNextChapter();
|
toNextChapter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onUp(String cid, ComicType type) {
|
void onUp() {
|
||||||
if (!toPrevPage(cid, type)) {
|
if (!toPrevPage()) {
|
||||||
toPrevChapter();
|
toPrevChapter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleVolumeEvent(String cid, ComicType type) {
|
void handleVolumeEvent() {
|
||||||
if (!App.isAndroid) {
|
if (!App.isAndroid) {
|
||||||
// Currently only support Android
|
// Currently only support Android
|
||||||
return;
|
return;
|
||||||
@@ -463,8 +467,8 @@ abstract mixin class _VolumeListener {
|
|||||||
volumeListener?.cancel();
|
volumeListener?.cancel();
|
||||||
}
|
}
|
||||||
volumeListener = VolumeListener(
|
volumeListener = VolumeListener(
|
||||||
onDown: () => onDown(cid, type),
|
onDown: onDown,
|
||||||
onUp: () => onUp(cid, type),
|
onUp: onUp,
|
||||||
)..listen();
|
)..listen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,6 +498,10 @@ abstract mixin class _ReaderLocation {
|
|||||||
|
|
||||||
bool get isLoading;
|
bool get isLoading;
|
||||||
|
|
||||||
|
String get cid;
|
||||||
|
|
||||||
|
ComicType get type;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
bool enablePageAnimation(String cid, ComicType type) => appdata.settings.getReaderSetting(cid, type.sourceKey, 'enablePageAnimation');
|
bool enablePageAnimation(String cid, ComicType type) => appdata.settings.getReaderSetting(cid, type.sourceKey, 'enablePageAnimation');
|
||||||
@@ -515,18 +523,18 @@ abstract mixin class _ReaderLocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the page is changed
|
/// Returns true if the page is changed
|
||||||
bool toNextPage(String cid, ComicType type) {
|
bool toNextPage() {
|
||||||
return toPage(cid, type, page + 1);
|
return toPage(page + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the page is changed
|
/// Returns true if the page is changed
|
||||||
bool toPrevPage(String cid, ComicType type) {
|
bool toPrevPage() {
|
||||||
return toPage(cid, type, page - 1);
|
return toPage(page - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _animationCount = 0;
|
int _animationCount = 0;
|
||||||
|
|
||||||
bool toPage(String cid, ComicType type, int page) {
|
bool toPage(int page) {
|
||||||
if (_validatePage(page)) {
|
if (_validatePage(page)) {
|
||||||
if (page == this.page && page != 1 && page != maxPage) {
|
if (page == this.page && page != 1 && page != maxPage) {
|
||||||
return false;
|
return false;
|
||||||
@@ -582,7 +590,7 @@ abstract mixin class _ReaderLocation {
|
|||||||
if (page == maxPage) {
|
if (page == maxPage) {
|
||||||
autoPageTurningTimer!.cancel();
|
autoPageTurningTimer!.cancel();
|
||||||
}
|
}
|
||||||
toNextPage(cid, type);
|
toNextPage();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -348,6 +348,99 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
|
|||||||
text = "P${context.reader.page}";
|
text = "P${context.reader.page}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final buttons = [
|
||||||
|
Tooltip(
|
||||||
|
message: "Collect the image".tl,
|
||||||
|
child: IconButton(
|
||||||
|
icon: Icon(isLiked() ? Icons.favorite : Icons.favorite_border),
|
||||||
|
onPressed: addImageFavorite,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (App.isDesktop)
|
||||||
|
Tooltip(
|
||||||
|
message: "${"Full Screen".tl}(F12)",
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.fullscreen),
|
||||||
|
onPressed: () {
|
||||||
|
context.reader.fullscreen();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (App.isAndroid)
|
||||||
|
Tooltip(
|
||||||
|
message: "Screen Rotation".tl,
|
||||||
|
child: IconButton(
|
||||||
|
icon: () {
|
||||||
|
if (rotation == null) {
|
||||||
|
return const Icon(Icons.screen_rotation);
|
||||||
|
} else if (rotation == false) {
|
||||||
|
return const Icon(Icons.screen_lock_portrait);
|
||||||
|
} else {
|
||||||
|
return const Icon(Icons.screen_lock_landscape);
|
||||||
|
}
|
||||||
|
}.call(),
|
||||||
|
onPressed: () {
|
||||||
|
if (rotation == null) {
|
||||||
|
setState(() {
|
||||||
|
rotation = false;
|
||||||
|
});
|
||||||
|
SystemChrome.setPreferredOrientations([
|
||||||
|
DeviceOrientation.portraitUp,
|
||||||
|
DeviceOrientation.portraitDown,
|
||||||
|
]);
|
||||||
|
} else if (rotation == false) {
|
||||||
|
setState(() {
|
||||||
|
rotation = true;
|
||||||
|
});
|
||||||
|
SystemChrome.setPreferredOrientations([
|
||||||
|
DeviceOrientation.landscapeLeft,
|
||||||
|
DeviceOrientation.landscapeRight,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
rotation = null;
|
||||||
|
});
|
||||||
|
SystemChrome.setPreferredOrientations(DeviceOrientation.values);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Tooltip(
|
||||||
|
message: "Auto Page Turning".tl,
|
||||||
|
child: IconButton(
|
||||||
|
icon: context.reader.autoPageTurningTimer != null
|
||||||
|
? const Icon(Icons.timer)
|
||||||
|
: const Icon(Icons.timer_sharp),
|
||||||
|
onPressed: () {
|
||||||
|
context.reader.autoPageTurning(
|
||||||
|
context.reader.cid,
|
||||||
|
context.reader.type,
|
||||||
|
);
|
||||||
|
update();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (context.reader.widget.chapters != null)
|
||||||
|
Tooltip(
|
||||||
|
message: "Chapters".tl,
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.library_books),
|
||||||
|
onPressed: openChapterDrawer,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Tooltip(
|
||||||
|
message: "Save Image".tl,
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.download),
|
||||||
|
onPressed: saveCurrentImage,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Tooltip(
|
||||||
|
message: "Share".tl,
|
||||||
|
child: IconButton(icon: const Icon(Icons.share), onPressed: share),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
Widget child = SizedBox(
|
Widget child = SizedBox(
|
||||||
height: kBottomBarHeight,
|
height: kBottomBarHeight,
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -360,18 +453,10 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
|
|||||||
onPressed: () => !isReversed
|
onPressed: () => !isReversed
|
||||||
? context.reader.chapter > 1
|
? context.reader.chapter > 1
|
||||||
? context.reader.toPrevChapter()
|
? context.reader.toPrevChapter()
|
||||||
: context.reader.toPage(
|
: context.reader.toPage(1)
|
||||||
context.reader.cid,
|
|
||||||
context.reader.type,
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
: context.reader.chapter < context.reader.maxChapter
|
: context.reader.chapter < context.reader.maxChapter
|
||||||
? context.reader.toNextChapter()
|
? context.reader.toNextChapter()
|
||||||
: context.reader.toPage(
|
: context.reader.toPage(context.reader.maxPage),
|
||||||
context.reader.cid,
|
|
||||||
context.reader.type,
|
|
||||||
context.reader.maxPage,
|
|
||||||
),
|
|
||||||
icon: const Icon(Icons.first_page),
|
icon: const Icon(Icons.first_page),
|
||||||
),
|
),
|
||||||
Expanded(child: buildSlider()),
|
Expanded(child: buildSlider()),
|
||||||
@@ -379,135 +464,35 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
|
|||||||
onPressed: () => !isReversed
|
onPressed: () => !isReversed
|
||||||
? context.reader.chapter < context.reader.maxChapter
|
? context.reader.chapter < context.reader.maxChapter
|
||||||
? context.reader.toNextChapter()
|
? context.reader.toNextChapter()
|
||||||
: context.reader.toPage(
|
: context.reader.toPage(context.reader.maxPage)
|
||||||
context.reader.cid,
|
|
||||||
context.reader.type,
|
|
||||||
context.reader.maxPage,
|
|
||||||
)
|
|
||||||
: context.reader.chapter > 1
|
: context.reader.chapter > 1
|
||||||
? context.reader.toPrevChapter()
|
? context.reader.toPrevChapter()
|
||||||
: context.reader.toPage(
|
: context.reader.toPage(1),
|
||||||
context.reader.cid,
|
|
||||||
context.reader.type,
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
icon: const Icon(Icons.last_page),
|
icon: const Icon(Icons.last_page),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Row(
|
LayoutBuilder(
|
||||||
children: [
|
builder: (context, constrains) {
|
||||||
const SizedBox(width: 16),
|
return Row(
|
||||||
Container(
|
children: [
|
||||||
height: 24,
|
if ((constrains.maxWidth - buttons.length * 42) > 80)
|
||||||
padding: const EdgeInsets.fromLTRB(6, 2, 6, 0),
|
Container(
|
||||||
decoration: BoxDecoration(
|
height: 24,
|
||||||
color: Theme.of(context).colorScheme.tertiaryContainer,
|
padding: const EdgeInsets.fromLTRB(6, 2, 6, 0),
|
||||||
borderRadius: BorderRadius.circular(8),
|
decoration: BoxDecoration(
|
||||||
),
|
color: Theme.of(context).colorScheme.tertiaryContainer,
|
||||||
child: Center(child: Text(text)),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
child: Center(child: Text(text)),
|
||||||
Tooltip(
|
).paddingLeft(16),
|
||||||
message: "Collect the image".tl,
|
const Spacer(),
|
||||||
child: IconButton(
|
...buttons,
|
||||||
icon: Icon(
|
const SizedBox(width: 4),
|
||||||
isLiked() ? Icons.favorite : Icons.favorite_border,
|
],
|
||||||
),
|
);
|
||||||
onPressed: addImageFavorite,
|
},
|
||||||
),
|
|
||||||
),
|
|
||||||
if (App.isDesktop)
|
|
||||||
Tooltip(
|
|
||||||
message: "${"Full Screen".tl}(F12)",
|
|
||||||
child: IconButton(
|
|
||||||
icon: const Icon(Icons.fullscreen),
|
|
||||||
onPressed: () {
|
|
||||||
context.reader.fullscreen();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (App.isAndroid)
|
|
||||||
Tooltip(
|
|
||||||
message: "Screen Rotation".tl,
|
|
||||||
child: IconButton(
|
|
||||||
icon: () {
|
|
||||||
if (rotation == null) {
|
|
||||||
return const Icon(Icons.screen_rotation);
|
|
||||||
} else if (rotation == false) {
|
|
||||||
return const Icon(Icons.screen_lock_portrait);
|
|
||||||
} else {
|
|
||||||
return const Icon(Icons.screen_lock_landscape);
|
|
||||||
}
|
|
||||||
}.call(),
|
|
||||||
onPressed: () {
|
|
||||||
if (rotation == null) {
|
|
||||||
setState(() {
|
|
||||||
rotation = false;
|
|
||||||
});
|
|
||||||
SystemChrome.setPreferredOrientations([
|
|
||||||
DeviceOrientation.portraitUp,
|
|
||||||
DeviceOrientation.portraitDown,
|
|
||||||
]);
|
|
||||||
} else if (rotation == false) {
|
|
||||||
setState(() {
|
|
||||||
rotation = true;
|
|
||||||
});
|
|
||||||
SystemChrome.setPreferredOrientations([
|
|
||||||
DeviceOrientation.landscapeLeft,
|
|
||||||
DeviceOrientation.landscapeRight,
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
setState(() {
|
|
||||||
rotation = null;
|
|
||||||
});
|
|
||||||
SystemChrome.setPreferredOrientations(
|
|
||||||
DeviceOrientation.values,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: "Auto Page Turning".tl,
|
|
||||||
child: IconButton(
|
|
||||||
icon: context.reader.autoPageTurningTimer != null
|
|
||||||
? const Icon(Icons.timer)
|
|
||||||
: const Icon(Icons.timer_sharp),
|
|
||||||
onPressed: () {
|
|
||||||
context.reader.autoPageTurning(
|
|
||||||
context.reader.cid,
|
|
||||||
context.reader.type,
|
|
||||||
);
|
|
||||||
update();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (context.reader.widget.chapters != null)
|
|
||||||
Tooltip(
|
|
||||||
message: "Chapters".tl,
|
|
||||||
child: IconButton(
|
|
||||||
icon: const Icon(Icons.library_books),
|
|
||||||
onPressed: openChapterDrawer,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: "Save Image".tl,
|
|
||||||
child: IconButton(
|
|
||||||
icon: const Icon(Icons.download),
|
|
||||||
onPressed: saveCurrentImage,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: "Share".tl,
|
|
||||||
child: IconButton(
|
|
||||||
icon: const Icon(Icons.share),
|
|
||||||
onPressed: share,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 4),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -545,11 +530,7 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
|
|||||||
reversed: isReversed,
|
reversed: isReversed,
|
||||||
divisions: (context.reader.maxPage - 1).clamp(2, 1 << 16),
|
divisions: (context.reader.maxPage - 1).clamp(2, 1 << 16),
|
||||||
onChanged: (i) {
|
onChanged: (i) {
|
||||||
context.reader.toPage(
|
context.reader.toPage(i.toInt());
|
||||||
context.reader.cid,
|
|
||||||
context.reader.type,
|
|
||||||
i.toInt(),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -659,10 +640,7 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
|
|||||||
context.reader.type.sourceKey,
|
context.reader.type.sourceKey,
|
||||||
key,
|
key,
|
||||||
)) {
|
)) {
|
||||||
context.reader.handleVolumeEvent(
|
context.reader.handleVolumeEvent();
|
||||||
context.reader.cid,
|
|
||||||
context.reader.type,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
context.reader.stopVolumeEvent();
|
context.reader.stopVolumeEvent();
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,10 @@ class DebugPageState extends State<DebugPage> {
|
|||||||
},
|
},
|
||||||
actionTitle: 'Open'.tl,
|
actionTitle: 'Open'.tl,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
|
_SwitchSetting(
|
||||||
|
title: "Ignore Certificate Errors".tl,
|
||||||
|
settingKey: "ignoreBadCertificate",
|
||||||
|
).toSliver(),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
@@ -19,17 +19,57 @@ class ReaderSettings extends StatefulWidget {
|
|||||||
class _ReaderSettingsState extends State<ReaderSettings> {
|
class _ReaderSettingsState extends State<ReaderSettings> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final comicId = widget.comicId;
|
||||||
|
final sourceKey = widget.comicSource;
|
||||||
|
final key = "$comicId@$sourceKey";
|
||||||
|
|
||||||
|
bool isEnabledSpecificSettings =
|
||||||
|
comicId != null &&
|
||||||
|
appdata.settings.isComicSpecificSettingsEnabled(comicId, sourceKey);
|
||||||
|
|
||||||
return SmoothCustomScrollView(
|
return SmoothCustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
SliverAppbar(title: Text("Reading".tl)),
|
SliverAppbar(title: Text("Reading".tl)),
|
||||||
|
if (comicId != null && sourceKey != null)
|
||||||
|
SliverMainAxisGroup(
|
||||||
|
slivers: [
|
||||||
|
SwitchListTile(
|
||||||
|
title: Text("Enable comic specific settings".tl),
|
||||||
|
value: isEnabledSpecificSettings,
|
||||||
|
onChanged: (b) {
|
||||||
|
setState(() {
|
||||||
|
appdata.settings.setEnabledComicSpecificSettings(
|
||||||
|
comicId,
|
||||||
|
sourceKey,
|
||||||
|
b,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
).toSliver(),
|
||||||
|
if (isEnabledSpecificSettings)
|
||||||
|
Center(
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
appdata.settings.resetComicReaderSettings(key);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
"Clear specific reader settings for this comic".tl,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
).toSliver(),
|
||||||
|
Divider().toSliver(),
|
||||||
|
],
|
||||||
|
),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: "Tap to turn Pages".tl,
|
title: "Tap to turn Pages".tl,
|
||||||
settingKey: "enableTapToTurnPages",
|
settingKey: "enableTapToTurnPages",
|
||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call("enableTapToTurnPages");
|
widget.onChanged?.call("enableTapToTurnPages");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: "Reverse tap to turn Pages".tl,
|
title: "Reverse tap to turn Pages".tl,
|
||||||
@@ -37,8 +77,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call("reverseTapToTurnPages");
|
widget.onChanged?.call("reverseTapToTurnPages");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: "Page animation".tl,
|
title: "Page animation".tl,
|
||||||
@@ -46,15 +86,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call("enablePageAnimation");
|
widget.onChanged?.call("enablePageAnimation");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
|
||||||
_SwitchSetting(
|
|
||||||
title: "Enable comic specific settings".tl,
|
|
||||||
settingKey: "enableComicSpecificSettings",
|
|
||||||
onChanged: () {
|
|
||||||
widget.onChanged?.call("enableComicSpecificSettings");
|
|
||||||
},
|
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
SelectSetting(
|
SelectSetting(
|
||||||
title: "Reading mode".tl,
|
title: "Reading mode".tl,
|
||||||
@@ -78,8 +111,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
}
|
}
|
||||||
widget.onChanged?.call("readerMode");
|
widget.onChanged?.call("readerMode");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
_SliderSetting(
|
_SliderSetting(
|
||||||
title: "Auto page turning interval".tl,
|
title: "Auto page turning interval".tl,
|
||||||
@@ -91,8 +124,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
widget.onChanged?.call("autoPageTurningInterval");
|
widget.onChanged?.call("autoPageTurningInterval");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
SliverAnimatedVisibility(
|
SliverAnimatedVisibility(
|
||||||
visible: appdata.settings['readerMode']!.startsWith('gallery'),
|
visible: appdata.settings['readerMode']!.startsWith('gallery'),
|
||||||
@@ -108,8 +141,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
widget.onChanged?.call("readerScreenPicNumberForLandscape");
|
widget.onChanged?.call("readerScreenPicNumberForLandscape");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SliverAnimatedVisibility(
|
SliverAnimatedVisibility(
|
||||||
@@ -125,8 +158,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call("readerScreenPicNumberForPortrait");
|
widget.onChanged?.call("readerScreenPicNumberForPortrait");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SliverAnimatedVisibility(
|
SliverAnimatedVisibility(
|
||||||
@@ -140,8 +173,23 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call("showSingleImageOnFirstPage");
|
widget.onChanged?.call("showSingleImageOnFirstPage");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverAnimatedVisibility(
|
||||||
|
visible: appdata.settings['readerMode']!.startsWith('continuous'),
|
||||||
|
child: _SliderSetting(
|
||||||
|
title: "Mouse scroll speed".tl,
|
||||||
|
settingsIndex: "readerScrollSpeed",
|
||||||
|
interval: 0.1,
|
||||||
|
min: 0.5,
|
||||||
|
max: 3,
|
||||||
|
onChanged: () {
|
||||||
|
widget.onChanged?.call("readerScrollSpeed");
|
||||||
|
},
|
||||||
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
@@ -151,8 +199,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
widget.onChanged?.call('enableDoubleTapToZoom');
|
widget.onChanged?.call('enableDoubleTapToZoom');
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: 'Long press to zoom'.tl,
|
title: 'Long press to zoom'.tl,
|
||||||
@@ -161,8 +209,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
widget.onChanged?.call('enableLongPressToZoom');
|
widget.onChanged?.call('enableLongPressToZoom');
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
SliverAnimatedVisibility(
|
SliverAnimatedVisibility(
|
||||||
visible: appdata.settings['enableLongPressToZoom'] == true,
|
visible: appdata.settings['enableLongPressToZoom'] == true,
|
||||||
@@ -173,8 +221,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
"press": "Press position".tl,
|
"press": "Press position".tl,
|
||||||
"center": "Screen center".tl,
|
"center": "Screen center".tl,
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
@@ -184,8 +232,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call('limitImageWidth');
|
widget.onChanged?.call('limitImageWidth');
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
if (App.isAndroid)
|
if (App.isAndroid)
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
@@ -194,8 +242,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call('enableTurnPageByVolumeKey');
|
widget.onChanged?.call('enableTurnPageByVolumeKey');
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: "Display time & battery info in reader".tl,
|
title: "Display time & battery info in reader".tl,
|
||||||
@@ -203,8 +251,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call("enableClockAndBatteryInfoInReader");
|
widget.onChanged?.call("enableClockAndBatteryInfoInReader");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: "Show system status bar".tl,
|
title: "Show system status bar".tl,
|
||||||
@@ -212,8 +260,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call("showSystemStatusBar");
|
widget.onChanged?.call("showSystemStatusBar");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
SelectSetting(
|
SelectSetting(
|
||||||
title: "Quick collect image".tl,
|
title: "Quick collect image".tl,
|
||||||
@@ -229,8 +277,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
help:
|
help:
|
||||||
"On the image browsing page, you can quickly collect images by sliding horizontally or vertically according to your reading mode"
|
"On the image browsing page, you can quickly collect images by sliding horizontally or vertically according to your reading mode"
|
||||||
.tl,
|
.tl,
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
_CallbackSetting(
|
_CallbackSetting(
|
||||||
title: "Custom Image Processing".tl,
|
title: "Custom Image Processing".tl,
|
||||||
@@ -243,8 +291,8 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
interval: 1,
|
interval: 1,
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 16,
|
max: 16,
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: "Show Page Number".tl,
|
title: "Show Page Number".tl,
|
||||||
@@ -252,39 +300,9 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
onChanged: () {
|
onChanged: () {
|
||||||
widget.onChanged?.call("showPageNumberInReader");
|
widget.onChanged?.call("showPageNumberInReader");
|
||||||
},
|
},
|
||||||
comicId: widget.comicId,
|
comicId: isEnabledSpecificSettings ? widget.comicId : null,
|
||||||
comicSource: widget.comicSource,
|
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
// reset button
|
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
if (widget.comicId == null) {
|
|
||||||
appdata.settings.resetAllComicReaderSettings();
|
|
||||||
} else {
|
|
||||||
var keys = appdata
|
|
||||||
.settings['comicSpecificSettings']["${widget.comicId}@${widget.comicSource}"]
|
|
||||||
?.keys;
|
|
||||||
appdata.settings.resetComicReaderSettings(
|
|
||||||
widget.comicId!,
|
|
||||||
widget.comicSource!,
|
|
||||||
);
|
|
||||||
if (keys != null) {
|
|
||||||
setState(() {});
|
|
||||||
for (var key in keys) {
|
|
||||||
widget.onChanged?.call(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
(widget.comicId == null
|
|
||||||
? "Clear specific reader settings for all comics"
|
|
||||||
: "Clear specific reader settings for this comic")
|
|
||||||
.tl,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user