diff --git a/android/app/build.gradle b/android/app/build.gradle index 7db6764..af5585b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -47,6 +47,9 @@ android { // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } + debug { + applicationIdSuffix ".debug" + } } } diff --git a/ci/version.code.txt b/ci/version.code.txt index 0d687f1..1de48e4 100644 --- a/ci/version.code.txt +++ b/ci/version.code.txt @@ -1 +1 @@ -v1.7.3 \ No newline at end of file +v1.7.4 \ No newline at end of file diff --git a/ci/version.info.txt b/ci/version.info.txt index 0fcc057..4b2eb26 100644 --- a/ci/version.info.txt +++ b/ci/version.info.txt @@ -1,4 +1,3 @@ -v1.7.3 -- [x] ✨ 可以隐藏发电图标(设置项) -- [x] ✨ 可以给阅读器加灰度滤镜(设置项)(彩色墨水屏下或许有用) -- [x] ✨ 可以选择阅读器背景色(设置项)(白色可防止墨水屏下拖影) +v1.7.4 +- [x] ♻️ 优化发电 +- [x] ♻️ 优化设置 diff --git a/lib/basic/config/CategoriesColumnCount.dart b/lib/basic/config/CategoriesColumnCount.dart index ebc2bba..7b60c02 100644 --- a/lib/basic/config/CategoriesColumnCount.dart +++ b/lib/basic/config/CategoriesColumnCount.dart @@ -20,9 +20,10 @@ Widget categoriesColumnCountSetting() { builder: (BuildContext context, void Function(void Function()) setState) { return ListTile( title: const Text( - "首页分类列数", + "首页分类展示列数", ), - subtitle: Text("$categoriesColumnCount"), + subtitle: + Text(categoriesColumnCount == 0 ? "自动" : "$categoriesColumnCount"), onTap: () async { int? value = await chooseMapDialog( context, @@ -33,7 +34,7 @@ Widget categoriesColumnCountSetting() { "4": 4, "5": 5, }, - "选择首页分类列数"); + "选择首页分类展示列数"); if (value != null) { await method.saveProperty(_propertyName, "$value"); categoriesColumnCount = value; diff --git a/lib/basic/config/EBookScrolling.dart b/lib/basic/config/EBookScrolling.dart new file mode 100644 index 0000000..738571a --- /dev/null +++ b/lib/basic/config/EBookScrolling.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import '../Method.dart'; + +const _propertyName = "eBookScrolling"; + +late bool _eBookScrolling; + +bool get eBookScrolling => _eBookScrolling; + +Future initEBookScrolling() async { + _eBookScrolling = (await method.loadProperty(_propertyName, "false")) == "true"; +} + +Widget eBookScrollingSetting() { + return StatefulBuilder( + builder: (BuildContext context, void Function(void Function()) setState) { + return SwitchListTile( + title: const Text("电子书模式滚动UI"), + value: _eBookScrolling, + onChanged: (value) async { + await method.saveProperty(_propertyName, "$value"); + _eBookScrolling = value; + setState(() {}); + }, + ); + }, + ); +} diff --git a/lib/basic/config/EBookScrollingRange.dart b/lib/basic/config/EBookScrollingRange.dart new file mode 100644 index 0000000..2217de1 --- /dev/null +++ b/lib/basic/config/EBookScrollingRange.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; + +import '../Method.dart'; + +const _propertyName = "eBookScrollingRange"; + +late int _eBookScrollingRange; + +Future initEBookScrollingRange() async { + _eBookScrollingRange = + int.parse((await method.loadProperty(_propertyName, "80"))); +} + +double get eBookScrollingRange => _eBookScrollingRange / 100; + +Widget eBookScrollingRangeSetting() { + return StatefulBuilder( + builder: (BuildContext context, void Function(void Function()) setState) { + return ListTile( + title: Text("电子书模式滚动UI - 滚动幅度 : $_eBookScrollingRange%屏幕高度"), + subtitle: Slider( + min: 30.toDouble(), + max: 80.toDouble(), + value: _eBookScrollingRange.toDouble(), + onChanged: (double value) async { + final va = value.toInt(); + await method.loadProperty(_propertyName, "$va"); + setState(() { + _eBookScrollingRange = va; + }); + }, + divisions: (80 - 30), + ), + ); + }, + ); +} diff --git a/lib/basic/config/EBookScrollingTrigger.dart b/lib/basic/config/EBookScrollingTrigger.dart new file mode 100644 index 0000000..5ddd617 --- /dev/null +++ b/lib/basic/config/EBookScrollingTrigger.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +import '../Method.dart'; + +const _propertyName = "eBookScrollingTrigger"; + +late double _eBookScrollingTrigger; + +Future initEBookScrollingTrigger() async { + _eBookScrollingTrigger = + double.parse((await method.loadProperty(_propertyName, "0.3"))); +} + +double get eBookScrollingTrigger => _eBookScrollingTrigger; + +Widget eBookScrollingTriggerSetting() { + return StatefulBuilder( + builder: (BuildContext context, void Function(void Function()) setState) { + return ListTile( + title: Text("电子书模式滚动UI - 触发距离 : $_eBookScrollingTrigger 厘米"), + subtitle: Slider( + min: 0.1.toDouble(), + max: 2.0.toDouble(), + value: _eBookScrollingTrigger.toDouble(), + onChanged: (double value) async { + await method.saveProperty(_propertyName, "$value"); + setState((){ + _eBookScrollingTrigger = value; + }); + }, + divisions: (20 - 1), + ), + ); + }, + ); +} diff --git a/lib/basic/config/HiddenFdIcon.dart b/lib/basic/config/HiddenFdIcon.dart index 7324bbb..6cdd82b 100644 --- a/lib/basic/config/HiddenFdIcon.dart +++ b/lib/basic/config/HiddenFdIcon.dart @@ -19,7 +19,6 @@ Widget hiddenFdIconSetting() { builder: (BuildContext context, void Function(void Function()) setState) { return SwitchListTile( title: const Text("隐藏个人空间的发电图标"), - subtitle: Text(_hiddenFdIcon ? "是" : "否"), value: _hiddenFdIcon, onChanged: (value) async { await method.saveProperty(_propertyName, "$value"); diff --git a/lib/basic/config/IconLoading.dart b/lib/basic/config/IconLoading.dart index 654189e..abc51be 100644 --- a/lib/basic/config/IconLoading.dart +++ b/lib/basic/config/IconLoading.dart @@ -31,7 +31,6 @@ Widget iconLoadingSetting() { builder: (BuildContext context, void Function(void Function()) setState) { return ListTile( title: const Text("尽量减少UI动画"), - subtitle: Text(_iconLoading ? "是" : "否"), onTap: () async { await _chooseIconLoading(context); setState(() {}); diff --git a/lib/basic/config/UsingRightClickPop.dart b/lib/basic/config/UsingRightClickPop.dart index ccfc0ea..dd0b85a 100644 --- a/lib/basic/config/UsingRightClickPop.dart +++ b/lib/basic/config/UsingRightClickPop.dart @@ -19,29 +19,20 @@ bool currentUsingRightClickPop() { return _usingRightClickPop; } -Future _chooseUsingRightClickPop(BuildContext context) async { - String? result = - await chooseListDialog(context, "鼠标右键返回上一页", ["是", "否"]); - if (result != null) { - var target = result == "是"; - await method.saveProperty(_propertyName, "$target"); - _usingRightClickPop = target; - } -} - Widget usingRightClickPopSetting() { if (!(Platform.isWindows || Platform.isMacOS || Platform.isLinux)) { return Container(); } return StatefulBuilder( builder: (BuildContext context, void Function(void Function()) setState) { - return ListTile( + return SwitchListTile( title: const Text("鼠标右键返回上一页"), - subtitle: Text(_usingRightClickPop ? "是" : "否"), - onTap: () async { - await _chooseUsingRightClickPop(context); + onChanged: (value) async { + await method.saveProperty(_propertyName, "${value ? "是" : "否"}"); + _usingRightClickPop = value; setState(() {}); }, + value: _usingRightClickPop, ); }, ); diff --git a/lib/basic/config/WillPopNotice.dart b/lib/basic/config/WillPopNotice.dart index 2f453fd..69c9b0a 100644 --- a/lib/basic/config/WillPopNotice.dart +++ b/lib/basic/config/WillPopNotice.dart @@ -17,8 +17,7 @@ Widget willPopNoticeSetting() { return StatefulBuilder( builder: (BuildContext context, void Function(void Function()) setState) { return SwitchListTile( - title: const Text("退出APP的提示"), - subtitle: Text(_willPopNotice ? "是" : "否"), + title: const Text("在首页连续按两下返回键才能退出APP"), value: _willPopNotice, onChanged: (value) async { await method.saveProperty(_propertyName, "$value"); diff --git a/lib/screens/AboutScreen.dart b/lib/screens/AboutScreen.dart index 0f06061..ffc5dd2 100644 --- a/lib/screens/AboutScreen.dart +++ b/lib/screens/AboutScreen.dart @@ -5,6 +5,7 @@ import 'package:pikapika/basic/Cross.dart'; import 'package:pikapika/basic/config/Version.dart'; import 'package:pikapika/screens/components/Badge.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; const _releasesUrl = "https://github.com/niuhuan/pikapika/releases"; @@ -54,7 +55,7 @@ class _AboutScreenState extends State { appBar: AppBar( title: const Text('关于'), ), - body: ListView( + body: PikaListView( children: [ SizedBox( width: min / 2, diff --git a/lib/screens/AccountScreen.dart b/lib/screens/AccountScreen.dart index 3734998..531cc53 100644 --- a/lib/screens/AccountScreen.dart +++ b/lib/screens/AccountScreen.dart @@ -15,6 +15,7 @@ import 'AppScreen.dart'; import 'DownloadListScreen.dart'; import 'ForgotPasswordScreen.dart'; import 'components/ContentLoading.dart'; +import 'components/ListView.dart'; // 账户设置 class AccountScreen extends StatefulWidget { @@ -102,7 +103,7 @@ class _AccountScreenState extends State { ), ], ), - body: ListView( + body: PikaListView( children: [ ListTile( title: const Text("账号"), diff --git a/lib/screens/CategoriesScreen.dart b/lib/screens/CategoriesScreen.dart index b3ffdab..b08e77f 100644 --- a/lib/screens/CategoriesScreen.dart +++ b/lib/screens/CategoriesScreen.dart @@ -20,6 +20,7 @@ import 'RandomComicsScreen.dart'; import 'components/Common.dart'; import 'components/ContentLoading.dart'; import 'components/Images.dart'; +import 'components/ListView.dart'; // 分类 class CategoriesScreen extends StatefulWidget { @@ -127,7 +128,7 @@ class _CategoriesScreenState extends State { if (snapshot.connectionState != ConnectionState.done) { return const ContentLoading(label: '加载中'); } - return ListView( + return PikaListView( children: [ Container(height: 20), Wrap( diff --git a/lib/screens/ComicInfoScreen.dart b/lib/screens/ComicInfoScreen.dart index e2edcdd..aaa9771 100644 --- a/lib/screens/ComicInfoScreen.dart +++ b/lib/screens/ComicInfoScreen.dart @@ -21,6 +21,7 @@ import 'components/CommentList.dart'; import 'components/ContentError.dart'; import 'components/ContentLoading.dart'; import 'components/ContinueReadButton.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 漫画详情 @@ -146,7 +147,7 @@ class _ComicInfoScreenState extends State with RouteAware { _buildDownloadAction(_epListFuture, _comicInfo), ], ), - body: ListView( + body: PikaListView( children: [ ComicInfoCard(_comicInfo, linkItem: true), ComicTagsCard(_comicInfo.tags), diff --git a/lib/screens/CommentScreen.dart b/lib/screens/CommentScreen.dart index c68ef4f..47ad259 100644 --- a/lib/screens/CommentScreen.dart +++ b/lib/screens/CommentScreen.dart @@ -7,6 +7,7 @@ import 'package:pikapika/screens/components/CommentItem.dart'; import 'package:pikapika/screens/components/CommentMainType.dart'; import 'package:pikapika/screens/components/ContentBuilder.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; class _CommentChildPage extends e.Page { @@ -67,7 +68,7 @@ class _CommentScreenState extends State { successBuilder: (BuildContext context, AsyncSnapshot<_CommentChildPage> snapshot) { var page = snapshot.data!; - return ListView( + return PikaListView( children: [ _buildPrePage(page), ...page.docs.map((e) => _buildComment(e)), diff --git a/lib/screens/DownloadConfirmScreen.dart b/lib/screens/DownloadConfirmScreen.dart index aea3ee8..e46ef0d 100644 --- a/lib/screens/DownloadConfirmScreen.dart +++ b/lib/screens/DownloadConfirmScreen.dart @@ -7,6 +7,7 @@ import 'package:pikapika/screens/components/ContentLoading.dart'; import 'package:pikapika/basic/Method.dart'; import 'components/ComicInfoCard.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 确认下载 @@ -128,7 +129,7 @@ class _DownloadConfirmScreenState extends State { if (snapshot.connectionState != ConnectionState.done) { return const ContentLoading(label: '加载中'); } - return ListView( + return PikaListView( children: [ ComicInfoCard(widget.comicInfo), _buildButtons(), diff --git a/lib/screens/DownloadExportGroupScreen.dart b/lib/screens/DownloadExportGroupScreen.dart index 931dfbd..c18d758 100644 --- a/lib/screens/DownloadExportGroupScreen.dart +++ b/lib/screens/DownloadExportGroupScreen.dart @@ -7,6 +7,7 @@ import '../basic/config/IconLoading.dart'; import 'DownloadExportingGroupScreen.dart'; import 'components/ContentLoading.dart'; import 'components/DownloadInfoCard.dart'; +import 'components/ListView.dart'; class DownloadExportGroupScreen extends StatefulWidget { const DownloadExportGroupScreen({Key? key}) : super(key: key); @@ -72,7 +73,7 @@ class _DownloadExportGroupScreenState extends State { _f = method.allDownloads(""); }); }, - child: ListView( + child: PikaListView( children: ws, ), ), diff --git a/lib/screens/DownloadExportToFileScreen.dart b/lib/screens/DownloadExportToFileScreen.dart index 8387072..06b1c85 100644 --- a/lib/screens/DownloadExportToFileScreen.dart +++ b/lib/screens/DownloadExportToFileScreen.dart @@ -12,6 +12,7 @@ import '../basic/config/IsPro.dart'; import 'components/ContentError.dart'; import 'components/ContentLoading.dart'; import 'components/DownloadInfoCard.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 导出 @@ -94,7 +95,7 @@ class _DownloadExportToFileScreenState if (snapshot.connectionState != ConnectionState.done) { return const ContentLoading(label: '加载中'); } - return ListView( + return PikaListView( children: [ DownloadInfoCard(task: _task), Container( diff --git a/lib/screens/DownloadExportToSocketScreen.dart b/lib/screens/DownloadExportToSocketScreen.dart index f20940b..32b5921 100644 --- a/lib/screens/DownloadExportToSocketScreen.dart +++ b/lib/screens/DownloadExportToSocketScreen.dart @@ -8,6 +8,7 @@ import 'package:pikapika/basic/Method.dart'; import 'components/ContentError.dart'; import 'components/ContentLoading.dart'; import 'components/DownloadInfoCard.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 传输到其他设备 @@ -85,7 +86,7 @@ class _DownloadExportToSocketScreenState if (snapshot.connectionState != ConnectionState.done) { return const ContentLoading(label: '加载中'); } - return ListView( + return PikaListView( children: [ DownloadInfoCard(task: widget.task), Container( diff --git a/lib/screens/DownloadExportingGroupScreen.dart b/lib/screens/DownloadExportingGroupScreen.dart index 1ec68bf..61c6a56 100644 --- a/lib/screens/DownloadExportingGroupScreen.dart +++ b/lib/screens/DownloadExportingGroupScreen.dart @@ -1,15 +1,12 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:pikapika/basic/Common.dart'; - import '../basic/Channels.dart'; -import '../basic/Cross.dart'; import '../basic/Method.dart'; import '../basic/config/ExportPath.dart'; import '../basic/config/ExportRename.dart'; import '../basic/config/IsPro.dart'; import 'components/ContentLoading.dart'; +import 'components/ListView.dart'; class DownloadExportingGroupScreen extends StatefulWidget { final List idList; @@ -57,7 +54,7 @@ class _DownloadExportingGroupScreenState if (exported) { return const Center(child: Text("导出成功")); } - return ListView( + return PikaListView( children: [ Container(height: 20), displayExportPathInfo(), diff --git a/lib/screens/DownloadImportScreen.dart b/lib/screens/DownloadImportScreen.dart index 2209a15..200a8af 100644 --- a/lib/screens/DownloadImportScreen.dart +++ b/lib/screens/DownloadImportScreen.dart @@ -14,6 +14,7 @@ import '../basic/config/ImportNotice.dart'; import '../basic/config/IsPro.dart'; import 'PkzArchiveScreen.dart'; import 'components/ContentLoading.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 导入 @@ -68,7 +69,7 @@ class _DownloadImportScreenState extends State { appBar: AppBar( title: const Text('导入'), ), - body: ListView( + body: PikaListView( children: [ Container( padding: const EdgeInsets.all(10), diff --git a/lib/screens/DownloadInfoScreen.dart b/lib/screens/DownloadInfoScreen.dart index a8b8992..16b3301 100644 --- a/lib/screens/DownloadInfoScreen.dart +++ b/lib/screens/DownloadInfoScreen.dart @@ -17,6 +17,7 @@ import 'components/ContentError.dart'; import 'components/ContentLoading.dart'; import 'components/ContinueReadButton.dart'; import 'components/DownloadInfoCard.dart'; +import 'components/ListView.dart'; import 'components/Recommendation.dart'; // 下载详情 @@ -122,7 +123,7 @@ class _DownloadInfoScreenState extends State } List tagsDynamic = json.decode(_task.tags); List tags = tagsDynamic.map((e) => "$e").toList(); - var list = ListView( + var list = PikaListView( children: [ DownloadInfoCard(task: _task, linkItem: true), ComicTagsCard(tags), diff --git a/lib/screens/DownloadListScreen.dart b/lib/screens/DownloadListScreen.dart index acbb1b8..7fbc63d 100644 --- a/lib/screens/DownloadListScreen.dart +++ b/lib/screens/DownloadListScreen.dart @@ -13,6 +13,7 @@ import 'DownloadImportScreen.dart'; import 'DownloadInfoScreen.dart'; import 'components/ContentLoading.dart'; import 'components/DownloadInfoCard.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 下载列表 @@ -118,7 +119,7 @@ class _DownloadListScreenState extends State { _f = method.allDownloads(_search); }); }, - child: ListView( + child: PikaListView( children: [ ...data.map(downloadWidget), ], diff --git a/lib/screens/ForgotPasswordScreen.dart b/lib/screens/ForgotPasswordScreen.dart index f4329cd..0934f9b 100644 --- a/lib/screens/ForgotPasswordScreen.dart +++ b/lib/screens/ForgotPasswordScreen.dart @@ -4,6 +4,7 @@ import '../basic/Common.dart'; import '../basic/Cross.dart'; import '../basic/Method.dart'; import 'components/ContentLoading.dart'; +import 'components/ListView.dart'; class ForgotPasswordScreen extends StatefulWidget { const ForgotPasswordScreen({Key? key}) : super(key: key); @@ -50,7 +51,7 @@ class _ForgotPasswordScreenState extends State { } Widget _inputEmailScreen() { - return ListView(children: [ + return PikaListView(children: [ ListTile( title: const Text("账号"), subtitle: Text(_email == "" ? "未设置" : _email), diff --git a/lib/screens/GameDownloadScreen.dart b/lib/screens/GameDownloadScreen.dart index 64afb16..f371cec 100644 --- a/lib/screens/GameDownloadScreen.dart +++ b/lib/screens/GameDownloadScreen.dart @@ -5,6 +5,7 @@ import 'package:pikapika/basic/Method.dart'; import 'package:pikapika/screens/components/ItemBuilder.dart'; import 'components/GameTitleCard.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 游戏下载地址列表页 @@ -35,7 +36,7 @@ class _GameDownloadScreenState extends State { appBar: AppBar( title: Text("下载 - ${widget.info.title}"), ), - body: ListView( + body: PikaListView( children: [ GameTitleCard(widget.info), ItemBuilder( diff --git a/lib/screens/GamesScreen.dart b/lib/screens/GamesScreen.dart index 660d8fc..21a78f7 100644 --- a/lib/screens/GamesScreen.dart +++ b/lib/screens/GamesScreen.dart @@ -7,6 +7,7 @@ import 'package:pikapika/screens/components/ContentBuilder.dart'; import '../basic/config/IconLoading.dart'; import 'GameInfoScreen.dart'; import 'components/Images.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 游戏列表 @@ -171,7 +172,7 @@ class _GamesScreenState extends State { ), ), ), - body: ListView( + body: PikaListView( children: [ ...wraps, ...page.page < page.pages diff --git a/lib/screens/ImportFromOffScreen.dart b/lib/screens/ImportFromOffScreen.dart index 3c3472c..b2c87ba 100644 --- a/lib/screens/ImportFromOffScreen.dart +++ b/lib/screens/ImportFromOffScreen.dart @@ -3,6 +3,7 @@ import 'package:pikapika/basic/Method.dart'; import '../basic/Channels.dart'; import 'components/ContentLoading.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; class ImportFromOffScreen extends StatefulWidget { @@ -58,7 +59,7 @@ class _ImportFromOffScreenState extends State { appBar: AppBar( title: const Text('导入'), ), - body: ListView( + body: PikaListView( children: [ Container( padding: const EdgeInsets.all(10), diff --git a/lib/screens/InitScreen.dart b/lib/screens/InitScreen.dart index 058e62e..4875caa 100644 --- a/lib/screens/InitScreen.dart +++ b/lib/screens/InitScreen.dart @@ -13,6 +13,9 @@ import 'package:pikapika/basic/config/ChooserRoot.dart'; import 'package:pikapika/basic/config/ContentFailedReloadAction.dart'; import 'package:pikapika/basic/config/DownloadAndExportPath.dart'; import 'package:pikapika/basic/config/DownloadThreadCount.dart'; +import 'package:pikapika/basic/config/EBookScrolling.dart'; +import 'package:pikapika/basic/config/EBookScrollingRange.dart'; +import 'package:pikapika/basic/config/EBookScrollingTrigger.dart'; import 'package:pikapika/basic/config/FullScreenAction.dart'; import 'package:pikapika/basic/config/FullScreenUI.dart'; import 'package:pikapika/basic/config/ImageAddress.dart'; @@ -119,6 +122,9 @@ class _InitScreenState extends State { await initWebDav(); await initImageFilter(); await initReaderBackgroundColor(); + await initEBookScrolling(); + await initEBookScrollingRange(); + await initEBookScrollingTrigger(); String? initUrl; if (Platform.isAndroid || Platform.isIOS) { diff --git a/lib/screens/MigrateScreen.dart b/lib/screens/MigrateScreen.dart index 965a83d..4d02978 100644 --- a/lib/screens/MigrateScreen.dart +++ b/lib/screens/MigrateScreen.dart @@ -6,6 +6,7 @@ import 'package:pikapika/basic/Method.dart'; import 'package:pikapika/screens/components/ContentBuilder.dart'; import 'package:pikapika/screens/components/ContentLoading.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; // 数据迁移页面 @@ -55,7 +56,7 @@ class _MigrateScreenState extends State { (BuildContext context, AsyncSnapshot snapshot) { switch (_migrate) { case 0: - return ListView( + return PikaListView( children: [ Container( padding: const EdgeInsets.all(10), diff --git a/lib/screens/ModifyPasswordScreen.dart b/lib/screens/ModifyPasswordScreen.dart index dd1a980..c2ace9e 100644 --- a/lib/screens/ModifyPasswordScreen.dart +++ b/lib/screens/ModifyPasswordScreen.dart @@ -3,6 +3,7 @@ import 'package:pikapika/basic/Method.dart'; import 'package:pikapika/screens/components/ContentLoading.dart'; import '../basic/Common.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; class ModifyPasswordScreen extends StatefulWidget { @@ -49,7 +50,7 @@ class _ModifyPasswordScreenState extends State { } Widget _buildForm() { - return ListView( + return PikaListView( children: [ const Divider(), ListTile( diff --git a/lib/screens/NetworkSettingsScreen.dart b/lib/screens/NetworkSettingsScreen.dart index b2a1c08..812ceca 100644 --- a/lib/screens/NetworkSettingsScreen.dart +++ b/lib/screens/NetworkSettingsScreen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:pikapika/screens/components/NetworkSetting.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; class NetworkSettingsScreen extends StatelessWidget { @@ -17,7 +18,7 @@ class NetworkSettingsScreen extends StatelessWidget { Widget buildScreen(BuildContext context) => Scaffold( appBar: AppBar(title: const Text('网络设置')), - body: ListView( + body: PikaListView( children: const [ NetworkSetting(), ], diff --git a/lib/screens/PkzArchiveScreen.dart b/lib/screens/PkzArchiveScreen.dart index c0a31ff..e1659d6 100644 --- a/lib/screens/PkzArchiveScreen.dart +++ b/lib/screens/PkzArchiveScreen.dart @@ -16,6 +16,7 @@ import '../basic/Navigator.dart'; import '../basic/config/IconLoading.dart'; import '../basic/config/Platform.dart'; import 'PkzComicInfoScreen.dart'; +import 'components/ListView.dart'; class PkzArchiveScreen extends StatefulWidget { final bool holdPkz; @@ -122,7 +123,7 @@ class _PkzArchiveScreenState extends State with RouteAware { BuildContext context, AsyncSnapshot snapshot, ) { - return ListView(children: [ + return PikaListView(children: [ ..._info.comics .map((e) => GestureDetector( behavior: HitTestBehavior.opaque, diff --git a/lib/screens/PkzComicInfoScreen.dart b/lib/screens/PkzComicInfoScreen.dart index b8c99b6..49e6f7a 100644 --- a/lib/screens/PkzComicInfoScreen.dart +++ b/lib/screens/PkzComicInfoScreen.dart @@ -1,18 +1,15 @@ import 'dart:async'; -import 'dart:io'; import 'package:flutter/material.dart'; import 'package:path/path.dart' as p; import 'package:pikapika/basic/Entities.dart'; import 'package:pikapika/basic/Method.dart'; import 'package:pikapika/screens/PkzReaderScreen.dart'; -import 'package:uni_links/uni_links.dart'; -import 'package:uri_to_file/uri_to_file.dart'; import '../basic/Common.dart'; import '../basic/Navigator.dart'; import '../basic/config/IconLoading.dart'; -import 'PkzArchiveScreen.dart'; +import 'components/ListView.dart'; import 'components/PkzComicInfoCard.dart'; class PkzComicInfoScreen extends StatefulWidget { @@ -116,7 +113,7 @@ class _PkzComicInfoScreenState extends State widget.pkzComic.title, ), ), - body: ListView(children: [ + body: PikaListView(children: [ PkzComicInfoCard(info: widget.pkzComic, pkzPath: widget.pkzPath), Container( padding: const EdgeInsets.only(top: 5, bottom: 5), diff --git a/lib/screens/ProScreen.dart b/lib/screens/ProScreen.dart index faaf598..878fe4d 100644 --- a/lib/screens/ProScreen.dart +++ b/lib/screens/ProScreen.dart @@ -8,6 +8,7 @@ import 'package:pikapika/screens/AccessKeyReplaceScreen.dart'; import '../basic/config/IconLoading.dart'; import '../basic/config/IsPro.dart'; +import 'components/ListView.dart'; class ProScreen extends StatefulWidget { const ProScreen({Key? key}) : super(key: key); @@ -48,7 +49,7 @@ class _ProScreenState extends State { appBar: AppBar( title: const Text("发电中心"), ), - body: ListView( + body: PikaListView( children: [ SizedBox( width: min / 2, @@ -100,13 +101,16 @@ class _ProScreenState extends State { ListTile( title: const Text("我刚才发了电"), onTap: () async { - final code = await inputString(context, "输入代码"); - if (code != null && code.isNotEmpty) { - try { - await method.inputCdKey(code); - defaultToast(context, "SUCCESS"); - } catch (e, s) { - defaultToast(context, "FAIL"); + var code = await inputString(context, "输入代码"); + if (code != null) { + code = code.trim(); + if (code.isNotEmpty) { + try { + await method.inputCdKey(code); + defaultToast(context, "SUCCESS"); + } catch (e, s) { + defaultToast(context, "FAIL"); + } } } await reloadIsPro(); diff --git a/lib/screens/RegisterScreen.dart b/lib/screens/RegisterScreen.dart index 2b0e6d5..54ff0a1 100644 --- a/lib/screens/RegisterScreen.dart +++ b/lib/screens/RegisterScreen.dart @@ -6,6 +6,7 @@ import 'package:pikapika/screens/components/NetworkSetting.dart'; import 'package:pikapika/screens/components/RightClickPop.dart'; import 'components/ContentLoading.dart'; +import 'components/ListView.dart'; /// 注册页面 class RegisterScreen extends StatefulWidget { @@ -133,7 +134,7 @@ class _RegisterScreenState extends State { ), ], ), - body: ListView( + body: PikaListView( children: [ const Divider(), ListTile( diff --git a/lib/screens/SettingsScreen.dart b/lib/screens/SettingsScreen.dart index 1bc5e1d..94a5bb2 100644 --- a/lib/screens/SettingsScreen.dart +++ b/lib/screens/SettingsScreen.dart @@ -10,6 +10,8 @@ import 'package:pikapika/basic/config/ChooserRoot.dart'; import 'package:pikapika/basic/config/ContentFailedReloadAction.dart'; import 'package:pikapika/basic/config/DownloadAndExportPath.dart'; import 'package:pikapika/basic/config/DownloadThreadCount.dart'; +import 'package:pikapika/basic/config/EBookScrollingRange.dart'; +import 'package:pikapika/basic/config/EBookScrollingTrigger.dart'; import 'package:pikapika/basic/config/ExportRename.dart'; import 'package:pikapika/basic/config/FullScreenAction.dart'; import 'package:pikapika/basic/config/FullScreenUI.dart'; @@ -24,17 +26,18 @@ import 'package:pikapika/basic/config/ReaderDirection.dart'; import 'package:pikapika/basic/config/ReaderSliderPosition.dart'; import 'package:pikapika/basic/config/ReaderType.dart'; import 'package:pikapika/basic/config/ShadowCategories.dart'; +import 'package:pikapika/basic/config/ShadowCategoriesMode.dart'; import 'package:pikapika/basic/config/ShowCommentAtDownload.dart'; import 'package:pikapika/basic/config/Themes.dart'; import 'package:pikapika/basic/config/TimeOffsetHour.dart'; import 'package:pikapika/basic/config/VolumeController.dart'; -import 'package:pikapika/basic/config/ShadowCategoriesMode.dart'; import 'package:pikapika/screens/components/NetworkSetting.dart'; import 'package:pikapika/screens/components/RightClickPop.dart'; import '../basic/config/Authentication.dart'; import '../basic/config/CategoriesColumnCount.dart'; import '../basic/config/DownloadCachePath.dart'; +import '../basic/config/EBookScrolling.dart'; import '../basic/config/HiddenFdIcon.dart'; import '../basic/config/ImageFilter.dart'; import '../basic/config/UsingRightClickPop.dart'; @@ -66,175 +69,158 @@ class _SettingsScreenState extends State { ); } - late var _index = 0; - Widget buildScreen(BuildContext context) { - final List<_IconAndWidgets> iaws = [ - _IconAndWidgets(Icons.lan, [ - const Padding(padding: EdgeInsets.only(top: 15)), - const Divider(), - const ListTile( - subtitle: Text("网络&账户"), - ), - const Divider(), - widget.hiddenAccountInfo - ? Container() - : ListTile( - onTap: () async { - Navigator.push( - context, - mixRoute( - builder: (context) => const ModifyPasswordScreen(), - ), - ); - }, - title: const Text('修改密码'), - ), - const Divider(), - const NetworkSetting(), - const Padding(padding: EdgeInsets.only(top: 15)), - const Divider(), - const ListTile( - subtitle: Text("同步"), - ), - ...webDavSettings(context), - const Divider(), - const Padding(padding: EdgeInsets.only(top: 15)), - ]), - _IconAndWidgets(Icons.ad_units, [ - const Padding(padding: EdgeInsets.only(top: 15)), - const Divider(), - const ListTile( - subtitle: Text("系统&界面"), - ), - const Divider(), - ListTile( - onTap: () async { - if (androidNightModeDisplay) { - Navigator.push( - context, - mixRoute(builder: (context) => const ThemeScreen()), - ); - } else { - chooseLightTheme(context); - } - }, - title: const Text('主题'), - ), - fullScreenUISetting(), - noAnimationSetting(), - iconLoadingSetting(), - categoriesColumnCountSetting(), - willPopNoticeSetting(), - hiddenFdIconSetting(), - pagerActionSetting(), - contentFailedReloadActionSetting(), - timeZoneSetting(), - fontSetting(), - usingRightClickPopSetting(), - const Divider(), - androidDisplayModeSetting(), - androidSecureFlagSetting(), - authenticationSetting(), - const Divider(), - migrate(context), - const Divider(), - const Padding(padding: EdgeInsets.only(top: 15)), - ]), - _IconAndWidgets(Icons.confirmation_num_rounded, [ - const Divider(), - const Padding(padding: EdgeInsets.only(top: 15)), - const Divider(), - const ListTile( - subtitle: Text("内容&阅读器"), - ), - const Divider(), - shadowCategoriesModeSetting(), - shadowCategoriesSetting(), - const Divider(), - qualitySetting(), - readerTypeSetting(), - readerDirectionSetting(), - readerSliderPositionSetting(), - autoFullScreenSetting(), - fullScreenActionSetting(), - volumeControllerSetting(), - keyboardControllerSetting(), - const Divider(), - imageFilterSetting(), - readerBackgroundColorSetting(), - const Divider(), - const Padding(padding: EdgeInsets.only(top: 15)), - ]), - _IconAndWidgets(Icons.download, [ - const Padding(padding: EdgeInsets.only(top: 15)), - const Divider(), - const ListTile( - subtitle: Text("下载&缓存"), - ), - const Divider(), - ListTile( - title: const Text("启动Web服务器"), - subtitle: const Text("让局域网内的设备通过浏览器看下载的漫画"), - onTap: (){ - Navigator.of(context).push( - mixRoute( - builder: (BuildContext context) => - const WebServerScreen(), - ), - ); - - }, - ), - const Divider(), - autoCleanSecSetting(), - ListTile( - onTap: () { - Navigator.push( - context, - mixRoute(builder: (context) => const CleanScreen()), - ); - }, - title: const Text('清除缓存'), - ), - const Divider(), - chooserRootSetting(), - downloadThreadCountSetting(), - downloadAndExportPathSetting(), - showCommentAtDownloadSetting(), - exportRenameSetting(), - const Divider(), - downloadCachePathSetting(), - importViewLogFromOff(), - const Divider(), - const Padding(padding: EdgeInsets.only(top: 15)), - ]), - ]; - var i = 0; return Scaffold( appBar: AppBar( title: const Text('设置'), - actions: [ - ...iaws.map( - (e) { - final idx = i; - return Opacity( - child: IconButton( - onPressed: () { - setState(() { - _index = idx; - }); - }, - icon: Icon(e.icon), - ), - opacity: i++ == _index ? 1 : .75, - ); - }, - ) - ], ), - body: ListView( - children: iaws[_index].widgets, + body: SingleChildScrollView( + padding: EdgeInsets.all(16), + child: Column( + children: [ + ExpansionTile( + leading: Icon(Icons.energy_savings_leaf), + title: Text('界面'), + children: [ + const Divider(), + ...themeWidgets(context, setState), + const Divider(), + pagerActionSetting(), + contentFailedReloadActionSetting(), + willPopNoticeSetting(), + categoriesColumnCountSetting(), + const Divider(), + timeZoneSetting(), + fontSetting(), + fullScreenUISetting(), + usingRightClickPopSetting(), + hiddenFdIconSetting(), + const Divider(), + androidDisplayModeSetting(), + androidSecureFlagSetting(), + authenticationSetting(), + const Divider(), + iconLoadingSetting(), + eBookScrollingSetting(), + eBookScrollingRangeSetting(), + eBookScrollingTriggerSetting(), + const Divider(), + ], + ), + ExpansionTile( + leading: Icon(Icons.lan), + title: Text('网络'), + children: [ + const Divider(), + const NetworkSetting(), + ], + ), + ExpansionTile( + leading: Icon(Icons.backup), + title: Text('同步'), + children: [ + const Divider(), + ...webDavSettings(context), + ], + ), + ExpansionTile( + leading: Icon(Icons.manage_accounts), + title: Text('账户'), + children: [ + const Divider(), + widget.hiddenAccountInfo + ? Container() + : ListTile( + onTap: () async { + Navigator.push( + context, + mixRoute( + builder: (context) => + const ModifyPasswordScreen(), + ), + ); + }, + title: const Text('修改密码'), + ), + ], + ), + ExpansionTile( + leading: Icon(Icons.dangerous), + title: Text('封印'), + children: [ + const Divider(), + shadowCategoriesModeSetting(), + shadowCategoriesSetting(), + ], + ), + ExpansionTile( + leading: Icon(Icons.menu_book_outlined), + title: Text('阅读'), + children: [ + const Divider(), + qualitySetting(), + readerTypeSetting(), + readerDirectionSetting(), + readerSliderPositionSetting(), + autoFullScreenSetting(), + fullScreenActionSetting(), + volumeControllerSetting(), + keyboardControllerSetting(), + const Divider(), + noAnimationSetting(), + imageFilterSetting(), + readerBackgroundColorSetting(), + ], + ), + ExpansionTile( + leading: Icon(Icons.download), + title: Text('下载'), + children: [ + const Divider(), + ListTile( + title: const Text("启动Web服务器"), + subtitle: const Text("让局域网内的设备通过浏览器看下载的漫画"), + onTap: () { + Navigator.of(context).push( + mixRoute( + builder: (BuildContext context) => + const WebServerScreen(), + ), + ); + }, + ), + const Divider(), + chooserRootSetting(), + downloadThreadCountSetting(), + downloadAndExportPathSetting(), + showCommentAtDownloadSetting(), + exportRenameSetting(), + ], + ), + ExpansionTile( + leading: Icon(Icons.ad_units), + title: Text('系统'), + children: [ + const Divider(), + autoCleanSecSetting(), + ListTile( + onTap: () { + Navigator.push( + context, + mixRoute(builder: (context) => const CleanScreen()), + ); + }, + title: const Text('清除缓存'), + ), + const Divider(), + migrate(context), + const Divider(), + downloadCachePathSetting(), + importViewLogFromOff(), + ], + ), + ], + ), ), ); } diff --git a/lib/screens/ThemeScreen.dart b/lib/screens/ThemeScreen.dart index d349339..879566c 100644 --- a/lib/screens/ThemeScreen.dart +++ b/lib/screens/ThemeScreen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import '../basic/config/Themes.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; class ThemeScreen extends StatefulWidget { @@ -23,45 +24,45 @@ class _ThemeScreenState extends State { Widget buildScreen(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("主题设置")), - body: ListView( - children: [ - const Divider(), - ListTile( - onTap: () async { - await chooseLightTheme(context); - setState(() {}); - }, - title: const Text('主题'), - subtitle: Text(currentLightThemeName()), - ), - const Divider(), - ...androidNightModeDisplay - ? [ - SwitchListTile( - title: const Text("深色模式下使用不同的主题"), - value: androidNightMode, - onChanged: (value) async { - await setAndroidNightMode(value); - setState(() {}); - }), - ] - : [], - const Divider(), - ...androidNightModeDisplay && androidNightMode - ? [ - ListTile( - onTap: () async { - await chooseDarkTheme(context); - setState(() {}); - }, - title: const Text('主题 (深色模式)'), - subtitle: Text(currentDarkThemeName()), - ), - ] - : [], - const Divider(), - ], + body: PikaListView( + children: themeWidgets(context, setState), ), ); } } + +List themeWidgets(BuildContext context, void Function(VoidCallback fn) setState) { + return [ + ListTile( + onTap: () async { + await chooseLightTheme(context); + setState(() {}); + }, + title: const Text('主题'), + subtitle: Text(currentLightThemeName()), + ), + ...androidNightModeDisplay + ? [ + SwitchListTile( + title: const Text("深色模式下使用不同的主题"), + value: androidNightMode, + onChanged: (value) async { + await setAndroidNightMode(value); + setState(() {}); + }), + ] + : [], + ...androidNightModeDisplay && androidNightMode + ? [ + ListTile( + onTap: () async { + await chooseDarkTheme(context); + setState(() {}); + }, + title: const Text('主题 (深色模式)'), + subtitle: Text(currentDarkThemeName()), + ), + ] + : [], + ]; +} diff --git a/lib/screens/ViewLogsScreen.dart b/lib/screens/ViewLogsScreen.dart index a79416c..890c7a8 100644 --- a/lib/screens/ViewLogsScreen.dart +++ b/lib/screens/ViewLogsScreen.dart @@ -10,6 +10,7 @@ import '../basic/Entities.dart'; import '../basic/config/IconLoading.dart'; import 'ComicInfoScreen.dart'; import 'components/Images.dart'; +import 'components/ListView.dart'; // 浏览记录 class ViewLogsScreen extends StatefulWidget { @@ -137,7 +138,7 @@ class _ViewLogsScreenState extends State { onPressed: _clearAll, icon: const Icon(Icons.auto_delete)), ], ), - body: ListView( + body: PikaListView( physics: _scrollPhysics, controller: _scrollController, children: entries.toList(), diff --git a/lib/screens/WebServerScreen.dart b/lib/screens/WebServerScreen.dart index a3f8b1e..e230343 100644 --- a/lib/screens/WebServerScreen.dart +++ b/lib/screens/WebServerScreen.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import '../basic/Method.dart'; import 'components/ContentError.dart'; import 'components/ContentLoading.dart'; +import 'components/ListView.dart'; import 'components/RightClickPop.dart'; class WebServerScreen extends StatefulWidget { @@ -52,7 +53,7 @@ class _WebServerScreenState extends State { if (snapshot.connectionState != ConnectionState.done) { return const ContentLoading(label: '加载中'); } - return ListView( + return PikaListView( children: [ Container( padding: const EdgeInsets.all(8), diff --git a/lib/screens/components/ComicList.dart b/lib/screens/components/ComicList.dart index b8ee3e4..fbc4559 100644 --- a/lib/screens/components/ComicList.dart +++ b/lib/screens/components/ComicList.dart @@ -12,6 +12,7 @@ import 'package:pikapika/basic/config/ShadowCategoriesMode.dart'; import 'ComicInfoCard.dart'; import 'Images.dart'; import 'LinkToComicInfo.dart'; +import 'ListView.dart'; class ComicListController { _ComicListState? _state; @@ -113,7 +114,7 @@ class _ComicListState extends State { } Widget _buildInfoCardList() { - return ListView( + return PikaListView( controller: widget.scrollController, physics: const AlwaysScrollableScrollPhysics(), children: [ @@ -229,19 +230,24 @@ class _ComicListState extends State { List wraps = []; List tmp = []; for (var e in widget.comicList) { - var shadow = e.categories.map( - (c) { - switch (currentShadowCategoriesMode()) { - case ShadowCategoriesMode.BLACK_LIST: - if (shadowCategories.contains(c)) return true; - break; - case ShadowCategoriesMode.WHITE_LIST: - if (!shadowCategories.contains(c)) return true; - break; + late bool shadow; + X: + switch (currentShadowCategoriesMode()) { + case ShadowCategoriesMode.BLACK_LIST: + shadow = e.categories + .map((c) => shadowCategories.contains(c)) + .reduce((value, element) => value || element); + break; + case ShadowCategoriesMode.WHITE_LIST: + for (var c in e.categories) { + if (shadowCategories.contains(c)) { + shadow = false; + break X; + } } - return false; - }, - ).reduce((value, element) => value || element); + shadow = true; + break; + } if (shadow) { tmp.add( Container( @@ -317,7 +323,7 @@ class _ComicListState extends State { tmp = []; } // 返回 - return ListView( + return PikaListView( controller: widget.scrollController, physics: const AlwaysScrollableScrollPhysics(), padding: EdgeInsets.only(top: gap, bottom: gap), @@ -338,19 +344,24 @@ class _ComicListState extends State { List wraps = []; List tmp = []; for (var e in widget.comicList) { - var shadow = e.categories.map( - (c) { - switch (currentShadowCategoriesMode()) { - case ShadowCategoriesMode.BLACK_LIST: - if (shadowCategories.contains(c)) return true; - break; - case ShadowCategoriesMode.WHITE_LIST: - if (!shadowCategories.contains(c)) return true; - break; + late bool shadow; + X: + switch (currentShadowCategoriesMode()) { + case ShadowCategoriesMode.BLACK_LIST: + shadow = e.categories + .map((c) => shadowCategories.contains(c)) + .reduce((value, element) => value || element); + break; + case ShadowCategoriesMode.WHITE_LIST: + for (var c in e.categories) { + if (shadowCategories.contains(c)) { + shadow = false; + break X; + } } - return false; - }, - ).reduce((value, element) => value || element); + shadow = true; + break; + } if (shadow) { tmp.add( Container( @@ -455,7 +466,7 @@ class _ComicListState extends State { tmp = []; } // 返回 - return ListView( + return PikaListView( controller: widget.scrollController, physics: const AlwaysScrollableScrollPhysics(), padding: EdgeInsets.only(top: gap, bottom: gap), diff --git a/lib/screens/components/ListView.dart b/lib/screens/components/ListView.dart new file mode 100644 index 0000000..48ce656 --- /dev/null +++ b/lib/screens/components/ListView.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:pikapika/basic/config/EBookScrolling.dart'; + +import '../../basic/config/EBookScrollingRange.dart'; +import '../../basic/config/EBookScrollingTrigger.dart'; + +class PikaListView extends StatefulWidget { + final EdgeInsets? padding; + final ScrollController? controller; + final List children; + final ScrollPhysics? physics; + + const PikaListView({ + Key? key, + required this.children, + this.controller, + this.padding, + this.physics, + }) : super(key: key); + + @override + State createState() => _PikaListViewState(); +} + +class _PikaListViewState extends State { + late ScrollController _privateController; + + @override + void initState() { + if (widget.controller == null) { + _privateController = ScrollController(); + } + super.initState(); + } + + @override + void dispose() { + if (widget.controller == null) { + _privateController.dispose(); + } + super.dispose(); + } + + ScrollController get _controller => widget.controller ?? _privateController; + double _y = 0; + + @override + Widget build(BuildContext context) { + if (!eBookScrolling) { + return ListView( + children: widget.children, + controller: _controller, + padding: widget.padding, + physics: widget.physics, + ); + } + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return GestureDetector( + onPanDown: (details) { + _y = 0; + }, + onPanUpdate: (details) { + _y += details.delta.dy; + }, + onPanEnd: (details) { + final lmPoints = + (MediaQuery.of(context).devicePixelRatio * (160 / 2.54)); + final double centimeters = _y / lmPoints; + late double off; + if (centimeters < -eBookScrollingTrigger) { + off = _controller.offset + + eBookScrollingRange * constraints.maxHeight; + off = off.clamp(0, _controller.position.maxScrollExtent); + _controller.jumpTo(off); + _controller.notifyListeners(); + } else if (centimeters > eBookScrollingTrigger) { + off = _controller.offset - + eBookScrollingRange * constraints.maxHeight; + off = off.clamp(0, _controller.position.maxScrollExtent); + _controller.jumpTo(off); + _controller.notifyListeners(); + } + }, + child: ListView( + physics: const NeverScrollableScrollPhysics(), + children: widget.children, + controller: _controller, + padding: widget.padding, + ), + ); + }, + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 5ec537c..29ca296 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -133,10 +133,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: dd328189f2f4ccea042bb5b382d5e981691cc74b5a3429b9317bff2b19704489 + sha256: dcde5ad1a0cebcf3715ea3f24d0db1888bf77027a26c77d7779e8ef63b8ade62 url: "https://pub.dev" source: hosted - version: "5.2.8" + version: "5.2.9" filesystem_picker: dependency: "direct main" description: @@ -566,10 +566,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: dd729390aa936bf1bdf5cd1bc7468ff340263f80a2c4f569416507667de8e3c8 + sha256: a52628068d282d01a07cd86e6ba99e497aa45ce8c91159015b2416907d78e411 url: "https://pub.dev" source: hosted - version: "6.0.26" + version: "6.0.27" url_launcher_ios: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 21b97ea..87c1215 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.7.3+18 +version: 1.7.4+19 environment: sdk: ">=2.12.0 <3.0.0"