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] 增加了批量导出ZIP/PKI到文件夹
- [x] 增加了从一个文件夹中导入所有ZIP/PKI的功能
- [x] 增加了发电页面, 对作者发过电的用户会展示发电特权图标
计划
- [ ] 本地骑士书签 (漫画书签?/快捷搜索书签?)
- [ ] 将Jasmine导出的PKI/JMI/导入, 阅读Jasmine导出的PKI

View File

@ -875,4 +875,13 @@ class Method {
Future inputCdKey(String 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"
import 'package:flutter/material.dart';
import 'package:pikapika/basic/Common.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> {
late Future<List<Collection>> _future;
late Key _key = UniqueKey();
@override
void initState() {
@ -42,10 +43,12 @@ class _ComicCollectionsScreenState extends State<ComicCollectionsScreen> {
return Scaffold(
appBar: AppBar(title: const Text("推荐")),
body: ContentBuilder(
key: _key,
future: _future,
onRefresh: () async {
setState(() {
_future = method.collections();
_key = UniqueKey();
});
},
successBuilder: (

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,13 +16,6 @@ class RandomComicsScreen extends StatefulWidget {
}
class _RandomComicsScreenState extends State<RandomComicsScreen> {
Future<List<ComicSimple>> _future = method.randomComics();
Future<void> _reload() async {
setState(() {
_future = method.randomComics();
});
}
@override
Widget build(BuildContext context){
@ -42,7 +35,7 @@ class _RandomComicsScreenState extends State<RandomComicsScreen> {
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> {
late Future<List<ComicSimple>> _future = method.leaderboard(widget.type);
Future<void> _reload() async {
setState(() {
_future = method.leaderboard(widget.type);
});
}
@override
Widget build(BuildContext context) {
return ComicListBuilder(_future, _reload);
return ComicListBuilder(() => method.leaderboard(widget.type));
}
}
@ -205,7 +197,7 @@ class _KnightLeaderBoardState extends State<_KnightLeaderBoard> {
onTap: () {
navPushOrReplace(
context,
(context) => ComicsScreen(
(context) => ComicsScreen(
creatorId: e.id,
creatorName: e.name,
),

View File

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

View File

@ -7,17 +7,18 @@ import 'package:pikapika/screens/components/FitButton.dart';
import 'ContentBuilder.dart';
class ComicListBuilder extends StatefulWidget {
final Future<List<ComicSimple>> future;
final Future Function() reload;
final Future<List<ComicSimple>> Function() takeList;
const ComicListBuilder(this.future, this.reload, {Key? key})
: super(key: key);
const ComicListBuilder(this.takeList, {Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _ComicListBuilderState();
}
class _ComicListBuilderState extends State<ComicListBuilder> {
late Future<List<ComicSimple>> _future = widget.takeList();
late Key _key = UniqueKey();
@override
void initState() {
shadowCategoriesEvent.subscribe(_onShadowChange);
@ -34,19 +35,27 @@ class _ComicListBuilderState extends State<ComicListBuilder> {
setState(() {});
}
Future _reload() async {
setState(() {
_future = widget.takeList();
_key = UniqueKey();
});
}
@override
Widget build(BuildContext context) {
return ContentBuilder(
future: widget.future,
onRefresh: widget.reload,
key: _key,
future: _future,
onRefresh: _reload,
successBuilder:
(BuildContext context, AsyncSnapshot<List<ComicSimple>> snapshot) {
return RefreshIndicator(
onRefresh: widget.reload,
onRefresh: _reload,
child: ComicList(
snapshot.data!,
appendWidget: FitButton(
onPressed: widget.reload,
onPressed: _reload,
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/ContentError.dart';
import 'package:pikapika/screens/components/FitButton.dart';
import '../../basic/Common.dart';
import '../../basic/config/IsPro.dart';
import 'ContentLoading.dart';
//
@ -180,6 +182,10 @@ class _ControllerComicPagerState extends State<ControllerComicPager> {
if (num == 0 || num > comicsPage.pages) {
return;
}
if (num > 50 && !isPro) {
defaultToast(context, "发电以后才能看50页以后的内容");
return;
}
_currentPage = num;
_load();
},
@ -212,6 +218,10 @@ class _ControllerComicPagerState extends State<ControllerComicPager> {
minWidth: 0,
onPressed: () {
if (comicsPage.page < comicsPage.pages) {
if (_currentPage >= 50 && !isPro) {
defaultToast(context, "发电以后才能看50页以后的内容");
return;
}
_currentPage = comicsPage.page + 1;
_load();
}
@ -230,6 +240,10 @@ class _ControllerComicPagerState extends State<ControllerComicPager> {
if (comicsPage.page < comicsPage.pages) {
return FitButton(
onPressed: () {
if (_currentPage >= 50 && !isPro) {
defaultToast(context, "发电以后才能看50页以后的内容");
return;
}
_currentPage = comicsPage.page + 1;
_load();
},
@ -254,7 +268,7 @@ class StreamComicPager extends StatefulWidget {
class _StreamComicPagerState extends State<StreamComicPager> {
final TextEditingController _textEditController =
TextEditingController(text: '');
TextEditingController(text: '');
final _scrollController = ScrollController();
late String _currentSort = SORT_DEFAULT;
late int _currentPage = 1;
@ -263,6 +277,7 @@ class _StreamComicPagerState extends State<StreamComicPager> {
late bool _loading = false;
late bool _over = false;
late bool _error = false;
late bool _noPro = false;
// late Future<dynamic> _pageFuture;
@ -273,7 +288,7 @@ class _StreamComicPagerState extends State<StreamComicPager> {
}
void _onScroll() {
if (_over || _error || _loading) {
if (_over || _error || _loading || _noPro) {
return;
}
if (_scrollController.offset + MediaQuery.of(context).size.height / 2 <
@ -302,6 +317,7 @@ class _StreamComicPagerState extends State<StreamComicPager> {
_maxPage = page.pages;
_list.addAll(page.docs);
_over = page.page >= page.pages;
_noPro = _currentPage > 50 && !isPro;
});
} catch (e, s) {
_error = true;
@ -391,7 +407,8 @@ class _StreamComicPagerState extends State<StreamComicPager> {
),
keyboardType: TextInputType.number,
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) {
return;
}
if (_currentPage >= 50 && !isPro) {
defaultToast(context, "发电以后才能看50页以后的内容");
return;
}
_currentPage = num;
_onSetOffset(num);
},
@ -429,7 +450,6 @@ class _StreamComicPagerState extends State<StreamComicPager> {
],
),
),
],
),
],
@ -439,6 +459,9 @@ class _StreamComicPagerState extends State<StreamComicPager> {
}
Widget? _buildLoadingCell() {
if (_noPro) {
return FitButton(onPressed: () {}, text: '发电以后才能看50页以后的内容');
}
if (_error) {
return FitButton(
onPressed: () {

View File

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

View File

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