mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
Add a setting for long press position. Close #287
This commit is contained in:
@@ -381,7 +381,10 @@
|
|||||||
"A valid WebDav directory URL": "有效的WebDav目录URL",
|
"A valid WebDav directory URL": "有效的WebDav目录URL",
|
||||||
"Shut Down": "关闭",
|
"Shut Down": "关闭",
|
||||||
"Uploading data...": "正在上传数据...",
|
"Uploading data...": "正在上传数据...",
|
||||||
"Pages": "页数"
|
"Pages": "页数",
|
||||||
|
"Long press zoom position": "长按缩放位置",
|
||||||
|
"Press position": "按压位置",
|
||||||
|
"Screen center": "屏幕中心"
|
||||||
},
|
},
|
||||||
"zh_TW": {
|
"zh_TW": {
|
||||||
"Home": "首頁",
|
"Home": "首頁",
|
||||||
@@ -765,6 +768,9 @@
|
|||||||
"A valid WebDav directory URL": "有效的WebDav目錄URL",
|
"A valid WebDav directory URL": "有效的WebDav目錄URL",
|
||||||
"Shut Down": "關閉",
|
"Shut Down": "關閉",
|
||||||
"Uploading data...": "正在上傳數據...",
|
"Uploading data...": "正在上傳數據...",
|
||||||
"Pages": "頁數"
|
"Pages": "頁數",
|
||||||
|
"Long press zoom position": "長按縮放位置",
|
||||||
|
"Press position": "按壓位置",
|
||||||
|
"Screen center": "螢幕中心"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -163,3 +163,29 @@ class SliverLazyToBoxAdapter extends StatelessWidget {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SliverAnimatedVisibility extends StatelessWidget {
|
||||||
|
const SliverAnimatedVisibility({
|
||||||
|
super.key,
|
||||||
|
required this.visible,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool visible;
|
||||||
|
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var child = visible ? this.child : const SizedBox.shrink();
|
||||||
|
|
||||||
|
return SliverToBoxAdapter(
|
||||||
|
child: AnimatedSize(
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -161,6 +161,7 @@ class Settings with ChangeNotifier {
|
|||||||
'cacheSize': 2048, // in MB
|
'cacheSize': 2048, // in MB
|
||||||
'downloadThreads': 5,
|
'downloadThreads': 5,
|
||||||
'enableLongPressToZoom': true,
|
'enableLongPressToZoom': true,
|
||||||
|
'longPressZoomPosition': "press", // press, center
|
||||||
'checkUpdateOnStart': false,
|
'checkUpdateOnStart': false,
|
||||||
'limitImageWidth': true,
|
'limitImageWidth': true,
|
||||||
'webdav': [], // empty means not configured
|
'webdav': [], // empty means not configured
|
||||||
|
@@ -343,10 +343,19 @@ class _GalleryModeState extends State<_GalleryMode>
|
|||||||
}
|
}
|
||||||
var photoViewController = photoViewControllers[reader.page]!;
|
var photoViewController = photoViewControllers[reader.page]!;
|
||||||
double target = photoViewController.getInitialScale!.call()! * 1.75;
|
double target = photoViewController.getInitialScale!.call()! * 1.75;
|
||||||
var size = MediaQuery.of(context).size;
|
var size = reader.size;
|
||||||
|
Offset zoomPosition;
|
||||||
|
if (appdata.settings['longPressZoomPosition'] != 'center') {
|
||||||
|
zoomPosition = Offset(
|
||||||
|
size.width / 2 - location.dx,
|
||||||
|
size.height / 2 - location.dy,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
zoomPosition = Offset(0, 0);
|
||||||
|
}
|
||||||
photoViewController.animateScale?.call(
|
photoViewController.animateScale?.call(
|
||||||
target,
|
target,
|
||||||
Offset(size.width / 2 - location.dx, size.height / 2 - location.dy),
|
zoomPosition,
|
||||||
);
|
);
|
||||||
isLongPressing = true;
|
isLongPressing = true;
|
||||||
}
|
}
|
||||||
@@ -608,6 +617,13 @@ class _ContinuousModeState extends State<_ContinuousMode>
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool onScaleUpdate([double? scale]) {
|
bool onScaleUpdate([double? scale]) {
|
||||||
|
if (prepareToNextChapter || prepareToPrevChapter) {
|
||||||
|
setState(() {
|
||||||
|
prepareToPrevChapter = false;
|
||||||
|
prepareToNextChapter = false;
|
||||||
|
});
|
||||||
|
context.readerScaffold.setFloatingButton(0);
|
||||||
|
}
|
||||||
var isZoomedIn = (scale ?? photoViewController.scale) != 1.0;
|
var isZoomedIn = (scale ?? photoViewController.scale) != 1.0;
|
||||||
if (isZoomedIn != this.isZoomedIn) {
|
if (isZoomedIn != this.isZoomedIn) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -731,7 +747,7 @@ class _ContinuousModeState extends State<_ContinuousMode>
|
|||||||
}
|
}
|
||||||
Offset offset;
|
Offset offset;
|
||||||
var sp = scrollController.position;
|
var sp = scrollController.position;
|
||||||
if (sp.pixels < sp.minScrollExtent || sp.pixels > sp.maxScrollExtent) {
|
if (sp.pixels <= sp.minScrollExtent || sp.pixels >= sp.maxScrollExtent) {
|
||||||
offset = Offset(value.dx, value.dy);
|
offset = Offset(value.dx, value.dy);
|
||||||
} else {
|
} else {
|
||||||
if (reader.mode == ReaderMode.continuousTopToBottom) {
|
if (reader.mode == ReaderMode.continuousTopToBottom) {
|
||||||
@@ -759,7 +775,10 @@ class _ContinuousModeState extends State<_ContinuousMode>
|
|||||||
delayedSetIsScrolling(false);
|
delayedSetIsScrolling(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification is ScrollUpdateNotification) {
|
var scale = photoViewController.scale ?? 1.0;
|
||||||
|
|
||||||
|
if (notification is ScrollUpdateNotification &&
|
||||||
|
(scale - 1).abs() < 0.05) {
|
||||||
if (!scrollController.hasClients) return false;
|
if (!scrollController.hasClients) return false;
|
||||||
if (scrollController.position.pixels <=
|
if (scrollController.position.pixels <=
|
||||||
scrollController.position.minScrollExtent &&
|
scrollController.position.minScrollExtent &&
|
||||||
@@ -800,8 +819,8 @@ class _ContinuousModeState extends State<_ContinuousMode>
|
|||||||
},
|
},
|
||||||
child: widget,
|
child: widget,
|
||||||
);
|
);
|
||||||
var width = MediaQuery.of(context).size.width;
|
var width = reader.size.width;
|
||||||
var height = MediaQuery.of(context).size.height;
|
var height = reader.size.height;
|
||||||
if (appdata.settings['limitImageWidth'] &&
|
if (appdata.settings['limitImageWidth'] &&
|
||||||
width / height > 0.7 &&
|
width / height > 0.7 &&
|
||||||
reader.mode == ReaderMode.continuousTopToBottom) {
|
reader.mode == ReaderMode.continuousTopToBottom) {
|
||||||
@@ -882,9 +901,19 @@ class _ContinuousModeState extends State<_ContinuousMode>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
double target = photoViewController.getInitialScale!.call()! * 1.75;
|
double target = photoViewController.getInitialScale!.call()! * 1.75;
|
||||||
|
var size = reader.size;
|
||||||
|
Offset zoomPosition;
|
||||||
|
if (appdata.settings['longPressZoomPosition'] != 'center') {
|
||||||
|
zoomPosition = Offset(
|
||||||
|
size.width / 2 - location.dx,
|
||||||
|
size.height / 2 - location.dy,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
zoomPosition = Offset(0, 0);
|
||||||
|
}
|
||||||
photoViewController.animateScale?.call(
|
photoViewController.animateScale?.call(
|
||||||
target,
|
target,
|
||||||
Offset(0, 0),
|
zoomPosition,
|
||||||
);
|
);
|
||||||
onScaleUpdate(target);
|
onScaleUpdate(target);
|
||||||
isLongPressing = true;
|
isLongPressing = true;
|
||||||
|
@@ -309,6 +309,13 @@ class _ReaderState extends State<Reader>
|
|||||||
}
|
}
|
||||||
return chapter == maxChapter;
|
return chapter == maxChapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the size of the reader.
|
||||||
|
/// The size is not always the same as the size of the screen.
|
||||||
|
Size get size {
|
||||||
|
var renderBox = context.findRenderObject() as RenderBox;
|
||||||
|
return renderBox.size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract mixin class _ImagePerPageHandler {
|
abstract mixin class _ImagePerPageHandler {
|
||||||
|
@@ -48,6 +48,7 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
"continuousTopToBottom": "Continuous (Top to Bottom)".tl,
|
"continuousTopToBottom": "Continuous (Top to Bottom)".tl,
|
||||||
},
|
},
|
||||||
onChanged: () {
|
onChanged: () {
|
||||||
|
setState(() {});
|
||||||
var readerMode = appdata.settings['readerMode'];
|
var readerMode = appdata.settings['readerMode'];
|
||||||
if (readerMode?.toLowerCase().startsWith('continuous') ?? false) {
|
if (readerMode?.toLowerCase().startsWith('continuous') ?? false) {
|
||||||
appdata.settings['readerScreenPicNumberForLandscape'] = 1;
|
appdata.settings['readerScreenPicNumberForLandscape'] = 1;
|
||||||
@@ -68,22 +69,12 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
widget.onChanged?.call("autoPageTurningInterval");
|
widget.onChanged?.call("autoPageTurningInterval");
|
||||||
},
|
},
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
SliverToBoxAdapter(
|
SliverAnimatedVisibility(
|
||||||
child: AbsorbPointer(
|
visible: appdata.settings['readerMode']!.startsWith('gallery'),
|
||||||
absorbing: (appdata.settings['readerMode']
|
|
||||||
?.toLowerCase()
|
|
||||||
.startsWith('continuous') ??
|
|
||||||
false),
|
|
||||||
child: AnimatedOpacity(
|
|
||||||
opacity: (appdata.settings['readerMode']
|
|
||||||
?.toLowerCase()
|
|
||||||
.startsWith('continuous') ??
|
|
||||||
false)
|
|
||||||
? 0.5
|
|
||||||
: 1.0,
|
|
||||||
duration: Duration(milliseconds: 300),
|
|
||||||
child: _SliderSetting(
|
child: _SliderSetting(
|
||||||
title: "The number of pic in screen for landscape (Only Gallery Mode)".tl,
|
title:
|
||||||
|
"The number of pic in screen for landscape (Only Gallery Mode)"
|
||||||
|
.tl,
|
||||||
settingsIndex: "readerScreenPicNumberForLandscape",
|
settingsIndex: "readerScreenPicNumberForLandscape",
|
||||||
interval: 1,
|
interval: 1,
|
||||||
min: 1,
|
min: 1,
|
||||||
@@ -93,24 +84,12 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
SliverAnimatedVisibility(
|
||||||
),
|
visible: appdata.settings['readerMode']!.startsWith('gallery'),
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: AbsorbPointer(
|
|
||||||
absorbing: (appdata.settings['readerMode']
|
|
||||||
?.toLowerCase()
|
|
||||||
.startsWith('continuous') ??
|
|
||||||
false),
|
|
||||||
child: AnimatedOpacity(
|
|
||||||
opacity: (appdata.settings['readerMode']
|
|
||||||
?.toLowerCase()
|
|
||||||
.startsWith('continuous') ??
|
|
||||||
false)
|
|
||||||
? 0.5
|
|
||||||
: 1.0,
|
|
||||||
duration: Duration(milliseconds: 300),
|
|
||||||
child: _SliderSetting(
|
child: _SliderSetting(
|
||||||
title: "The number of pic in screen for portrait (Only Gallery Mode)".tl,
|
title:
|
||||||
|
"The number of pic in screen for portrait (Only Gallery Mode)"
|
||||||
|
.tl,
|
||||||
settingsIndex: "readerScreenPicNumberForPortrait",
|
settingsIndex: "readerScreenPicNumberForPortrait",
|
||||||
interval: 1,
|
interval: 1,
|
||||||
min: 1,
|
min: 1,
|
||||||
@@ -120,15 +99,25 @@ class _ReaderSettingsState extends State<ReaderSettings> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: 'Long press to zoom'.tl,
|
title: 'Long press to zoom'.tl,
|
||||||
settingKey: 'enableLongPressToZoom',
|
settingKey: 'enableLongPressToZoom',
|
||||||
onChanged: () {
|
onChanged: () {
|
||||||
|
setState(() {});
|
||||||
widget.onChanged?.call('enableLongPressToZoom');
|
widget.onChanged?.call('enableLongPressToZoom');
|
||||||
},
|
},
|
||||||
).toSliver(),
|
).toSliver(),
|
||||||
|
SliverAnimatedVisibility(
|
||||||
|
visible: appdata.settings['enableLongPressToZoom'] == true,
|
||||||
|
child: SelectSetting(
|
||||||
|
title: "Long press zoom position".tl,
|
||||||
|
settingKey: "longPressZoomPosition",
|
||||||
|
optionTranslation: {
|
||||||
|
"press": "Press position".tl,
|
||||||
|
"center": "Screen center".tl,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
_SwitchSetting(
|
_SwitchSetting(
|
||||||
title: 'Limit image width'.tl,
|
title: 'Limit image width'.tl,
|
||||||
subtitle: 'When using Continuous(Top to Bottom) mode'.tl,
|
subtitle: 'When using Continuous(Top to Bottom) mode'.tl,
|
||||||
|
Reference in New Issue
Block a user