From bb4be5fef199d6509cd465d66c9e49550cb3864c Mon Sep 17 00:00:00 2001 From: appdevelpo <56633229+appdevelpo@users.noreply.github.com> Date: Sun, 11 Feb 2024 01:45:29 +0800 Subject: [PATCH] add color settings in mobile novel reader --- assets/i18n/en.json | 5 +- lib/controllers/watch/novel_controller.dart | 11 +++- lib/utils/miru_storage.dart | 4 +- .../reader/novel/novel_reader_content.dart | 9 ++- .../reader/novel/novel_reader_settings.dart | 66 ++++++++++++++++++- 5 files changed, 89 insertions(+), 6 deletions(-) diff --git a/assets/i18n/en.json b/assets/i18n/en.json index b405dfe6..4efac953 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -215,7 +215,10 @@ "tts-lang": "TTS Language", "tts-volume": "TTS Volume", "tts-pitch": "TTS Pitch", - "text-color": "Text Color" + "text-color": "Text Color", + "heighlight-color": "Highlight Color", + "heighlight-text-color": "Highlight Text Color", + "leading": "Leading" }, "bugreport": { "auto-remove-subtitle": "delete in ~ days", diff --git a/lib/controllers/watch/novel_controller.dart b/lib/controllers/watch/novel_controller.dart index f1e6ee8d..e410ff30 100644 --- a/lib/controllers/watch/novel_controller.dart +++ b/lib/controllers/watch/novel_controller.dart @@ -38,6 +38,10 @@ class NovelController extends ReaderController { late final RxList subtitles = List.generate(playList.length, (index) => "").obs; final Rx textColor = Colors.white.obs; + final Rx heighLightColor = Colors.blue.obs; + final Rx heighLightTextColor = Colors.white.obs; + final RxInt currentLine = 0.obs; + final RxDouble leading = 20.0.obs; initTts() { ttsVolume.value = MiruStorage.getSetting(SettingKey.ttsVolume); ttsRate.value = MiruStorage.getSetting(SettingKey.ttsRate); @@ -60,6 +64,7 @@ class NovelController extends ReaderController { WakelockPlus.toggle( enable: MiruStorage.getSetting(SettingKey.enableWakelock)); ttsLangValue.value = MiruStorage.getSetting(SettingKey.ttsLanguage); + leading.value = MiruStorage.getSetting(SettingKey.leading); ttsLang.value = await flutterTts.getLanguages; debugPrint(ttsLang.toString()); itemPositionsListener.itemPositions.addListener(() { @@ -122,10 +127,14 @@ class NovelController extends ReaderController { } final readingProgress = items[index.value][i]; debugPrint("current reading: $readingProgress , progress: $i"); - animeScrollTo(localToGloabalProgress(i) - 1); + animeScrollTo((localToGloabalProgress(i) - 2) > 0 + ? localToGloabalProgress(i) - 2 + : 0); + currentLine.value = i; await flutterTts.speak(items[index.value][i]); } enableAutoScroll.value = false; + currentLine.value = -1; }); ever(currentGlobalProgress, (callback) { if (updateSlider.value) { diff --git a/lib/utils/miru_storage.dart b/lib/utils/miru_storage.dart index baa2bad0..34b5e743 100644 --- a/lib/utils/miru_storage.dart +++ b/lib/utils/miru_storage.dart @@ -136,9 +136,10 @@ class MiruStorage { await _initSetting(SettingKey.autoScrollOffset, 20.0); await _initSetting( SettingKey.ttsLanguage, Platform.localeName.split('_')[0]); - await _initSetting(SettingKey.ttsPitch, 0.3); + await _initSetting(SettingKey.ttsPitch, 1.0); await _initSetting(SettingKey.ttsRate, 0.3); await _initSetting(SettingKey.ttsVolume, 0.5); + await _initSetting(SettingKey.leading, 20.0); } static _initSetting(String key, dynamic value) async { @@ -207,4 +208,5 @@ class SettingKey { static String ttsPitch = "TTSPitch"; static String ttsRate = "TTSRate"; static String ttsVolume = "TTSVolume"; + static String leading = "Leading"; } diff --git a/lib/views/pages/watch/reader/novel/novel_reader_content.dart b/lib/views/pages/watch/reader/novel/novel_reader_content.dart index dabb1b15..60bd57a2 100644 --- a/lib/views/pages/watch/reader/novel/novel_reader_content.dart +++ b/lib/views/pages/watch/reader/novel/novel_reader_content.dart @@ -186,7 +186,7 @@ class _NovelReaderContentState extends State { Widget _textContent(int index, double fontSize) { final content = _c.items.expand((element) => element).toList(); return Obx(() => Padding( - padding: const EdgeInsets.only(bottom: 20), + padding: EdgeInsets.only(bottom: _c.leading.value), child: SelectableText.rich( onTap: () { _c.setControllPanel.value = !_c.setControllPanel.value; @@ -197,9 +197,14 @@ class _NovelReaderContentState extends State { TextSpan( text: content[index], style: TextStyle( - color: _c.textColor.value, + color: index == _c.currentLine.value + ? _c.heighLightTextColor.value + : _c.textColor.value, fontSize: fontSize, fontWeight: FontWeight.w400, + backgroundColor: index == _c.currentLine.value + ? _c.heighLightColor.value + : null, height: 2, textBaseline: TextBaseline.ideographic, fontFamily: 'Microsoft Yahei', diff --git a/lib/views/pages/watch/reader/novel/novel_reader_settings.dart b/lib/views/pages/watch/reader/novel/novel_reader_settings.dart index 45f28dbd..240783f3 100644 --- a/lib/views/pages/watch/reader/novel/novel_reader_settings.dart +++ b/lib/views/pages/watch/reader/novel/novel_reader_settings.dart @@ -122,7 +122,23 @@ class _NovelReaderSettingsState extends State { divisions: 24, min: 12, max: 24, - )) + )), + const SizedBox(height: 16), + Text("novel-settings.leading".i18n), + const SizedBox(height: 5), + SizedBox( + width: double.infinity, + child: Slider( + value: _c.leading.value, + onChanged: (value) { + _c.leading.value = value; + }, + label: _c.leading.value.toString(), + divisions: 40, + min: 0, + max: 40, + ), + ), ], )), ), @@ -255,6 +271,54 @@ class _NovelReaderSettingsState extends State { selected: ColorUtils.baseColors[index] == _c.textColor.value)), ), + const SizedBox(height: 16), + Text("novel-settings.heighlight-color".i18n), + const SizedBox(height: 5), + Wrap( + spacing: 5, + children: List.generate( + ColorUtils.baseColors.length, + (index) => ChoiceChip( + onSelected: (val) { + if (val) { + _c.heighLightColor.value = + ColorUtils.baseColors[index]; + } + }, + label: Container( + width: 20, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: ColorUtils.baseColors[index], + ), + ), + selected: ColorUtils.baseColors[index] == + _c.heighLightColor.value)), + ), + const SizedBox(height: 16), + Text("novel-settings.heighlight-text-color".i18n), + const SizedBox(height: 5), + Wrap( + spacing: 5, + children: List.generate( + ColorUtils.baseColors.length, + (index) => ChoiceChip( + onSelected: (val) { + if (val) { + _c.heighLightTextColor.value = + ColorUtils.baseColors[index]; + } + }, + label: Container( + width: 20, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: ColorUtils.baseColors[index], + ), + ), + selected: ColorUtils.baseColors[index] == + _c.heighLightTextColor.value)), + ), ], )), )