Skip to content

Commit

Permalink
feat(mobile):more options in setting
Browse files Browse the repository at this point in the history
fix:full screen  in comic and novel reader
feat(indicator bar):  battery indicator,
feat:wakelock
  • Loading branch information
appdevelpo committed Jan 20, 2024
1 parent 47e6a91 commit 5bfbe6c
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 79 deletions.
38 changes: 34 additions & 4 deletions lib/controllers/watch/comic_controller.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:miru_app/data/providers/anilist_provider.dart';
Expand All @@ -8,6 +9,10 @@ import 'package:miru_app/data/services/database_service.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:extended_image/extended_image.dart';
import 'package:miru_app/utils/miru_storage.dart';
import 'dart:async';
import 'package:battery_plus/battery_plus.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:miru_app/utils/i18n.dart';

class ComicController extends ReaderController<ExtensionMangaWatch> {
ComicController({
Expand Down Expand Up @@ -38,17 +43,39 @@ class ComicController extends ReaderController<ExtensionMangaWatch> {
final itemPositionsListener = ItemPositionsListener.create();
final itemScrollController = ItemScrollController();
final scrollOffsetController = ScrollOffsetController();

final alignMode = Alignment.bottomLeft.obs;
// 是否已经恢复上次阅读
final isRecover = false.obs;

final batteryLevel = 100.obs;
// 是否按下 ctrl

Timer? _barreryTimer;
final statusBarElement = <String, RxBool>{
'reader-setting.battery'.i18n: true.obs,
'reader-setting.time'.i18n: true.obs,
'reader-setting.page-indicator'.i18n: true.obs,
'reader-setting.battery-icon'.i18n: true.obs,
};
final isZoom = false.obs;
final currentTime = "".obs;
Future<void> _statusBar([Timer? t]) async {
final battery = Battery();
batteryLevel.value = await battery.batteryLevel;
final datenow = DateTime.now();
final hour = datenow.hour < 10 ? "0${datenow.hour}" : datenow.hour;
final minute = datenow.minute < 10 ? "0${datenow.minute}" : datenow.minute;
currentTime.value = "$hour:$minute";
debugPrint("${datenow.toLocal()}");
}

@override
void onInit() {
void onInit() async {
_initSetting();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
WakelockPlus.toggle(
enable: MiruStorage.getSetting(SettingKey.enableWakelock));
await _statusBar();
_barreryTimer = Timer.periodic(
const Duration(seconds: 10), (timer) => _statusBar(timer));
itemPositionsListener.itemPositions.addListener(() {
if (itemPositionsListener.itemPositions.value.isEmpty) {
return;
Expand Down Expand Up @@ -196,6 +223,9 @@ class ComicController extends ReaderController<ExtensionMangaWatch> {
mediaId: anilistID,
);
}
_barreryTimer!.cancel();
WakelockPlus.disable();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
super.onClose();
}
}
7 changes: 6 additions & 1 deletion lib/controllers/watch/novel_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import 'package:miru_app/controllers/watch/reader_controller.dart';
import 'package:miru_app/data/services/database_service.dart';
import 'package:miru_app/utils/miru_storage.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:flutter/services.dart';

class NovelController extends ReaderController<ExtensionFikushonWatch> {
NovelController({
Expand All @@ -26,8 +28,10 @@ class NovelController extends ReaderController<ExtensionFikushonWatch> {
@override
void onInit() {
super.onInit();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
fontSize.value = MiruStorage.getSetting(SettingKey.novelFontSize);

WakelockPlus.toggle(
enable: MiruStorage.getSetting(SettingKey.enableWakelock));
itemPositionsListener.itemPositions.addListener(() {
if (itemPositionsListener.itemPositions.value.isEmpty) {
return;
Expand Down Expand Up @@ -72,6 +76,7 @@ class NovelController extends ReaderController<ExtensionFikushonWatch> {
totalProgress,
);
}
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
super.onClose();
}
}
3 changes: 3 additions & 0 deletions lib/utils/miru_storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class MiruStorage {
await _initSetting(SettingKey.proxy, '');
await _initSetting(SettingKey.proxyType, 'DIRECT');
await _initSetting(SettingKey.saveLog, true);
await _initSetting(SettingKey.enableWakelock, false);
}

static _initSetting(String key, dynamic value) async {
Expand Down Expand Up @@ -176,7 +177,9 @@ class SettingKey {
static String keyJ = 'KeyJ';
static String arrowLeft = 'Arrowleft';
static String arrowRight = 'Arrowright';
//reading mode
static String readingMode = 'ReadingMode';
static String enableWakelock = 'EnableWakelock';
static String aniListToken = 'AniListToken';
static String aniListUserId = 'AniListUserId';
static String autoTracking = 'AutoTracking';
Expand Down
72 changes: 53 additions & 19 deletions lib/views/pages/watch/reader/comic/comic_reader_content.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:fluent_ui/fluent_ui.dart' as fluent;
Expand All @@ -12,6 +11,7 @@ import 'package:miru_app/views/widgets/platform_widget.dart';
import 'package:miru_app/views/widgets/progress.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:extended_image/extended_image.dart';
import 'package:based_battery_indicator/based_battery_indicator.dart';

class ComicReaderContent extends StatefulWidget {
const ComicReaderContent(this.tag, {super.key});
Expand All @@ -22,11 +22,6 @@ class ComicReaderContent extends StatefulWidget {
}

class _ComicReaderContentState extends State<ComicReaderContent> {
@override
void initState() {
super.initState();
}

late final _c = Get.find<ComicController>(tag: widget.tag);

// 按下数量
Expand All @@ -46,27 +41,66 @@ class _ComicReaderContentState extends State<ComicReaderContent> {
);
}

_buildDisplay(Widget child) {
Widget _buildDisplay(Widget child) {
if (_c.statusBarElement.values.every((element) => element.value == false)) {
return child;
}
return Stack(
children: [
child,
Positioned(
bottom: 0,
child: Container(
color: Colors.black.withAlpha(200),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 2),
child: Obx(
() => Text(
"${_c.currentPage.value + 1}/${_c.watchData.value?.urls.length ?? 0}",
style: const TextStyle(color: Colors.white, fontSize: 15),
Obx(() => Align(
alignment: _c.alignMode.value,
child: Container(
color: Colors.black.withAlpha(200),
padding: const EdgeInsets.fromLTRB(20, 2, 12, 2),
child: _indicatorBuilder(),
),
),
),
),
)),
],
);
}

Widget _indicatorBuilder() {
return Obx(() => Row(mainAxisSize: MainAxisSize.min, children: [
if (_c.statusBarElement["reader-setting.page-indicator".i18n]!
.value) ...[
Text(
"${_c.currentPage.value + 1}/${_c.watchData.value?.urls.length ?? 0}",
style: const TextStyle(color: Colors.white, fontSize: 15),
),
const SizedBox(width: 8)
],
if (_c
.statusBarElement["reader-setting.battery-icon".i18n]!.value) ...[
BasedBatteryIndicator(
status: BasedBatteryStatus(
value: _c.batteryLevel.value,
type: BasedBatteryStatusType.normal,
),
trackHeight: 10.0,
trackAspectRatio: 2.0,
curve: Curves.ease,
duration: const Duration(seconds: 10),
),
const SizedBox(width: 8)
],
if (_c.statusBarElement["reader-setting.battery".i18n]!.value) ...[
Text(
"${_c.batteryLevel.value}%",
style: const TextStyle(color: Colors.white, fontSize: 15),
),
const SizedBox(width: 8)
],
if (_c.statusBarElement["reader-setting.time".i18n]!.value) ...[
Text(
_c.currentTime.value,
style: const TextStyle(color: Colors.white, fontSize: 15),
),
const SizedBox(width: 8)
],
]));
}

_buildContent() {
late Color backgroundColor;
if (Platform.isAndroid) {
Expand Down
130 changes: 95 additions & 35 deletions lib/views/pages/watch/reader/comic/comic_reader_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import 'package:get/get.dart';
import 'package:miru_app/models/index.dart';
import 'package:miru_app/controllers/watch/comic_controller.dart';
import 'package:miru_app/utils/i18n.dart';
import 'package:miru_app/utils/miru_storage.dart';
import 'package:miru_app/views/widgets/platform_widget.dart';
import 'package:miru_app/views/widgets/settings/settings_switch_tile.dart';
import 'package:wakelock_plus/wakelock_plus.dart';

class ComicReaderSettings extends StatefulWidget {
const ComicReaderSettings(this.tag, {super.key});
Expand All @@ -20,43 +23,100 @@ class _ComicReaderSettingsState extends State<ComicReaderSettings> {
Widget _buildAndroid(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 阅读模式
Text('comic-settings.read-mode'.i18n),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: SegmentedButton(
segments: [
ButtonSegment<MangaReadMode>(
value: MangaReadMode.standard,
label: Text('comic-settings.standard'.i18n),
),
ButtonSegment<MangaReadMode>(
value: MangaReadMode.rightToLeft,
label: Text('comic-settings.right-to-left'.i18n),
child: Obx(() => Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 阅读模式

Text('comic-settings.read-mode'.i18n),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: SegmentedButton(
segments: [
ButtonSegment<MangaReadMode>(
value: MangaReadMode.standard,
label: Text('comic-settings.standard'.i18n),
),
ButtonSegment<MangaReadMode>(
value: MangaReadMode.rightToLeft,
label: Text('comic-settings.right-to-left'.i18n),
),
ButtonSegment<MangaReadMode>(
value: MangaReadMode.webTonn,
label: Text('comic-settings.web-tonn'.i18n),
),
],
selected: <MangaReadMode>{_c.readType.value},
onSelectionChanged: (value) {
if (value.isNotEmpty) {
_c.readType.value = value.first;
}
},
showSelectedIcon: false,
),
ButtonSegment<MangaReadMode>(
value: MangaReadMode.webTonn,
label: Text('comic-settings.web-tonn'.i18n),
),

const SizedBox(height: 16),
Text('comic-settings.indicator-alignment'.i18n),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: SegmentedButton(
segments: [
ButtonSegment<Alignment>(
value: Alignment.bottomLeft,
label: Text('comic-settings.bottomLeft'.i18n),
),
ButtonSegment<Alignment>(
value: Alignment.bottomRight,
label: Text('comic-settings.rightLeft'.i18n),
),
ButtonSegment<Alignment>(
value: Alignment.topLeft,
label: Text('comic-settings.topLeft'.i18n),
),
ButtonSegment<Alignment>(
value: Alignment.topRight,
label: Text('comic-settings.topRight'.i18n),
)
],
selected: <Alignment>{_c.alignMode.value},
onSelectionChanged: (value) {
if (value.isNotEmpty) {
_c.alignMode.value = value.first;
}
},
showSelectedIcon: false,
),
],
selected: <MangaReadMode>{_c.readType.value},
onSelectionChanged: (value) {
if (value.isNotEmpty) {
setState(() {
_c.readType.value = value.first;
});
}
},
showSelectedIcon: false,
),
),
],
),
),
const SizedBox(height: 16),
Text('comic-settings.status-bar'.i18n),
const SizedBox(height: 5),
Wrap(
spacing: 5,
children: _c.statusBarElement.keys
.map((e) => FilterChip(
label: Text(e),
selected: _c.statusBarElement[e]!.value,
onSelected: (val) {
_c.statusBarElement[e]!.value = val;
}))
.toList(),
),
SettingsSwitchTile(
icon: const Icon(Icons.coffee),
title: "reader-settings.enable-wakelock".i18n,
buildValue: () =>
MiruStorage.getSetting(SettingKey.enableWakelock),
onChanged: (val) {
WakelockPlus.toggle(enable: val);
MiruStorage.setSetting(SettingKey.enableWakelock, val);
}),
const SizedBox(height: 16),
],
)),
);
}

Expand Down
Loading

0 comments on commit 5bfbe6c

Please sign in to comment.