v1.5.6
This commit is contained in:
parent
7b10874096
commit
37a5523893
|
@ -1 +1 @@
|
|||
v1.5.5
|
||||
v1.5.6
|
|
@ -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
|
||||
|
||||
|
|
|
@ -875,4 +875,13 @@ class Method {
|
|||
Future inputCdKey(String cdKey) {
|
||||
return _flatInvoke("inputCdKey", cdKey);
|
||||
}
|
||||
|
||||
Future reloadSwitchAddress() {
|
||||
return _flatInvoke("reloadSwitchAddress", "");
|
||||
}
|
||||
|
||||
Future resetSwitchAddress() {
|
||||
return _flatInvoke("resetSwitchAddress", "");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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, "分流重制失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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: (
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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: (
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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: '刷新',
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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: () {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -14,6 +14,7 @@ class NetworkSetting extends StatelessWidget {
|
|||
switchAddressSetting(),
|
||||
imageSwitchAddressSetting(),
|
||||
proxySetting(),
|
||||
reloadSwitchAddressSetting(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue