🚀 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.
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix ".debug"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
v1.7.3
|
v1.7.4
|
|
@ -1,4 +1,3 @@
|
||||||
v1.7.3
|
v1.7.4
|
||||||
- [x] ✨ 可以隐藏发电图标(设置项)
|
- [x] ♻️ 优化发电
|
||||||
- [x] ✨ 可以给阅读器加灰度滤镜(设置项)(彩色墨水屏下或许有用)
|
- [x] ♻️ 优化设置
|
||||||
- [x] ✨ 可以选择阅读器背景色(设置项)(白色可防止墨水屏下拖影)
|
|
||||||
|
|
|
@ -20,9 +20,10 @@ Widget categoriesColumnCountSetting() {
|
||||||
builder: (BuildContext context, void Function(void Function()) setState) {
|
builder: (BuildContext context, void Function(void Function()) setState) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text(
|
title: const Text(
|
||||||
"首页分类列数",
|
"首页分类展示列数",
|
||||||
),
|
),
|
||||||
subtitle: Text("$categoriesColumnCount"),
|
subtitle:
|
||||||
|
Text(categoriesColumnCount == 0 ? "自动" : "$categoriesColumnCount"),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
int? value = await chooseMapDialog(
|
int? value = await chooseMapDialog(
|
||||||
context,
|
context,
|
||||||
|
@ -33,7 +34,7 @@ Widget categoriesColumnCountSetting() {
|
||||||
"4": 4,
|
"4": 4,
|
||||||
"5": 5,
|
"5": 5,
|
||||||
},
|
},
|
||||||
"选择首页分类列数");
|
"选择首页分类展示列数");
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
await method.saveProperty(_propertyName, "$value");
|
await method.saveProperty(_propertyName, "$value");
|
||||||
categoriesColumnCount = 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) {
|
builder: (BuildContext context, void Function(void Function()) setState) {
|
||||||
return SwitchListTile(
|
return SwitchListTile(
|
||||||
title: const Text("隐藏个人空间的发电图标"),
|
title: const Text("隐藏个人空间的发电图标"),
|
||||||
subtitle: Text(_hiddenFdIcon ? "是" : "否"),
|
|
||||||
value: _hiddenFdIcon,
|
value: _hiddenFdIcon,
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
await method.saveProperty(_propertyName, "$value");
|
await method.saveProperty(_propertyName, "$value");
|
||||||
|
|
|
@ -31,7 +31,6 @@ Widget iconLoadingSetting() {
|
||||||
builder: (BuildContext context, void Function(void Function()) setState) {
|
builder: (BuildContext context, void Function(void Function()) setState) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text("尽量减少UI动画"),
|
title: const Text("尽量减少UI动画"),
|
||||||
subtitle: Text(_iconLoading ? "是" : "否"),
|
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await _chooseIconLoading(context);
|
await _chooseIconLoading(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|
|
@ -19,29 +19,20 @@ bool currentUsingRightClickPop() {
|
||||||
return _usingRightClickPop;
|
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() {
|
Widget usingRightClickPopSetting() {
|
||||||
if (!(Platform.isWindows || Platform.isMacOS || Platform.isLinux)) {
|
if (!(Platform.isWindows || Platform.isMacOS || Platform.isLinux)) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
return StatefulBuilder(
|
return StatefulBuilder(
|
||||||
builder: (BuildContext context, void Function(void Function()) setState) {
|
builder: (BuildContext context, void Function(void Function()) setState) {
|
||||||
return ListTile(
|
return SwitchListTile(
|
||||||
title: const Text("鼠标右键返回上一页"),
|
title: const Text("鼠标右键返回上一页"),
|
||||||
subtitle: Text(_usingRightClickPop ? "是" : "否"),
|
onChanged: (value) async {
|
||||||
onTap: () async {
|
await method.saveProperty(_propertyName, "${value ? "是" : "否"}");
|
||||||
await _chooseUsingRightClickPop(context);
|
_usingRightClickPop = value;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
|
value: _usingRightClickPop,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,8 +17,7 @@ Widget willPopNoticeSetting() {
|
||||||
return StatefulBuilder(
|
return StatefulBuilder(
|
||||||
builder: (BuildContext context, void Function(void Function()) setState) {
|
builder: (BuildContext context, void Function(void Function()) setState) {
|
||||||
return SwitchListTile(
|
return SwitchListTile(
|
||||||
title: const Text("退出APP的提示"),
|
title: const Text("在首页连续按两下返回键才能退出APP"),
|
||||||
subtitle: Text(_willPopNotice ? "是" : "否"),
|
|
||||||
value: _willPopNotice,
|
value: _willPopNotice,
|
||||||
onChanged: (value) async {
|
onChanged: (value) async {
|
||||||
await method.saveProperty(_propertyName, "$value");
|
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/basic/config/Version.dart';
|
||||||
import 'package:pikapika/screens/components/Badge.dart';
|
import 'package:pikapika/screens/components/Badge.dart';
|
||||||
|
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
const _releasesUrl = "https://github.com/niuhuan/pikapika/releases";
|
const _releasesUrl = "https://github.com/niuhuan/pikapika/releases";
|
||||||
|
@ -54,7 +55,7 @@ class _AboutScreenState extends State<AboutScreen> {
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('关于'),
|
title: const Text('关于'),
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: min / 2,
|
width: min / 2,
|
||||||
|
|
|
@ -15,6 +15,7 @@ import 'AppScreen.dart';
|
||||||
import 'DownloadListScreen.dart';
|
import 'DownloadListScreen.dart';
|
||||||
import 'ForgotPasswordScreen.dart';
|
import 'ForgotPasswordScreen.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
// 账户设置
|
// 账户设置
|
||||||
class AccountScreen extends StatefulWidget {
|
class AccountScreen extends StatefulWidget {
|
||||||
|
@ -102,7 +103,7 @@ class _AccountScreenState extends State<AccountScreen> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text("账号"),
|
title: const Text("账号"),
|
||||||
|
|
|
@ -20,6 +20,7 @@ import 'RandomComicsScreen.dart';
|
||||||
import 'components/Common.dart';
|
import 'components/Common.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
import 'components/Images.dart';
|
import 'components/Images.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
// 分类
|
// 分类
|
||||||
class CategoriesScreen extends StatefulWidget {
|
class CategoriesScreen extends StatefulWidget {
|
||||||
|
@ -127,7 +128,7 @@ class _CategoriesScreenState extends State<CategoriesScreen> {
|
||||||
if (snapshot.connectionState != ConnectionState.done) {
|
if (snapshot.connectionState != ConnectionState.done) {
|
||||||
return const ContentLoading(label: '加载中');
|
return const ContentLoading(label: '加载中');
|
||||||
}
|
}
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
Container(height: 20),
|
Container(height: 20),
|
||||||
Wrap(
|
Wrap(
|
||||||
|
|
|
@ -21,6 +21,7 @@ import 'components/CommentList.dart';
|
||||||
import 'components/ContentError.dart';
|
import 'components/ContentError.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
import 'components/ContinueReadButton.dart';
|
import 'components/ContinueReadButton.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 漫画详情
|
// 漫画详情
|
||||||
|
@ -146,7 +147,7 @@ class _ComicInfoScreenState extends State<ComicInfoScreen> with RouteAware {
|
||||||
_buildDownloadAction(_epListFuture, _comicInfo),
|
_buildDownloadAction(_epListFuture, _comicInfo),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
ComicInfoCard(_comicInfo, linkItem: true),
|
ComicInfoCard(_comicInfo, linkItem: true),
|
||||||
ComicTagsCard(_comicInfo.tags),
|
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/CommentMainType.dart';
|
||||||
import 'package:pikapika/screens/components/ContentBuilder.dart';
|
import 'package:pikapika/screens/components/ContentBuilder.dart';
|
||||||
|
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
class _CommentChildPage extends e.Page {
|
class _CommentChildPage extends e.Page {
|
||||||
|
@ -67,7 +68,7 @@ class _CommentScreenState extends State<CommentScreen> {
|
||||||
successBuilder:
|
successBuilder:
|
||||||
(BuildContext context, AsyncSnapshot<_CommentChildPage> snapshot) {
|
(BuildContext context, AsyncSnapshot<_CommentChildPage> snapshot) {
|
||||||
var page = snapshot.data!;
|
var page = snapshot.data!;
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
_buildPrePage(page),
|
_buildPrePage(page),
|
||||||
...page.docs.map((e) => _buildComment(e)),
|
...page.docs.map((e) => _buildComment(e)),
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:pikapika/screens/components/ContentLoading.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
|
||||||
import 'components/ComicInfoCard.dart';
|
import 'components/ComicInfoCard.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 确认下载
|
// 确认下载
|
||||||
|
@ -128,7 +129,7 @@ class _DownloadConfirmScreenState extends State<DownloadConfirmScreen> {
|
||||||
if (snapshot.connectionState != ConnectionState.done) {
|
if (snapshot.connectionState != ConnectionState.done) {
|
||||||
return const ContentLoading(label: '加载中');
|
return const ContentLoading(label: '加载中');
|
||||||
}
|
}
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
ComicInfoCard(widget.comicInfo),
|
ComicInfoCard(widget.comicInfo),
|
||||||
_buildButtons(),
|
_buildButtons(),
|
||||||
|
|
|
@ -7,6 +7,7 @@ import '../basic/config/IconLoading.dart';
|
||||||
import 'DownloadExportingGroupScreen.dart';
|
import 'DownloadExportingGroupScreen.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
import 'components/DownloadInfoCard.dart';
|
import 'components/DownloadInfoCard.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
class DownloadExportGroupScreen extends StatefulWidget {
|
class DownloadExportGroupScreen extends StatefulWidget {
|
||||||
const DownloadExportGroupScreen({Key? key}) : super(key: key);
|
const DownloadExportGroupScreen({Key? key}) : super(key: key);
|
||||||
|
@ -72,7 +73,7 @@ class _DownloadExportGroupScreenState extends State<DownloadExportGroupScreen> {
|
||||||
_f = method.allDownloads("");
|
_f = method.allDownloads("");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: ListView(
|
child: PikaListView(
|
||||||
children: ws,
|
children: ws,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -12,6 +12,7 @@ import '../basic/config/IsPro.dart';
|
||||||
import 'components/ContentError.dart';
|
import 'components/ContentError.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
import 'components/DownloadInfoCard.dart';
|
import 'components/DownloadInfoCard.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 导出
|
// 导出
|
||||||
|
@ -94,7 +95,7 @@ class _DownloadExportToFileScreenState
|
||||||
if (snapshot.connectionState != ConnectionState.done) {
|
if (snapshot.connectionState != ConnectionState.done) {
|
||||||
return const ContentLoading(label: '加载中');
|
return const ContentLoading(label: '加载中');
|
||||||
}
|
}
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
DownloadInfoCard(task: _task),
|
DownloadInfoCard(task: _task),
|
||||||
Container(
|
Container(
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:pikapika/basic/Method.dart';
|
||||||
import 'components/ContentError.dart';
|
import 'components/ContentError.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
import 'components/DownloadInfoCard.dart';
|
import 'components/DownloadInfoCard.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 传输到其他设备
|
// 传输到其他设备
|
||||||
|
@ -85,7 +86,7 @@ class _DownloadExportToSocketScreenState
|
||||||
if (snapshot.connectionState != ConnectionState.done) {
|
if (snapshot.connectionState != ConnectionState.done) {
|
||||||
return const ContentLoading(label: '加载中');
|
return const ContentLoading(label: '加载中');
|
||||||
}
|
}
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
DownloadInfoCard(task: widget.task),
|
DownloadInfoCard(task: widget.task),
|
||||||
Container(
|
Container(
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pikapika/basic/Common.dart';
|
import 'package:pikapika/basic/Common.dart';
|
||||||
|
|
||||||
import '../basic/Channels.dart';
|
import '../basic/Channels.dart';
|
||||||
import '../basic/Cross.dart';
|
|
||||||
import '../basic/Method.dart';
|
import '../basic/Method.dart';
|
||||||
import '../basic/config/ExportPath.dart';
|
import '../basic/config/ExportPath.dart';
|
||||||
import '../basic/config/ExportRename.dart';
|
import '../basic/config/ExportRename.dart';
|
||||||
import '../basic/config/IsPro.dart';
|
import '../basic/config/IsPro.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
class DownloadExportingGroupScreen extends StatefulWidget {
|
class DownloadExportingGroupScreen extends StatefulWidget {
|
||||||
final List<String> idList;
|
final List<String> idList;
|
||||||
|
@ -57,7 +54,7 @@ class _DownloadExportingGroupScreenState
|
||||||
if (exported) {
|
if (exported) {
|
||||||
return const Center(child: Text("导出成功"));
|
return const Center(child: Text("导出成功"));
|
||||||
}
|
}
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
Container(height: 20),
|
Container(height: 20),
|
||||||
displayExportPathInfo(),
|
displayExportPathInfo(),
|
||||||
|
|
|
@ -14,6 +14,7 @@ import '../basic/config/ImportNotice.dart';
|
||||||
import '../basic/config/IsPro.dart';
|
import '../basic/config/IsPro.dart';
|
||||||
import 'PkzArchiveScreen.dart';
|
import 'PkzArchiveScreen.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 导入
|
// 导入
|
||||||
|
@ -68,7 +69,7 @@ class _DownloadImportScreenState extends State<DownloadImportScreen> {
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('导入'),
|
title: const Text('导入'),
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
|
|
|
@ -17,6 +17,7 @@ import 'components/ContentError.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
import 'components/ContinueReadButton.dart';
|
import 'components/ContinueReadButton.dart';
|
||||||
import 'components/DownloadInfoCard.dart';
|
import 'components/DownloadInfoCard.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/Recommendation.dart';
|
import 'components/Recommendation.dart';
|
||||||
|
|
||||||
// 下载详情
|
// 下载详情
|
||||||
|
@ -122,7 +123,7 @@ class _DownloadInfoScreenState extends State<DownloadInfoScreen>
|
||||||
}
|
}
|
||||||
List<dynamic> tagsDynamic = json.decode(_task.tags);
|
List<dynamic> tagsDynamic = json.decode(_task.tags);
|
||||||
List<String> tags = tagsDynamic.map((e) => "$e").toList();
|
List<String> tags = tagsDynamic.map((e) => "$e").toList();
|
||||||
var list = ListView(
|
var list = PikaListView(
|
||||||
children: [
|
children: [
|
||||||
DownloadInfoCard(task: _task, linkItem: true),
|
DownloadInfoCard(task: _task, linkItem: true),
|
||||||
ComicTagsCard(tags),
|
ComicTagsCard(tags),
|
||||||
|
|
|
@ -13,6 +13,7 @@ import 'DownloadImportScreen.dart';
|
||||||
import 'DownloadInfoScreen.dart';
|
import 'DownloadInfoScreen.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
import 'components/DownloadInfoCard.dart';
|
import 'components/DownloadInfoCard.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 下载列表
|
// 下载列表
|
||||||
|
@ -118,7 +119,7 @@ class _DownloadListScreenState extends State<DownloadListScreen> {
|
||||||
_f = method.allDownloads(_search);
|
_f = method.allDownloads(_search);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: ListView(
|
child: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
...data.map(downloadWidget),
|
...data.map(downloadWidget),
|
||||||
],
|
],
|
||||||
|
|
|
@ -4,6 +4,7 @@ import '../basic/Common.dart';
|
||||||
import '../basic/Cross.dart';
|
import '../basic/Cross.dart';
|
||||||
import '../basic/Method.dart';
|
import '../basic/Method.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
class ForgotPasswordScreen extends StatefulWidget {
|
class ForgotPasswordScreen extends StatefulWidget {
|
||||||
const ForgotPasswordScreen({Key? key}) : super(key: key);
|
const ForgotPasswordScreen({Key? key}) : super(key: key);
|
||||||
|
@ -50,7 +51,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _inputEmailScreen() {
|
Widget _inputEmailScreen() {
|
||||||
return ListView(children: [
|
return PikaListView(children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text("账号"),
|
title: const Text("账号"),
|
||||||
subtitle: Text(_email == "" ? "未设置" : _email),
|
subtitle: Text(_email == "" ? "未设置" : _email),
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:pikapika/basic/Method.dart';
|
||||||
import 'package:pikapika/screens/components/ItemBuilder.dart';
|
import 'package:pikapika/screens/components/ItemBuilder.dart';
|
||||||
|
|
||||||
import 'components/GameTitleCard.dart';
|
import 'components/GameTitleCard.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 游戏下载地址列表页
|
// 游戏下载地址列表页
|
||||||
|
@ -35,7 +36,7 @@ class _GameDownloadScreenState extends State<GameDownloadScreen> {
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text("下载 - ${widget.info.title}"),
|
title: Text("下载 - ${widget.info.title}"),
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
GameTitleCard(widget.info),
|
GameTitleCard(widget.info),
|
||||||
ItemBuilder(
|
ItemBuilder(
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:pikapika/screens/components/ContentBuilder.dart';
|
||||||
import '../basic/config/IconLoading.dart';
|
import '../basic/config/IconLoading.dart';
|
||||||
import 'GameInfoScreen.dart';
|
import 'GameInfoScreen.dart';
|
||||||
import 'components/Images.dart';
|
import 'components/Images.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 游戏列表
|
// 游戏列表
|
||||||
|
@ -171,7 +172,7 @@ class _GamesScreenState extends State<GamesScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
...wraps,
|
...wraps,
|
||||||
...page.page < page.pages
|
...page.page < page.pages
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:pikapika/basic/Method.dart';
|
||||||
|
|
||||||
import '../basic/Channels.dart';
|
import '../basic/Channels.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
class ImportFromOffScreen extends StatefulWidget {
|
class ImportFromOffScreen extends StatefulWidget {
|
||||||
|
@ -58,7 +59,7 @@ class _ImportFromOffScreenState extends State<ImportFromOffScreen> {
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('导入'),
|
title: const Text('导入'),
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(10),
|
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/ContentFailedReloadAction.dart';
|
||||||
import 'package:pikapika/basic/config/DownloadAndExportPath.dart';
|
import 'package:pikapika/basic/config/DownloadAndExportPath.dart';
|
||||||
import 'package:pikapika/basic/config/DownloadThreadCount.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/FullScreenAction.dart';
|
||||||
import 'package:pikapika/basic/config/FullScreenUI.dart';
|
import 'package:pikapika/basic/config/FullScreenUI.dart';
|
||||||
import 'package:pikapika/basic/config/ImageAddress.dart';
|
import 'package:pikapika/basic/config/ImageAddress.dart';
|
||||||
|
@ -119,6 +122,9 @@ class _InitScreenState extends State<InitScreen> {
|
||||||
await initWebDav();
|
await initWebDav();
|
||||||
await initImageFilter();
|
await initImageFilter();
|
||||||
await initReaderBackgroundColor();
|
await initReaderBackgroundColor();
|
||||||
|
await initEBookScrolling();
|
||||||
|
await initEBookScrollingRange();
|
||||||
|
await initEBookScrollingTrigger();
|
||||||
|
|
||||||
String? initUrl;
|
String? initUrl;
|
||||||
if (Platform.isAndroid || Platform.isIOS) {
|
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/ContentBuilder.dart';
|
||||||
import 'package:pikapika/screens/components/ContentLoading.dart';
|
import 'package:pikapika/screens/components/ContentLoading.dart';
|
||||||
|
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
// 数据迁移页面
|
// 数据迁移页面
|
||||||
|
@ -55,7 +56,7 @@ class _MigrateScreenState extends State<MigrateScreen> {
|
||||||
(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
|
(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
|
||||||
switch (_migrate) {
|
switch (_migrate) {
|
||||||
case 0:
|
case 0:
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:pikapika/basic/Method.dart';
|
||||||
import 'package:pikapika/screens/components/ContentLoading.dart';
|
import 'package:pikapika/screens/components/ContentLoading.dart';
|
||||||
|
|
||||||
import '../basic/Common.dart';
|
import '../basic/Common.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
class ModifyPasswordScreen extends StatefulWidget {
|
class ModifyPasswordScreen extends StatefulWidget {
|
||||||
|
@ -49,7 +50,7 @@ class _ModifyPasswordScreenState extends State<ModifyPasswordScreen> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildForm() {
|
Widget _buildForm() {
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pikapika/screens/components/NetworkSetting.dart';
|
import 'package:pikapika/screens/components/NetworkSetting.dart';
|
||||||
|
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
class NetworkSettingsScreen extends StatelessWidget {
|
class NetworkSettingsScreen extends StatelessWidget {
|
||||||
|
@ -17,7 +18,7 @@ class NetworkSettingsScreen extends StatelessWidget {
|
||||||
|
|
||||||
Widget buildScreen(BuildContext context) => Scaffold(
|
Widget buildScreen(BuildContext context) => Scaffold(
|
||||||
appBar: AppBar(title: const Text('网络设置')),
|
appBar: AppBar(title: const Text('网络设置')),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: const [
|
children: const [
|
||||||
NetworkSetting(),
|
NetworkSetting(),
|
||||||
],
|
],
|
||||||
|
|
|
@ -16,6 +16,7 @@ import '../basic/Navigator.dart';
|
||||||
import '../basic/config/IconLoading.dart';
|
import '../basic/config/IconLoading.dart';
|
||||||
import '../basic/config/Platform.dart';
|
import '../basic/config/Platform.dart';
|
||||||
import 'PkzComicInfoScreen.dart';
|
import 'PkzComicInfoScreen.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
class PkzArchiveScreen extends StatefulWidget {
|
class PkzArchiveScreen extends StatefulWidget {
|
||||||
final bool holdPkz;
|
final bool holdPkz;
|
||||||
|
@ -122,7 +123,7 @@ class _PkzArchiveScreenState extends State<PkzArchiveScreen> with RouteAware {
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
AsyncSnapshot snapshot,
|
AsyncSnapshot snapshot,
|
||||||
) {
|
) {
|
||||||
return ListView(children: [
|
return PikaListView(children: [
|
||||||
..._info.comics
|
..._info.comics
|
||||||
.map((e) => GestureDetector(
|
.map((e) => GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:pikapika/basic/Entities.dart';
|
import 'package:pikapika/basic/Entities.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
import 'package:pikapika/screens/PkzReaderScreen.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/Common.dart';
|
||||||
import '../basic/Navigator.dart';
|
import '../basic/Navigator.dart';
|
||||||
import '../basic/config/IconLoading.dart';
|
import '../basic/config/IconLoading.dart';
|
||||||
import 'PkzArchiveScreen.dart';
|
import 'components/ListView.dart';
|
||||||
import 'components/PkzComicInfoCard.dart';
|
import 'components/PkzComicInfoCard.dart';
|
||||||
|
|
||||||
class PkzComicInfoScreen extends StatefulWidget {
|
class PkzComicInfoScreen extends StatefulWidget {
|
||||||
|
@ -116,7 +113,7 @@ class _PkzComicInfoScreenState extends State<PkzComicInfoScreen>
|
||||||
widget.pkzComic.title,
|
widget.pkzComic.title,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: ListView(children: [
|
body: PikaListView(children: [
|
||||||
PkzComicInfoCard(info: widget.pkzComic, pkzPath: widget.pkzPath),
|
PkzComicInfoCard(info: widget.pkzComic, pkzPath: widget.pkzPath),
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(top: 5, bottom: 5),
|
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/IconLoading.dart';
|
||||||
import '../basic/config/IsPro.dart';
|
import '../basic/config/IsPro.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
class ProScreen extends StatefulWidget {
|
class ProScreen extends StatefulWidget {
|
||||||
const ProScreen({Key? key}) : super(key: key);
|
const ProScreen({Key? key}) : super(key: key);
|
||||||
|
@ -48,7 +49,7 @@ class _ProScreenState extends State<ProScreen> {
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text("发电中心"),
|
title: const Text("发电中心"),
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: min / 2,
|
width: min / 2,
|
||||||
|
@ -100,13 +101,16 @@ class _ProScreenState extends State<ProScreen> {
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text("我刚才发了电"),
|
title: const Text("我刚才发了电"),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final code = await inputString(context, "输入代码");
|
var code = await inputString(context, "输入代码");
|
||||||
if (code != null && code.isNotEmpty) {
|
if (code != null) {
|
||||||
try {
|
code = code.trim();
|
||||||
await method.inputCdKey(code);
|
if (code.isNotEmpty) {
|
||||||
defaultToast(context, "SUCCESS");
|
try {
|
||||||
} catch (e, s) {
|
await method.inputCdKey(code);
|
||||||
defaultToast(context, "FAIL");
|
defaultToast(context, "SUCCESS");
|
||||||
|
} catch (e, s) {
|
||||||
|
defaultToast(context, "FAIL");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await reloadIsPro();
|
await reloadIsPro();
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:pikapika/screens/components/NetworkSetting.dart';
|
||||||
import 'package:pikapika/screens/components/RightClickPop.dart';
|
import 'package:pikapika/screens/components/RightClickPop.dart';
|
||||||
|
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
/// 注册页面
|
/// 注册页面
|
||||||
class RegisterScreen extends StatefulWidget {
|
class RegisterScreen extends StatefulWidget {
|
||||||
|
@ -133,7 +134,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: [
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
|
|
@ -10,6 +10,8 @@ import 'package:pikapika/basic/config/ChooserRoot.dart';
|
||||||
import 'package:pikapika/basic/config/ContentFailedReloadAction.dart';
|
import 'package:pikapika/basic/config/ContentFailedReloadAction.dart';
|
||||||
import 'package:pikapika/basic/config/DownloadAndExportPath.dart';
|
import 'package:pikapika/basic/config/DownloadAndExportPath.dart';
|
||||||
import 'package:pikapika/basic/config/DownloadThreadCount.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/ExportRename.dart';
|
||||||
import 'package:pikapika/basic/config/FullScreenAction.dart';
|
import 'package:pikapika/basic/config/FullScreenAction.dart';
|
||||||
import 'package:pikapika/basic/config/FullScreenUI.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/ReaderSliderPosition.dart';
|
||||||
import 'package:pikapika/basic/config/ReaderType.dart';
|
import 'package:pikapika/basic/config/ReaderType.dart';
|
||||||
import 'package:pikapika/basic/config/ShadowCategories.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/ShowCommentAtDownload.dart';
|
||||||
import 'package:pikapika/basic/config/Themes.dart';
|
import 'package:pikapika/basic/config/Themes.dart';
|
||||||
import 'package:pikapika/basic/config/TimeOffsetHour.dart';
|
import 'package:pikapika/basic/config/TimeOffsetHour.dart';
|
||||||
import 'package:pikapika/basic/config/VolumeController.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/NetworkSetting.dart';
|
||||||
import 'package:pikapika/screens/components/RightClickPop.dart';
|
import 'package:pikapika/screens/components/RightClickPop.dart';
|
||||||
|
|
||||||
import '../basic/config/Authentication.dart';
|
import '../basic/config/Authentication.dart';
|
||||||
import '../basic/config/CategoriesColumnCount.dart';
|
import '../basic/config/CategoriesColumnCount.dart';
|
||||||
import '../basic/config/DownloadCachePath.dart';
|
import '../basic/config/DownloadCachePath.dart';
|
||||||
|
import '../basic/config/EBookScrolling.dart';
|
||||||
import '../basic/config/HiddenFdIcon.dart';
|
import '../basic/config/HiddenFdIcon.dart';
|
||||||
import '../basic/config/ImageFilter.dart';
|
import '../basic/config/ImageFilter.dart';
|
||||||
import '../basic/config/UsingRightClickPop.dart';
|
import '../basic/config/UsingRightClickPop.dart';
|
||||||
|
@ -66,175 +69,158 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late var _index = 0;
|
|
||||||
|
|
||||||
Widget buildScreen(BuildContext context) {
|
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(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('设置'),
|
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(
|
body: SingleChildScrollView(
|
||||||
children: iaws[_index].widgets,
|
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(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../basic/config/Themes.dart';
|
import '../basic/config/Themes.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
class ThemeScreen extends StatefulWidget {
|
class ThemeScreen extends StatefulWidget {
|
||||||
|
@ -23,45 +24,45 @@ class _ThemeScreenState extends State<ThemeScreen> {
|
||||||
Widget buildScreen(BuildContext context) {
|
Widget buildScreen(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text("主题设置")),
|
appBar: AppBar(title: const Text("主题设置")),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
children: [
|
children: themeWidgets(context, setState),
|
||||||
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(),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Widget> 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()),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
: [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import '../basic/Entities.dart';
|
||||||
import '../basic/config/IconLoading.dart';
|
import '../basic/config/IconLoading.dart';
|
||||||
import 'ComicInfoScreen.dart';
|
import 'ComicInfoScreen.dart';
|
||||||
import 'components/Images.dart';
|
import 'components/Images.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
|
|
||||||
// 浏览记录
|
// 浏览记录
|
||||||
class ViewLogsScreen extends StatefulWidget {
|
class ViewLogsScreen extends StatefulWidget {
|
||||||
|
@ -137,7 +138,7 @@ class _ViewLogsScreenState extends State<ViewLogsScreen> {
|
||||||
onPressed: _clearAll, icon: const Icon(Icons.auto_delete)),
|
onPressed: _clearAll, icon: const Icon(Icons.auto_delete)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: PikaListView(
|
||||||
physics: _scrollPhysics,
|
physics: _scrollPhysics,
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
children: entries.toList(),
|
children: entries.toList(),
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
import '../basic/Method.dart';
|
import '../basic/Method.dart';
|
||||||
import 'components/ContentError.dart';
|
import 'components/ContentError.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
import 'components/ListView.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
|
||||||
class WebServerScreen extends StatefulWidget {
|
class WebServerScreen extends StatefulWidget {
|
||||||
|
@ -52,7 +53,7 @@ class _WebServerScreenState extends State<WebServerScreen> {
|
||||||
if (snapshot.connectionState != ConnectionState.done) {
|
if (snapshot.connectionState != ConnectionState.done) {
|
||||||
return const ContentLoading(label: '加载中');
|
return const ContentLoading(label: '加载中');
|
||||||
}
|
}
|
||||||
return ListView(
|
return PikaListView(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
|
|
|
@ -12,6 +12,7 @@ import 'package:pikapika/basic/config/ShadowCategoriesMode.dart';
|
||||||
import 'ComicInfoCard.dart';
|
import 'ComicInfoCard.dart';
|
||||||
import 'Images.dart';
|
import 'Images.dart';
|
||||||
import 'LinkToComicInfo.dart';
|
import 'LinkToComicInfo.dart';
|
||||||
|
import 'ListView.dart';
|
||||||
|
|
||||||
class ComicListController {
|
class ComicListController {
|
||||||
_ComicListState? _state;
|
_ComicListState? _state;
|
||||||
|
@ -113,7 +114,7 @@ class _ComicListState extends State<ComicList> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildInfoCardList() {
|
Widget _buildInfoCardList() {
|
||||||
return ListView(
|
return PikaListView(
|
||||||
controller: widget.scrollController,
|
controller: widget.scrollController,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
children: [
|
children: [
|
||||||
|
@ -229,19 +230,24 @@ class _ComicListState extends State<ComicList> {
|
||||||
List<Widget> wraps = [];
|
List<Widget> wraps = [];
|
||||||
List<Widget> tmp = [];
|
List<Widget> tmp = [];
|
||||||
for (var e in widget.comicList) {
|
for (var e in widget.comicList) {
|
||||||
var shadow = e.categories.map(
|
late bool shadow;
|
||||||
(c) {
|
X:
|
||||||
switch (currentShadowCategoriesMode()) {
|
switch (currentShadowCategoriesMode()) {
|
||||||
case ShadowCategoriesMode.BLACK_LIST:
|
case ShadowCategoriesMode.BLACK_LIST:
|
||||||
if (shadowCategories.contains(c)) return true;
|
shadow = e.categories
|
||||||
break;
|
.map((c) => shadowCategories.contains(c))
|
||||||
case ShadowCategoriesMode.WHITE_LIST:
|
.reduce((value, element) => value || element);
|
||||||
if (!shadowCategories.contains(c)) return true;
|
break;
|
||||||
break;
|
case ShadowCategoriesMode.WHITE_LIST:
|
||||||
|
for (var c in e.categories) {
|
||||||
|
if (shadowCategories.contains(c)) {
|
||||||
|
shadow = false;
|
||||||
|
break X;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
shadow = true;
|
||||||
},
|
break;
|
||||||
).reduce((value, element) => value || element);
|
}
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
tmp.add(
|
tmp.add(
|
||||||
Container(
|
Container(
|
||||||
|
@ -317,7 +323,7 @@ class _ComicListState extends State<ComicList> {
|
||||||
tmp = [];
|
tmp = [];
|
||||||
}
|
}
|
||||||
// 返回
|
// 返回
|
||||||
return ListView(
|
return PikaListView(
|
||||||
controller: widget.scrollController,
|
controller: widget.scrollController,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
padding: EdgeInsets.only(top: gap, bottom: gap),
|
padding: EdgeInsets.only(top: gap, bottom: gap),
|
||||||
|
@ -338,19 +344,24 @@ class _ComicListState extends State<ComicList> {
|
||||||
List<Widget> wraps = [];
|
List<Widget> wraps = [];
|
||||||
List<Widget> tmp = [];
|
List<Widget> tmp = [];
|
||||||
for (var e in widget.comicList) {
|
for (var e in widget.comicList) {
|
||||||
var shadow = e.categories.map(
|
late bool shadow;
|
||||||
(c) {
|
X:
|
||||||
switch (currentShadowCategoriesMode()) {
|
switch (currentShadowCategoriesMode()) {
|
||||||
case ShadowCategoriesMode.BLACK_LIST:
|
case ShadowCategoriesMode.BLACK_LIST:
|
||||||
if (shadowCategories.contains(c)) return true;
|
shadow = e.categories
|
||||||
break;
|
.map((c) => shadowCategories.contains(c))
|
||||||
case ShadowCategoriesMode.WHITE_LIST:
|
.reduce((value, element) => value || element);
|
||||||
if (!shadowCategories.contains(c)) return true;
|
break;
|
||||||
break;
|
case ShadowCategoriesMode.WHITE_LIST:
|
||||||
|
for (var c in e.categories) {
|
||||||
|
if (shadowCategories.contains(c)) {
|
||||||
|
shadow = false;
|
||||||
|
break X;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
shadow = true;
|
||||||
},
|
break;
|
||||||
).reduce((value, element) => value || element);
|
}
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
tmp.add(
|
tmp.add(
|
||||||
Container(
|
Container(
|
||||||
|
@ -455,7 +466,7 @@ class _ComicListState extends State<ComicList> {
|
||||||
tmp = [];
|
tmp = [];
|
||||||
}
|
}
|
||||||
// 返回
|
// 返回
|
||||||
return ListView(
|
return PikaListView(
|
||||||
controller: widget.scrollController,
|
controller: widget.scrollController,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
padding: EdgeInsets.only(top: gap, bottom: gap),
|
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"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: file_picker
|
name: file_picker
|
||||||
sha256: dd328189f2f4ccea042bb5b382d5e981691cc74b5a3429b9317bff2b19704489
|
sha256: dcde5ad1a0cebcf3715ea3f24d0db1888bf77027a26c77d7779e8ef63b8ade62
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.2.8"
|
version: "5.2.9"
|
||||||
filesystem_picker:
|
filesystem_picker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -566,10 +566,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_android
|
name: url_launcher_android
|
||||||
sha256: dd729390aa936bf1bdf5cd1bc7468ff340263f80a2c4f569416507667de8e3c8
|
sha256: a52628068d282d01a07cd86e6ba99e497aa45ce8c91159015b2416907d78e411
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.26"
|
version: "6.0.27"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
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.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.7.3+18
|
version: 1.7.4+19
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
|
Loading…
Reference in New Issue