From 64d8bcba9a3c34854cb8a0fb964af341969b063a Mon Sep 17 00:00:00 2001 From: nyne Date: Sun, 10 Nov 2024 17:50:20 +0800 Subject: [PATCH] [Android] Turn page by volume keys --- assets/translation.json | 6 ++++-- lib/foundation/appdata.dart | 1 + lib/pages/reader/reader.dart | 32 ++++++++++++++++++++++++++++++++ lib/pages/reader/scaffold.dart | 7 +++++++ lib/pages/settings/reader.dart | 8 ++++++++ lib/utils/volume.dart | 31 +++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 lib/utils/volume.dart diff --git a/assets/translation.json b/assets/translation.json index ab09880..f213c0a 100644 --- a/assets/translation.json +++ b/assets/translation.json @@ -188,7 +188,8 @@ "Data Sync": "数据同步", "Quick Favorite": "快速收藏", "Long press on the favorite button to quickly add to this folder": "长按收藏按钮快速添加到这个文件夹", - "Added": "已添加" + "Added": "已添加", + "Turn page by volume keys": "使用音量键翻页" }, "zh_TW": { "Home": "首頁", @@ -379,6 +380,7 @@ "Data Sync": "數據同步", "Quick Favorite": "快速收藏", "Long press on the favorite button to quickly add to this folder": "長按收藏按鈕快速添加到這個文件夾", - "Added": "已添加" + "Added": "已添加", + "Turn page by volume keys": "使用音量鍵翻頁" } } \ No newline at end of file diff --git a/lib/foundation/appdata.dart b/lib/foundation/appdata.dart index e72bdf3..dc93fb8 100644 --- a/lib/foundation/appdata.dart +++ b/lib/foundation/appdata.dart @@ -117,6 +117,7 @@ class _Settings with ChangeNotifier { 'webdav': [], // empty means not configured 'dataVersion': 0, 'quickFavorite': null, + 'enableTurnPageByVolumeKey': true, }; operator [](String key) { diff --git a/lib/pages/reader/reader.dart b/lib/pages/reader/reader.dart index 65b4a47..65a432e 100644 --- a/lib/pages/reader/reader.dart +++ b/lib/pages/reader/reader.dart @@ -23,6 +23,7 @@ import 'package:venera/pages/settings/settings_page.dart'; import 'package:venera/utils/file_type.dart'; import 'package:venera/utils/io.dart'; import 'package:venera/utils/translations.dart'; +import 'package:venera/utils/volume.dart'; import 'package:window_manager/window_manager.dart'; part 'scaffold.dart'; @@ -97,6 +98,8 @@ class _ReaderState extends State with _ReaderLocation, _ReaderWindow { var focusNode = FocusNode(); + VolumeListener? volumeListener; + @override void initState() { page = widget.initialPage ?? 1; @@ -107,6 +110,9 @@ class _ReaderState extends State with _ReaderLocation, _ReaderWindow { updateHistory(); }); SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); + if(appdata.settings['enableTurnPageByVolumeKey']) { + handleVolumeEvent(); + } super.initState(); } @@ -115,6 +121,7 @@ class _ReaderState extends State with _ReaderLocation, _ReaderWindow { autoPageTurningTimer?.cancel(); focusNode.dispose(); SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + stopVolumeEvent(); super.dispose(); } @@ -152,6 +159,31 @@ class _ReaderState extends State with _ReaderLocation, _ReaderWindow { HistoryManager().addHistory(history!); } } + + void handleVolumeEvent() { + if(!App.isAndroid) { + // Currently only support Android + return; + } + if(volumeListener != null) { + volumeListener?.cancel(); + } + volumeListener = VolumeListener( + onDown: () { + toNextPage(); + }, + onUp: () { + toPrevPage(); + }, + )..listen(); + } + + void stopVolumeEvent() { + if(volumeListener != null) { + volumeListener?.cancel(); + volumeListener = null; + } + } } abstract mixin class _ReaderLocation { diff --git a/lib/pages/reader/scaffold.dart b/lib/pages/reader/scaffold.dart index 598e173..36ecea3 100644 --- a/lib/pages/reader/scaffold.dart +++ b/lib/pages/reader/scaffold.dart @@ -470,6 +470,13 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> { context.reader.mode = ReaderMode.fromKey(appdata.settings[key]); App.rootContext.pop(); } + if (key == "enableTurnPageByVolumeKey") { + if(appdata.settings[key]) { + context.reader.handleVolumeEvent(); + } else { + context.reader.stopVolumeEvent(); + } + } context.reader.update(); }, ), diff --git a/lib/pages/settings/reader.dart b/lib/pages/settings/reader.dart index a597736..3635800 100644 --- a/lib/pages/settings/reader.dart +++ b/lib/pages/settings/reader.dart @@ -69,6 +69,14 @@ class _ReaderSettingsState extends State { widget.onChanged?.call('limitImageWidth'); }, ).toSliver(), + if(App.isAndroid) + _SwitchSetting( + title: 'Turn page by volume key'.tl, + settingKey: 'enableTurnPageByVolumeKey', + onChanged: () { + widget.onChanged?.call('enableTurnPageByVolumeKey'); + }, + ).toSliver(), ], ); } diff --git a/lib/utils/volume.dart b/lib/utils/volume.dart new file mode 100644 index 0000000..fb053ed --- /dev/null +++ b/lib/utils/volume.dart @@ -0,0 +1,31 @@ +import 'dart:async'; + +import 'package:flutter/services.dart'; + +class VolumeListener { + static const channel = EventChannel('venera/volume'); + + void Function()? onUp; + + void Function()? onDown; + + VolumeListener({this.onUp, this.onDown}); + + StreamSubscription? stream; + + void listen() { + stream = channel.receiveBroadcastStream().listen(onEvent); + } + + void onEvent(event) { + if (event == 1) { + onUp!(); + } else if (event == 2) { + onDown!(); + } + } + + void cancel() { + stream?.cancel(); + } +} \ No newline at end of file