🚀 v1.7.4
This commit is contained in:
parent
260aea01cd
commit
e57be1a892
|
@ -47,6 +47,9 @@ android {
|
|||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
v1.7.3
|
||||
v1.7.4
|
|
@ -1,4 +1,3 @@
|
|||
v1.7.3
|
||||
- [x] ✨ 可以隐藏发电图标(设置项)
|
||||
- [x] ✨ 可以给阅读器加灰度滤镜(设置项)(彩色墨水屏下或许有用)
|
||||
- [x] ✨ 可以选择阅读器背景色(设置项)(白色可防止墨水屏下拖影)
|
||||
v1.7.4
|
||||
- [x] ♻️ 优化发电
|
||||
- [x] ♻️ 优化设置
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(() {});
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
|
@ -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),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
|
@ -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),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
|
@ -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");
|
||||
|
|
|
@ -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(() {});
|
||||
|
|
|
@ -19,29 +19,20 @@ bool currentUsingRightClickPop() {
|
|||
return _usingRightClickPop;
|
||||
}
|
||||
|
||||
Future<void> _chooseUsingRightClickPop(BuildContext context) async {
|
||||
String? result =
|
||||
await chooseListDialog<String>(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,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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<AboutScreen> {
|
|||
appBar: AppBar(
|
||||
title: const Text('关于'),
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: min / 2,
|
||||
|
|
|
@ -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<AccountScreen> {
|
|||
),
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: const Text("账号"),
|
||||
|
|
|
@ -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<CategoriesScreen> {
|
|||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return const ContentLoading(label: '加载中');
|
||||
}
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
children: [
|
||||
Container(height: 20),
|
||||
Wrap(
|
||||
|
|
|
@ -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<ComicInfoScreen> with RouteAware {
|
|||
_buildDownloadAction(_epListFuture, _comicInfo),
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
ComicInfoCard(_comicInfo, linkItem: true),
|
||||
ComicTagsCard(_comicInfo.tags),
|
||||
|
|
|
@ -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<CommentScreen> {
|
|||
successBuilder:
|
||||
(BuildContext context, AsyncSnapshot<_CommentChildPage> snapshot) {
|
||||
var page = snapshot.data!;
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
children: [
|
||||
_buildPrePage(page),
|
||||
...page.docs.map((e) => _buildComment(e)),
|
||||
|
|
|
@ -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<DownloadConfirmScreen> {
|
|||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return const ContentLoading(label: '加载中');
|
||||
}
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
children: [
|
||||
ComicInfoCard(widget.comicInfo),
|
||||
_buildButtons(),
|
||||
|
|
|
@ -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<DownloadExportGroupScreen> {
|
|||
_f = method.allDownloads("");
|
||||
});
|
||||
},
|
||||
child: ListView(
|
||||
child: PikaListView(
|
||||
children: ws,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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<String> idList;
|
||||
|
@ -57,7 +54,7 @@ class _DownloadExportingGroupScreenState
|
|||
if (exported) {
|
||||
return const Center(child: Text("导出成功"));
|
||||
}
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
children: [
|
||||
Container(height: 20),
|
||||
displayExportPathInfo(),
|
||||
|
|
|
@ -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<DownloadImportScreen> {
|
|||
appBar: AppBar(
|
||||
title: const Text('导入'),
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
|
|
|
@ -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<DownloadInfoScreen>
|
|||
}
|
||||
List<dynamic> tagsDynamic = json.decode(_task.tags);
|
||||
List<String> tags = tagsDynamic.map((e) => "$e").toList();
|
||||
var list = ListView(
|
||||
var list = PikaListView(
|
||||
children: [
|
||||
DownloadInfoCard(task: _task, linkItem: true),
|
||||
ComicTagsCard(tags),
|
||||
|
|
|
@ -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<DownloadListScreen> {
|
|||
_f = method.allDownloads(_search);
|
||||
});
|
||||
},
|
||||
child: ListView(
|
||||
child: PikaListView(
|
||||
children: [
|
||||
...data.map(downloadWidget),
|
||||
],
|
||||
|
|
|
@ -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<ForgotPasswordScreen> {
|
|||
}
|
||||
|
||||
Widget _inputEmailScreen() {
|
||||
return ListView(children: [
|
||||
return PikaListView(children: [
|
||||
ListTile(
|
||||
title: const Text("账号"),
|
||||
subtitle: Text(_email == "" ? "未设置" : _email),
|
||||
|
|
|
@ -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<GameDownloadScreen> {
|
|||
appBar: AppBar(
|
||||
title: Text("下载 - ${widget.info.title}"),
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
GameTitleCard(widget.info),
|
||||
ItemBuilder(
|
||||
|
|
|
@ -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<GamesScreen> {
|
|||
),
|
||||
),
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
...wraps,
|
||||
...page.page < page.pages
|
||||
|
|
|
@ -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<ImportFromOffScreen> {
|
|||
appBar: AppBar(
|
||||
title: const Text('导入'),
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
|
|
|
@ -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<InitScreen> {
|
|||
await initWebDav();
|
||||
await initImageFilter();
|
||||
await initReaderBackgroundColor();
|
||||
await initEBookScrolling();
|
||||
await initEBookScrollingRange();
|
||||
await initEBookScrollingTrigger();
|
||||
|
||||
String? initUrl;
|
||||
if (Platform.isAndroid || Platform.isIOS) {
|
||||
|
|
|
@ -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<MigrateScreen> {
|
|||
(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
|
||||
switch (_migrate) {
|
||||
case 0:
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
|
|
|
@ -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<ModifyPasswordScreen> {
|
|||
}
|
||||
|
||||
Widget _buildForm() {
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
children: [
|
||||
const Divider(),
|
||||
ListTile(
|
||||
|
|
|
@ -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(),
|
||||
],
|
||||
|
|
|
@ -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<PkzArchiveScreen> with RouteAware {
|
|||
BuildContext context,
|
||||
AsyncSnapshot snapshot,
|
||||
) {
|
||||
return ListView(children: [
|
||||
return PikaListView(children: [
|
||||
..._info.comics
|
||||
.map((e) => GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
|
|
|
@ -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<PkzComicInfoScreen>
|
|||
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),
|
||||
|
|
|
@ -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<ProScreen> {
|
|||
appBar: AppBar(
|
||||
title: const Text("发电中心"),
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: min / 2,
|
||||
|
@ -100,8 +101,10 @@ class _ProScreenState extends State<ProScreen> {
|
|||
ListTile(
|
||||
title: const Text("我刚才发了电"),
|
||||
onTap: () async {
|
||||
final code = await inputString(context, "输入代码");
|
||||
if (code != null && code.isNotEmpty) {
|
||||
var code = await inputString(context, "输入代码");
|
||||
if (code != null) {
|
||||
code = code.trim();
|
||||
if (code.isNotEmpty) {
|
||||
try {
|
||||
await method.inputCdKey(code);
|
||||
defaultToast(context, "SUCCESS");
|
||||
|
@ -109,6 +112,7 @@ class _ProScreenState extends State<ProScreen> {
|
|||
defaultToast(context, "FAIL");
|
||||
}
|
||||
}
|
||||
}
|
||||
await reloadIsPro();
|
||||
setState(() {});
|
||||
},
|
||||
|
|
|
@ -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<RegisterScreen> {
|
|||
),
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
children: [
|
||||
const Divider(),
|
||||
ListTile(
|
||||
|
|
|
@ -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,16 +69,64 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
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("网络&账户"),
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('设置'),
|
||||
),
|
||||
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()
|
||||
|
@ -84,73 +135,28 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||
Navigator.push(
|
||||
context,
|
||||
mixRoute(
|
||||
builder: (context) => const ModifyPasswordScreen(),
|
||||
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("内容&阅读器"),
|
||||
],
|
||||
),
|
||||
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(),
|
||||
|
@ -161,17 +167,15 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||
volumeControllerSetting(),
|
||||
keyboardControllerSetting(),
|
||||
const Divider(),
|
||||
noAnimationSetting(),
|
||||
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("下载&缓存"),
|
||||
],
|
||||
),
|
||||
ExpansionTile(
|
||||
leading: Icon(Icons.download),
|
||||
title: Text('下载'),
|
||||
children: [
|
||||
const Divider(),
|
||||
ListTile(
|
||||
title: const Text("启动Web服务器"),
|
||||
|
@ -183,9 +187,20 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||
const WebServerScreen(),
|
||||
),
|
||||
);
|
||||
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
chooserRootSetting(),
|
||||
downloadThreadCountSetting(),
|
||||
downloadAndExportPathSetting(),
|
||||
showCommentAtDownloadSetting(),
|
||||
exportRenameSetting(),
|
||||
],
|
||||
),
|
||||
ExpansionTile(
|
||||
leading: Icon(Icons.ad_units),
|
||||
title: Text('系统'),
|
||||
children: [
|
||||
const Divider(),
|
||||
autoCleanSecSetting(),
|
||||
ListTile(
|
||||
|
@ -198,43 +213,14 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||
title: const Text('清除缓存'),
|
||||
),
|
||||
const Divider(),
|
||||
chooserRootSetting(),
|
||||
downloadThreadCountSetting(),
|
||||
downloadAndExportPathSetting(),
|
||||
showCommentAtDownloadSetting(),
|
||||
exportRenameSetting(),
|
||||
migrate(context),
|
||||
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,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,9 +24,15 @@ class _ThemeScreenState extends State<ThemeScreen> {
|
|||
Widget buildScreen(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text("主题设置")),
|
||||
body: ListView(
|
||||
children: [
|
||||
const Divider(),
|
||||
body: PikaListView(
|
||||
children: themeWidgets(context, setState),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> themeWidgets(BuildContext context, void Function(VoidCallback fn) setState) {
|
||||
return [
|
||||
ListTile(
|
||||
onTap: () async {
|
||||
await chooseLightTheme(context);
|
||||
|
@ -34,7 +41,6 @@ class _ThemeScreenState extends State<ThemeScreen> {
|
|||
title: const Text('主题'),
|
||||
subtitle: Text(currentLightThemeName()),
|
||||
),
|
||||
const Divider(),
|
||||
...androidNightModeDisplay
|
||||
? [
|
||||
SwitchListTile(
|
||||
|
@ -46,7 +52,6 @@ class _ThemeScreenState extends State<ThemeScreen> {
|
|||
}),
|
||||
]
|
||||
: [],
|
||||
const Divider(),
|
||||
...androidNightModeDisplay && androidNightMode
|
||||
? [
|
||||
ListTile(
|
||||
|
@ -59,9 +64,5 @@ class _ThemeScreenState extends State<ThemeScreen> {
|
|||
),
|
||||
]
|
||||
: [],
|
||||
const Divider(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
|
@ -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<ViewLogsScreen> {
|
|||
onPressed: _clearAll, icon: const Icon(Icons.auto_delete)),
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
body: PikaListView(
|
||||
physics: _scrollPhysics,
|
||||
controller: _scrollController,
|
||||
children: entries.toList(),
|
||||
|
|
|
@ -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<WebServerScreen> {
|
|||
if (snapshot.connectionState != ConnectionState.done) {
|
||||
return const ContentLoading(label: '加载中');
|
||||
}
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
|
|
|
@ -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<ComicList> {
|
|||
}
|
||||
|
||||
Widget _buildInfoCardList() {
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
controller: widget.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
children: [
|
||||
|
@ -229,19 +230,24 @@ class _ComicListState extends State<ComicList> {
|
|||
List<Widget> wraps = [];
|
||||
List<Widget> tmp = [];
|
||||
for (var e in widget.comicList) {
|
||||
var shadow = e.categories.map(
|
||||
(c) {
|
||||
late bool shadow;
|
||||
X:
|
||||
switch (currentShadowCategoriesMode()) {
|
||||
case ShadowCategoriesMode.BLACK_LIST:
|
||||
if (shadowCategories.contains(c)) return true;
|
||||
shadow = e.categories
|
||||
.map((c) => shadowCategories.contains(c))
|
||||
.reduce((value, element) => value || element);
|
||||
break;
|
||||
case ShadowCategoriesMode.WHITE_LIST:
|
||||
if (!shadowCategories.contains(c)) return true;
|
||||
for (var c in e.categories) {
|
||||
if (shadowCategories.contains(c)) {
|
||||
shadow = false;
|
||||
break X;
|
||||
}
|
||||
}
|
||||
shadow = true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
).reduce((value, element) => value || element);
|
||||
if (shadow) {
|
||||
tmp.add(
|
||||
Container(
|
||||
|
@ -317,7 +323,7 @@ class _ComicListState extends State<ComicList> {
|
|||
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<ComicList> {
|
|||
List<Widget> wraps = [];
|
||||
List<Widget> tmp = [];
|
||||
for (var e in widget.comicList) {
|
||||
var shadow = e.categories.map(
|
||||
(c) {
|
||||
late bool shadow;
|
||||
X:
|
||||
switch (currentShadowCategoriesMode()) {
|
||||
case ShadowCategoriesMode.BLACK_LIST:
|
||||
if (shadowCategories.contains(c)) return true;
|
||||
shadow = e.categories
|
||||
.map((c) => shadowCategories.contains(c))
|
||||
.reduce((value, element) => value || element);
|
||||
break;
|
||||
case ShadowCategoriesMode.WHITE_LIST:
|
||||
if (!shadowCategories.contains(c)) return true;
|
||||
for (var c in e.categories) {
|
||||
if (shadowCategories.contains(c)) {
|
||||
shadow = false;
|
||||
break X;
|
||||
}
|
||||
}
|
||||
shadow = true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
).reduce((value, element) => value || element);
|
||||
if (shadow) {
|
||||
tmp.add(
|
||||
Container(
|
||||
|
@ -455,7 +466,7 @@ class _ComicListState extends State<ComicList> {
|
|||
tmp = [];
|
||||
}
|
||||
// 返回
|
||||
return ListView(
|
||||
return PikaListView(
|
||||
controller: widget.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.only(top: gap, bottom: gap),
|
||||
|
|
|
@ -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<Widget> children;
|
||||
final ScrollPhysics? physics;
|
||||
|
||||
const PikaListView({
|
||||
Key? key,
|
||||
required this.children,
|
||||
this.controller,
|
||||
this.padding,
|
||||
this.physics,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _PikaListViewState();
|
||||
}
|
||||
|
||||
class _PikaListViewState extends State<PikaListView> {
|
||||
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,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue