This commit is contained in:
niuhuan 2022-07-12 15:28:47 +08:00
parent 7b10874096
commit 37a5523893
18 changed files with 140 additions and 52 deletions

View File

@ -1 +1 @@
v1.5.5 v1.5.6

View File

@ -1,13 +1,11 @@
更新 v1.5.6
- [x] 从服务器获取最新的分流
- [x] 优化排行榜/骑士榜/以及各个异步加载页的刷新逻辑
v1.5.5
- [x] 对历史记录页面进行优化 - [x] 对历史记录页面进行优化
- [x] 对导入进行优化 - [x] 对导入进行优化
- [x] 增加了批量导出ZIP/PKI到文件夹 - [x] 增加了批量导出ZIP/PKI到文件夹
- [x] 增加了从一个文件夹中导入所有ZIP/PKI的功能 - [x] 增加了从一个文件夹中导入所有ZIP/PKI的功能
- [x] 增加了发电页面, 对作者发过电的用户会展示发电特权图标 - [x] 增加了发电页面, 对作者发过电的用户会展示发电特权图标
计划
- [ ] 本地骑士书签 (漫画书签?/快捷搜索书签?)
- [ ] 将Jasmine导出的PKI/JMI/导入, 阅读Jasmine导出的PKI

View File

@ -875,4 +875,13 @@ class Method {
Future inputCdKey(String cdKey) { Future inputCdKey(String cdKey) {
return _flatInvoke("inputCdKey", cdKey); return _flatInvoke("inputCdKey", cdKey);
} }
Future reloadSwitchAddress() {
return _flatInvoke("reloadSwitchAddress", "");
}
Future resetSwitchAddress() {
return _flatInvoke("resetSwitchAddress", "");
}
} }

View File

@ -5,6 +5,7 @@
// addr = "172.67.208.169:443" // addr = "172.67.208.169:443"
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pikapika/basic/Common.dart';
import '../Method.dart'; import '../Method.dart';
@ -62,3 +63,38 @@ Widget switchAddressSetting() {
}, },
); );
} }
Widget reloadSwitchAddressSetting() {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile(
title: const Text("==== 分流 ===="),
onTap: () async {
String? choose = await chooseListDialog(context, "==== 分流 ====", [
"从服务器获取最新的分流地址",
"重制分流为默认值",
]);
if (choose != null) {
if (choose == "从服务器获取最新的分流地址") {
try {
await method.reloadSwitchAddress();
defaultToast(context, "分流2/3已同步");
} catch (e, s) {
print("$e\$s");
defaultToast(context, "分流同步失败");
}
} else if (choose == "重制分流为默认值") {
try {
await method.resetSwitchAddress();
defaultToast(context, "分流2/3已重制为默认值");
} catch (e, s) {
print("$e\$s");
defaultToast(context, "分流重制失败");
}
}
}
},
);
},
);
}

View File

@ -16,6 +16,7 @@ class ComicCollectionsScreen extends StatefulWidget {
class _ComicCollectionsScreenState extends State<ComicCollectionsScreen> { class _ComicCollectionsScreenState extends State<ComicCollectionsScreen> {
late Future<List<Collection>> _future; late Future<List<Collection>> _future;
late Key _key = UniqueKey();
@override @override
void initState() { void initState() {
@ -42,10 +43,12 @@ class _ComicCollectionsScreenState extends State<ComicCollectionsScreen> {
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text("推荐")), appBar: AppBar(title: const Text("推荐")),
body: ContentBuilder( body: ContentBuilder(
key: _key,
future: _future, future: _future,
onRefresh: () async { onRefresh: () async {
setState(() { setState(() {
_future = method.collections(); _future = method.collections();
_key = UniqueKey();
}); });
}, },
successBuilder: ( successBuilder: (

View File

@ -40,6 +40,7 @@ class CommentScreen extends StatefulWidget {
class _CommentScreenState extends State<CommentScreen> { class _CommentScreenState extends State<CommentScreen> {
late int _currentPage = 1; late int _currentPage = 1;
late Future<_CommentChildPage> _future = _loadPage(); late Future<_CommentChildPage> _future = _loadPage();
late Key _key = UniqueKey();
Future<_CommentChildPage> _loadPage() async { Future<_CommentChildPage> _loadPage() async {
switch (widget.mainType) { switch (widget.mainType) {
@ -60,6 +61,7 @@ class _CommentScreenState extends State<CommentScreen> {
Widget _buildChildrenPager() { Widget _buildChildrenPager() {
return ContentBuilder( return ContentBuilder(
key: _key,
future: _future, future: _future,
onRefresh: _loadPage, onRefresh: _loadPage,
successBuilder: successBuilder:
@ -78,7 +80,7 @@ class _CommentScreenState extends State<CommentScreen> {
} }
@override @override
Widget build(BuildContext context){ Widget build(BuildContext context) {
return rightClickPop( return rightClickPop(
child: buildScreen(context), child: buildScreen(context),
context: context, context: context,
@ -126,6 +128,7 @@ class _CommentScreenState extends State<CommentScreen> {
} }
setState(() { setState(() {
_future = _loadPage(); _future = _loadPage();
_key = UniqueKey();
widget.comment.commentsCount++; widget.comment.commentsCount++;
}); });
} catch (e) { } catch (e) {
@ -163,6 +166,7 @@ class _CommentScreenState extends State<CommentScreen> {
setState(() { setState(() {
_currentPage = page.page - 1; _currentPage = page.page - 1;
_future = _loadPage(); _future = _loadPage();
_key = UniqueKey();
}); });
}, },
child: Container( child: Container(
@ -183,6 +187,7 @@ class _CommentScreenState extends State<CommentScreen> {
setState(() { setState(() {
_currentPage = page.page + 1; _currentPage = page.page + 1;
_future = _loadPage(); _future = _loadPage();
_key = UniqueKey();
}); });
}, },
child: Container( child: Container(

View File

@ -220,7 +220,7 @@ class _DownloadImportScreenState extends State<DownloadImportScreen> {
} }
}, },
child: Text( child: Text(
'选择文件夹\n(导入里面所有的zip)' + (!isPro ? "\n(发电后使用)" : ""), '选择文件夹\n(导入里面所有的zip/pki)' + (!isPro ? "\n(发电后使用)" : ""),
style: TextStyle(), style: TextStyle(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),

View File

@ -19,6 +19,7 @@ class GamesScreen extends StatefulWidget {
class _GamesScreenState extends State<GamesScreen> { class _GamesScreenState extends State<GamesScreen> {
int _currentPage = 1; int _currentPage = 1;
late Future<GamePage> _future = _loadPage(); late Future<GamePage> _future = _loadPage();
late Key _key = UniqueKey();
Future<GamePage> _loadPage() { Future<GamePage> _loadPage() {
return method.games(_currentPage); return method.games(_currentPage);
@ -28,11 +29,12 @@ class _GamesScreenState extends State<GamesScreen> {
setState(() { setState(() {
_currentPage = number; _currentPage = number;
_future = _loadPage(); _future = _loadPage();
_key = UniqueKey();
}); });
} }
@override @override
Widget build(BuildContext context){ Widget build(BuildContext context) {
return rightClickPop( return rightClickPop(
child: buildScreen(context), child: buildScreen(context),
context: context, context: context,
@ -46,6 +48,7 @@ class _GamesScreenState extends State<GamesScreen> {
title: const Text('游戏'), title: const Text('游戏'),
), ),
body: ContentBuilder( body: ContentBuilder(
key: _key,
future: _future, future: _future,
onRefresh: _loadPage, onRefresh: _loadPage,
successBuilder: successBuilder:

View File

@ -17,6 +17,7 @@ class MigrateScreen extends StatefulWidget {
} }
class _MigrateScreenState extends State<MigrateScreen> { class _MigrateScreenState extends State<MigrateScreen> {
late final Key _key = UniqueKey();
late final Future _future = _load(); late final Future _future = _load();
late String _current; late String _current;
late List<String> paths; late List<String> paths;
@ -47,6 +48,7 @@ class _MigrateScreenState extends State<MigrateScreen> {
title: const Text('数据迁移'), title: const Text('数据迁移'),
), ),
body: ContentBuilder( body: ContentBuilder(
key: _key,
future: _future, future: _future,
onRefresh: () async {}, onRefresh: () async {},
successBuilder: successBuilder:

View File

@ -33,6 +33,7 @@ class _PkzArchiveScreenState extends State<PkzArchiveScreen> with RouteAware {
Map<String, PkzComicViewLog> _logMap = {}; Map<String, PkzComicViewLog> _logMap = {};
late String _fileName; late String _fileName;
late Future _future; late Future _future;
late Key _key;
late PkzArchive _info; late PkzArchive _info;
StreamSubscription<String?>? _linkSubscription; StreamSubscription<String?>? _linkSubscription;
@ -43,6 +44,7 @@ class _PkzArchiveScreenState extends State<PkzArchiveScreen> with RouteAware {
} }
_fileName = p.basename(widget.pkzPath); _fileName = p.basename(widget.pkzPath);
_future = _load(); _future = _load();
_key = UniqueKey();
super.initState(); super.initState();
} }
@ -99,10 +101,12 @@ class _PkzArchiveScreenState extends State<PkzArchiveScreen> with RouteAware {
title: Text(_fileName), title: Text(_fileName),
), ),
body: ContentBuilder( body: ContentBuilder(
key: _key,
future: _future, future: _future,
onRefresh: () async { onRefresh: () async {
setState(() { setState(() {
_future = _load(); _future = _load();
_key = UniqueKey();
}); });
}, },
successBuilder: ( successBuilder: (

View File

@ -57,6 +57,16 @@ class _ProScreenState extends State<ProScreen> {
), ),
), ),
const Divider(), const Divider(),
const Padding(
padding: EdgeInsets.all(20),
child: Text(
"发电小功能 \n"
" 多线程下载\n"
" 批量导入导出\n"
" 跳页",
),
),
const Divider(),
ListTile( ListTile(
title: const Text("发电详情"), title: const Text("发电详情"),
subtitle: Text( subtitle: Text(

View File

@ -16,13 +16,6 @@ class RandomComicsScreen extends StatefulWidget {
} }
class _RandomComicsScreenState extends State<RandomComicsScreen> { class _RandomComicsScreenState extends State<RandomComicsScreen> {
Future<List<ComicSimple>> _future = method.randomComics();
Future<void> _reload() async {
setState(() {
_future = method.randomComics();
});
}
@override @override
Widget build(BuildContext context){ Widget build(BuildContext context){
@ -42,7 +35,7 @@ class _RandomComicsScreenState extends State<RandomComicsScreen> {
chooseLayoutActionButton(context), chooseLayoutActionButton(context),
], ],
), ),
body: ComicListBuilder(_future, _reload), body: ComicListBuilder(method.randomComics),
); );
} }
} }

View File

@ -81,17 +81,9 @@ class _Leaderboard extends StatefulWidget {
} }
class _LeaderboardState extends State<_Leaderboard> { class _LeaderboardState extends State<_Leaderboard> {
late Future<List<ComicSimple>> _future = method.leaderboard(widget.type);
Future<void> _reload() async {
setState(() {
_future = method.leaderboard(widget.type);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ComicListBuilder(_future, _reload); return ComicListBuilder(() => method.leaderboard(widget.type));
} }
} }

View File

@ -131,13 +131,13 @@ class _RegisterScreenState extends State<RegisterScreen> {
children: [ children: [
const Divider(), const Divider(),
ListTile( ListTile(
title: const Text("账号 (不一定是邮箱/登录使用)"), title: const Text("账号 (小写字母+数字/登录使用)"),
subtitle: Text(_email == "" ? "未设置" : _email), subtitle: Text(_email == "" ? "未设置" : _email),
onTap: () async { onTap: () async {
String? input = await displayTextInputDialog( String? input = await displayTextInputDialog(
context, context,
src: _email, src: _email,
title: '账号', title: '账号 (小写字母+数字/登录使用)',
hint: '请输入账号', hint: '请输入账号',
); );
if (input != null) { if (input != null) {
@ -148,13 +148,13 @@ class _RegisterScreenState extends State<RegisterScreen> {
}, },
), ),
ListTile( ListTile(
title: const Text("密码 (8位以上)"), title: const Text("密码 (大小写字母+数字/8位以上)"),
subtitle: Text(_password == "" ? "未设置" : '\u2022' * 10), subtitle: Text(_password == "" ? "未设置" : '\u2022' * 10),
onTap: () async { onTap: () async {
String? input = await displayTextInputDialog( String? input = await displayTextInputDialog(
context, context,
src: _password, src: _password,
title: '密码', title: '密码 (大小写字母+数字/8位以上)',
hint: '请输入密码', hint: '请输入密码',
isPasswd: true, isPasswd: true,
); );
@ -166,7 +166,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
}, },
), ),
ListTile( ListTile(
title: const Text("昵称 (2-50字)"), title: const Text("昵称 (可使用中文/2-50字)"),
subtitle: Text(_name == "" ? "未设置" : _name), subtitle: Text(_name == "" ? "未设置" : _name),
onTap: () async { onTap: () async {
String? input = await displayTextInputDialog( String? input = await displayTextInputDialog(

View File

@ -7,17 +7,18 @@ import 'package:pikapika/screens/components/FitButton.dart';
import 'ContentBuilder.dart'; import 'ContentBuilder.dart';
class ComicListBuilder extends StatefulWidget { class ComicListBuilder extends StatefulWidget {
final Future<List<ComicSimple>> future; final Future<List<ComicSimple>> Function() takeList;
final Future Function() reload;
const ComicListBuilder(this.future, this.reload, {Key? key}) const ComicListBuilder(this.takeList, {Key? key}) : super(key: key);
: super(key: key);
@override @override
State<StatefulWidget> createState() => _ComicListBuilderState(); State<StatefulWidget> createState() => _ComicListBuilderState();
} }
class _ComicListBuilderState extends State<ComicListBuilder> { class _ComicListBuilderState extends State<ComicListBuilder> {
late Future<List<ComicSimple>> _future = widget.takeList();
late Key _key = UniqueKey();
@override @override
void initState() { void initState() {
shadowCategoriesEvent.subscribe(_onShadowChange); shadowCategoriesEvent.subscribe(_onShadowChange);
@ -34,19 +35,27 @@ class _ComicListBuilderState extends State<ComicListBuilder> {
setState(() {}); setState(() {});
} }
Future _reload() async {
setState(() {
_future = widget.takeList();
_key = UniqueKey();
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ContentBuilder( return ContentBuilder(
future: widget.future, key: _key,
onRefresh: widget.reload, future: _future,
onRefresh: _reload,
successBuilder: successBuilder:
(BuildContext context, AsyncSnapshot<List<ComicSimple>> snapshot) { (BuildContext context, AsyncSnapshot<List<ComicSimple>> snapshot) {
return RefreshIndicator( return RefreshIndicator(
onRefresh: widget.reload, onRefresh: _reload,
child: ComicList( child: ComicList(
snapshot.data!, snapshot.data!,
appendWidget: FitButton( appendWidget: FitButton(
onPressed: widget.reload, onPressed: _reload,
text: '刷新', text: '刷新',
), ),
), ),

View File

@ -8,6 +8,8 @@ import 'package:pikapika/basic/enum/Sort.dart';
import 'package:pikapika/screens/components/ComicList.dart'; import 'package:pikapika/screens/components/ComicList.dart';
import 'package:pikapika/screens/components/ContentError.dart'; import 'package:pikapika/screens/components/ContentError.dart';
import 'package:pikapika/screens/components/FitButton.dart'; import 'package:pikapika/screens/components/FitButton.dart';
import '../../basic/Common.dart';
import '../../basic/config/IsPro.dart';
import 'ContentLoading.dart'; import 'ContentLoading.dart';
// //
@ -180,6 +182,10 @@ class _ControllerComicPagerState extends State<ControllerComicPager> {
if (num == 0 || num > comicsPage.pages) { if (num == 0 || num > comicsPage.pages) {
return; return;
} }
if (num > 50 && !isPro) {
defaultToast(context, "发电以后才能看50页以后的内容");
return;
}
_currentPage = num; _currentPage = num;
_load(); _load();
}, },
@ -212,6 +218,10 @@ class _ControllerComicPagerState extends State<ControllerComicPager> {
minWidth: 0, minWidth: 0,
onPressed: () { onPressed: () {
if (comicsPage.page < comicsPage.pages) { if (comicsPage.page < comicsPage.pages) {
if (_currentPage >= 50 && !isPro) {
defaultToast(context, "发电以后才能看50页以后的内容");
return;
}
_currentPage = comicsPage.page + 1; _currentPage = comicsPage.page + 1;
_load(); _load();
} }
@ -230,6 +240,10 @@ class _ControllerComicPagerState extends State<ControllerComicPager> {
if (comicsPage.page < comicsPage.pages) { if (comicsPage.page < comicsPage.pages) {
return FitButton( return FitButton(
onPressed: () { onPressed: () {
if (_currentPage >= 50 && !isPro) {
defaultToast(context, "发电以后才能看50页以后的内容");
return;
}
_currentPage = comicsPage.page + 1; _currentPage = comicsPage.page + 1;
_load(); _load();
}, },
@ -263,6 +277,7 @@ class _StreamComicPagerState extends State<StreamComicPager> {
late bool _loading = false; late bool _loading = false;
late bool _over = false; late bool _over = false;
late bool _error = false; late bool _error = false;
late bool _noPro = false;
// late Future<dynamic> _pageFuture; // late Future<dynamic> _pageFuture;
@ -273,7 +288,7 @@ class _StreamComicPagerState extends State<StreamComicPager> {
} }
void _onScroll() { void _onScroll() {
if (_over || _error || _loading) { if (_over || _error || _loading || _noPro) {
return; return;
} }
if (_scrollController.offset + MediaQuery.of(context).size.height / 2 < if (_scrollController.offset + MediaQuery.of(context).size.height / 2 <
@ -302,6 +317,7 @@ class _StreamComicPagerState extends State<StreamComicPager> {
_maxPage = page.pages; _maxPage = page.pages;
_list.addAll(page.docs); _list.addAll(page.docs);
_over = page.page >= page.pages; _over = page.page >= page.pages;
_noPro = _currentPage > 50 && !isPro;
}); });
} catch (e, s) { } catch (e, s) {
_error = true; _error = true;
@ -391,7 +407,8 @@ class _StreamComicPagerState extends State<StreamComicPager> {
), ),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[ inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'\d+')), FilteringTextInputFormatter.allow(
RegExp(r'\d+')),
], ],
), ),
), ),
@ -413,6 +430,10 @@ class _StreamComicPagerState extends State<StreamComicPager> {
if (num == 0 || num > _maxPage) { if (num == 0 || num > _maxPage) {
return; return;
} }
if (_currentPage >= 50 && !isPro) {
defaultToast(context, "发电以后才能看50页以后的内容");
return;
}
_currentPage = num; _currentPage = num;
_onSetOffset(num); _onSetOffset(num);
}, },
@ -429,7 +450,6 @@ class _StreamComicPagerState extends State<StreamComicPager> {
], ],
), ),
), ),
], ],
), ),
], ],
@ -439,6 +459,9 @@ class _StreamComicPagerState extends State<StreamComicPager> {
} }
Widget? _buildLoadingCell() { Widget? _buildLoadingCell() {
if (_noPro) {
return FitButton(onPressed: () {}, text: '发电以后才能看50页以后的内容');
}
if (_error) { if (_error) {
return FitButton( return FitButton(
onPressed: () { onPressed: () {

View File

@ -7,12 +7,12 @@ class ContentBuilder<T> extends StatelessWidget {
final Future<dynamic> Function() onRefresh; final Future<dynamic> Function() onRefresh;
final AsyncWidgetBuilder<T> successBuilder; final AsyncWidgetBuilder<T> successBuilder;
const ContentBuilder( const ContentBuilder({
{Key? key, required Key? key,
required this.future, required this.future,
required this.onRefresh, required this.onRefresh,
required this.successBuilder}) required this.successBuilder,
: super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -14,6 +14,7 @@ class NetworkSetting extends StatelessWidget {
switchAddressSetting(), switchAddressSetting(),
imageSwitchAddressSetting(), imageSwitchAddressSetting(),
proxySetting(), proxySetting(),
reloadSwitchAddressSetting(),
], ],
); );
} }