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..a0bf05c 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,20 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> { ); } + Widget buildStatusInfo() { + return Positioned( + bottom: 13, + right: 25, + child: Row( + children: [ + _ClockWidget(), + const SizedBox(width: 10), + _BatteryWidget(), + ], + ), + ); + } + void openChapterDrawer() { showSideBar( context, @@ -569,6 +584,190 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> { } } +class _BatteryWidget extends StatefulWidget { + @override + _BatteryWidgetState createState() => _BatteryWidgetState(); +} + +class _BatteryWidgetState extends State<_BatteryWidget> { + late Battery _battery; + late int _batteryLevel; + Timer? _timer; + bool _hasBattery = false; + + @override + void initState() { + super.initState(); + _battery = Battery(); + _checkBatteryAvailability(); + if(_hasBattery) { + _timer = Timer.periodic(const Duration(seconds: 1), (timer) async { + final batteryLevel = await _battery.batteryLevel; + if(_batteryLevel != batteryLevel) { + setState(() { + _batteryLevel = batteryLevel; + }); + } + }); + } else { + _timer = null; + } + } + + void _checkBatteryAvailability() async { + try { + _batteryLevel = await _battery.batteryLevel; + if (_batteryLevel != -1) { + setState(() { + _hasBattery = true; + }); + } 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/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: