diff --git a/assets/translation.json b/assets/translation.json index f213c0a..73539a0 100644 --- a/assets/translation.json +++ b/assets/translation.json @@ -189,7 +189,8 @@ "Quick Favorite": "快速收藏", "Long press on the favorite button to quickly add to this folder": "长按收藏按钮快速添加到这个文件夹", "Added": "已添加", - "Turn page by volume keys": "使用音量键翻页" + "Turn page by volume keys": "使用音量键翻页", + "Display time & battery info in reader":"在阅读器中显示时间和电量信息" }, "zh_TW": { "Home": "首頁", @@ -381,6 +382,7 @@ "Quick Favorite": "快速收藏", "Long press on the favorite button to quickly add to this folder": "長按收藏按鈕快速添加到這個文件夾", "Added": "已添加", - "Turn page by volume keys": "使用音量鍵翻頁" + "Turn page by volume keys": "使用音量鍵翻頁", + "Display time & battery info in reader":"在閱讀器中顯示時間和電量信息" } } \ No newline at end of file diff --git a/lib/foundation/appdata.dart b/lib/foundation/appdata.dart index dc93fb8..afd1522 100644 --- a/lib/foundation/appdata.dart +++ b/lib/foundation/appdata.dart @@ -118,6 +118,7 @@ class _Settings with ChangeNotifier { 'dataVersion': 0, 'quickFavorite': null, 'enableTurnPageByVolumeKey': true, + 'enableClockAndBatteryInfoInReader': true, }; operator [](String key) { diff --git a/lib/pages/reader/reader.dart b/lib/pages/reader/reader.dart index 6dea93f..3cc1838 100644 --- a/lib/pages/reader/reader.dart +++ b/lib/pages/reader/reader.dart @@ -26,6 +26,7 @@ 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'; +import 'package:battery_plus/battery_plus.dart'; part 'scaffold.dart'; part 'images.dart'; diff --git a/lib/pages/reader/scaffold.dart b/lib/pages/reader/scaffold.dart index 36ecea3..265fc11 100644 --- a/lib/pages/reader/scaffold.dart +++ b/lib/pages/reader/scaffold.dart @@ -131,10 +131,11 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> { child: widget.child, ), buildPageInfoText(), + buildStatusInfo(), AnimatedPositioned( duration: const Duration(milliseconds: 180), right: 16, - bottom: showFloatingButtonValue == 0 ? -58 : 16, + bottom: showFloatingButtonValue == 0 ? -58 : 36, child: buildEpChangeButton(), ), AnimatedPositioned( @@ -424,6 +425,24 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> { ); } + Widget buildStatusInfo() { + if(appdata.settings['enableClockAndBatteryInfoInReader']) { + return Positioned( + bottom: 13, + right: 25, + child: Row( + children: [ + _ClockWidget(), + const SizedBox(width: 10), + _BatteryWidget(), + ], + ), + ); + } else { + return const SizedBox.shrink(); + } + } + void openChapterDrawer() { showSideBar( context, @@ -569,6 +588,186 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> { } } +class _BatteryWidget extends StatefulWidget { + @override + _BatteryWidgetState createState() => _BatteryWidgetState(); +} + +class _BatteryWidgetState extends State<_BatteryWidget> { + late Battery _battery; + late int _batteryLevel = 100; + Timer? _timer; + bool _hasBattery = false; + + @override + void initState() { + super.initState(); + _battery = Battery(); + _checkBatteryAvailability(); + } + + void _checkBatteryAvailability() async { + try { + _batteryLevel = await _battery.batteryLevel; + if (_batteryLevel != -1) { + setState(() { + _hasBattery = true; + _timer = Timer.periodic(const Duration(seconds: 1), (timer) { + _battery.batteryLevel.then((level) =>{ + if(_batteryLevel != level) { + setState(() { + _batteryLevel = level; + }) + } + }); + }); + }); + } else { + setState(() { + _hasBattery = false; + }); + } + } catch (e) { + setState(() { + _hasBattery = false; + }); + } + } + + @override + Widget build(BuildContext context) { + if (!_hasBattery) { + return const SizedBox.shrink(); //Empty Widget + } + return _batteryInfo(_batteryLevel); + } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); + } + + Widget _batteryInfo(int batteryLevel) { + IconData batteryIcon; + Color batteryColor = Colors.black; + + if (batteryLevel >= 96) { + batteryIcon = Icons.battery_full_sharp; + } else if (batteryLevel >= 84) { + batteryIcon = Icons.battery_6_bar_sharp; + } else if (batteryLevel >= 72) { + batteryIcon = Icons.battery_5_bar_sharp; + } else if (batteryLevel >= 60) { + batteryIcon = Icons.battery_4_bar_sharp; + } else if (batteryLevel >= 48) { + batteryIcon = Icons.battery_3_bar_sharp; + } else if (batteryLevel >= 36) { + batteryIcon = Icons.battery_2_bar_sharp; + } else if (batteryLevel >= 24) { + batteryIcon = Icons.battery_1_bar_sharp; + } else if (batteryLevel >= 12) { + batteryIcon = Icons.battery_0_bar_sharp; + } else { + batteryIcon = Icons.battery_alert_sharp; + batteryColor = Colors.red; + } + + return Row( + children: [ + Icon( + batteryIcon, + size: 16, + color: batteryColor, + // Stroke + shadows: List.generate(9, + (index) { + if(index == 4) { + return null; + } + double offsetX = (index % 3 - 1) * 0.8; + double offsetY = ((index / 3).floor() - 1) * 0.8; + return Shadow( + color: context.colorScheme.onInverseSurface, + offset: Offset(offsetX, offsetY), + ); + }, + ).whereType().toList(), + ), + Stack( + children: [ + Text( + '$batteryLevel%', + style: TextStyle( + fontSize: 14, + foreground: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 1.4 + ..color = context.colorScheme.onInverseSurface, + ), + ), + Text('$batteryLevel%'), + ], + ), + ], + ); + } +} + +class _ClockWidget extends StatefulWidget { + @override + _ClockWidgetState createState() => _ClockWidgetState(); +} + +class _ClockWidgetState extends State<_ClockWidget> { + late String _currentTime; + late Timer _timer; + + @override + void initState() { + super.initState(); + _currentTime = _getCurrentTime(); + _timer = Timer.periodic(const Duration(seconds: 1), (timer) { + final time = _getCurrentTime(); + if(_currentTime != time) { + setState(() { + _currentTime = time; + }); + } + }); + } + + String _getCurrentTime() { + final now = DateTime.now(); + return "${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}"; + } + + @override + void dispose() { + _timer.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Text( + _currentTime, + style: TextStyle( + fontSize: 14, + foreground: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 1.4 + ..color = context.colorScheme.onInverseSurface, + ), + ), + Text(_currentTime), + ], + ); + } +} + class _ChaptersView extends StatefulWidget { const _ChaptersView(this.reader); diff --git a/lib/pages/settings/reader.dart b/lib/pages/settings/reader.dart index 3635800..e982dc3 100644 --- a/lib/pages/settings/reader.dart +++ b/lib/pages/settings/reader.dart @@ -77,6 +77,13 @@ class _ReaderSettingsState extends State { widget.onChanged?.call('enableTurnPageByVolumeKey'); }, ).toSliver(), + _SwitchSetting( + title: "Display time & battery info in reader".tl, + settingKey: "enableClockAndBatteryInfoInReader", + onChanged: () { + widget.onChanged?.call("enableClockAndBatteryInfoInReader"); + }, + ).toSliver(), ], ); } diff --git a/pubspec.lock b/pubspec.lock index c1c24c8..87a2ebf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + battery_plus: + dependency: "direct main" + description: + name: battery_plus + sha256: "220c8f1961efb01d6870493b5ac5a80afaeaffc8757f7a11ed3025a8570d29e7" + url: "https://pub.dev" + source: hosted + version: "6.2.0" + battery_plus_platform_interface: + dependency: transitive + description: + name: battery_plus_platform_interface + sha256: e8342c0f32de4b1dfd0223114b6785e48e579bfc398da9471c9179b907fa4910 + url: "https://pub.dev" + source: hosted + version: "2.0.1" boolean_selector: dependency: transitive description: @@ -121,6 +137,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + url: "https://pub.dev" + source: hosted + version: "0.7.10" desktop_webview_window: dependency: "direct main" description: @@ -800,6 +824,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + upower: + dependency: transitive + description: + name: upower + sha256: cf042403154751180affa1d15614db7fa50234bc2373cd21c3db666c38543ebf + url: "https://pub.dev" + source: hosted + version: "0.7.0" url_launcher: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index aad2ff3..79e4d25 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,6 +63,7 @@ dependencies: git: url: https://github.com/wgh136/webdav_client ref: 285f87f15bccd2d5d5ff443761348c6ee47b98d1 + battery_plus: ^6.2.0 dev_dependencies: flutter_test: