♻️ Permisson rewrite
This commit is contained in:
parent
2c30885bc3
commit
4a2489dcf4
16
README.md
16
README.md
|
@ -89,21 +89,11 @@ VPN->代理->分流, 这三个功能如果同时设置, 您会在您手机的VPN
|
|||
|
||||
## 请您遵守使用规则
|
||||
|
||||
本文中提到的本软件拓展包括但是不限于以下内容
|
||||
软件副本分发以及代码使用规则
|
||||
|
||||
- 使用本软件进行继续开发形成的软件。
|
||||
- 引入本软件部分内容为依赖/使用本软件内代码的同时包含本软件内一致内容或功能。
|
||||
- 直接对本软件进行打包发布
|
||||
|
||||
软件副本分发以及代码使用规则规则
|
||||
|
||||
- 本软件仅供学习交流使用, 本软件或本软件的拓展, 个人或企业不可用于商业用途, 不可上架任何商店。
|
||||
- 本软件的拓展在未经允许的情况下可以自用但不允许释放任何releases。
|
||||
- 本软件的代码在未经允许的情况下可以自用但不允许释放任何releases, 个人或企业不可用于商业用途, 不可上架任何商店。。
|
||||
- 不要在任何其他 **二次元软件** 的 **聊天社区** 或 **开发社区** 内, 发布有关本软件的链接或信息, 对于观点不同产生的分歧作者不站队任何立场。
|
||||
- 不要发送本软件安装包到 **任何社区内** , 不要将APK/IPA/ZIP/DMG发送包括任何聊天软件内的群聊功能。 分享本软件时, 在社区中使用Github中提供的Releases页面的链接, 或使用私聊窗口发送。
|
||||
|
||||
源代码使用规则
|
||||
|
||||
- 不要发送本软件安装包到 **任何社区内** , 不要将APK/IPA/ZIP/DMG发送包括任何聊天软件内的群聊功能。 请使用Github中提供的Releases页面的链接。
|
||||
- 对本仓库的fork需要保留本仓库的链接, 以引导用户在主要仓库进行讨论。
|
||||
|
||||
责任声明
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
v1.7.2
|
||||
- [x] 🐛 修复安卓13导入导出的问题
|
||||
- [x] 🐛 修复测速不好用的问题
|
||||
- [x] ♻️ 梳理一些权限
|
||||
- [x] ✨ 增加批量下载功能
|
||||
- [x] ✨ 增加PAT入会发电
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
|
||||
import 'package:pikapika/screens/AccessKeyReplaceScreen.dart';
|
||||
import 'package:uni_links/uni_links.dart';
|
||||
import 'package:uri_to_file/uri_to_file.dart';
|
||||
|
||||
|
@ -300,7 +301,17 @@ StreamSubscription<String?> linkSubscript(BuildContext context) {
|
|||
return linkStream.listen((uri) async {
|
||||
if (uri == null) return;
|
||||
var parsed = Uri.parse(uri);
|
||||
if (RegExp(r"^pika://comic/([0-9A-z]+)/$").allMatches(uri).isNotEmpty) {
|
||||
if (RegExp(r"^pika://access_key/([0-9A-z:\-]+)/$").allMatches(uri).isNotEmpty) {
|
||||
String accessKey = RegExp(r"^pika://access_key/([0-9A-z:\-]+)/$")
|
||||
.allMatches(uri)
|
||||
.first
|
||||
.group(1)!;
|
||||
Navigator.of(context).push(
|
||||
mixRoute(
|
||||
builder: (BuildContext context) => AccessKeyReplaceScreen(accessKey: accessKey),
|
||||
),
|
||||
);
|
||||
} else if (RegExp(r"^pika://comic/([0-9A-z]+)/$").allMatches(uri).isNotEmpty) {
|
||||
String comicId = RegExp(r"^pika://comic/([0-9A-z]+)/$")
|
||||
.allMatches(uri)
|
||||
.first
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:file_picker/file_picker.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:pikapika/basic/Common.dart';
|
||||
import 'package:pikapika/basic/config/Platform.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import 'Method.dart';
|
||||
|
@ -68,8 +69,13 @@ Future<dynamic> saveImageQuiet(String path, BuildContext context) async {
|
|||
}
|
||||
|
||||
Future<dynamic> _saveImageAndroid(String path, BuildContext context) async {
|
||||
var p = await Permission.storage.request();
|
||||
if (!p.isGranted) {
|
||||
late bool g;
|
||||
if (androidVersion < 30) {
|
||||
g = await Permission.storage.request().isGranted;
|
||||
}else{
|
||||
g = await Permission.manageExternalStorage.request().isGranted;
|
||||
}
|
||||
if (!g) {
|
||||
return;
|
||||
}
|
||||
return method.androidSaveFileToImage(path);
|
||||
|
|
|
@ -1065,6 +1065,7 @@ class ProInfoPat {
|
|||
required this.reBind,
|
||||
required this.errorType,
|
||||
required this.errorMsg,
|
||||
required this.accessKey,
|
||||
});
|
||||
late final bool isPro;
|
||||
late final String patId;
|
||||
|
@ -1073,6 +1074,7 @@ class ProInfoPat {
|
|||
late final int reBind;
|
||||
late final int errorType;
|
||||
late final String errorMsg;
|
||||
late final String accessKey;
|
||||
|
||||
ProInfoPat.fromJson(Map<String, dynamic> json){
|
||||
isPro = json['is_pro'];
|
||||
|
@ -1082,6 +1084,7 @@ class ProInfoPat {
|
|||
reBind = json['re_bind'];
|
||||
errorType = json['error_type'];
|
||||
errorMsg = json['error_msg'];
|
||||
accessKey = json['access_key'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
@ -1093,6 +1096,7 @@ class ProInfoPat {
|
|||
_data['re_bind'] = reBind;
|
||||
_data['error_type'] = errorType;
|
||||
_data['error_msg'] = errorMsg;
|
||||
_data['access_key'] = accessKey;
|
||||
return _data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1013,4 +1013,20 @@ class Method {
|
|||
Future downloadAll(List<String> comicIds) {
|
||||
return _flatInvoke("downloadAll", comicIds);
|
||||
}
|
||||
|
||||
Future setPatAccessKey(String accessKey) {
|
||||
return _flatInvoke("setPatAccessKey", accessKey);
|
||||
}
|
||||
|
||||
Future reloadPatAccount() {
|
||||
return _flatInvoke("reloadPatAccount", "");
|
||||
}
|
||||
|
||||
Future bindThisAccount() {
|
||||
return _flatInvoke("bindThisAccount", "");
|
||||
}
|
||||
|
||||
Future clearPat() {
|
||||
return _flatInvoke("clearPat", "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:permission_handler/permission_handler.dart';
|
|||
|
||||
import '../Common.dart';
|
||||
import '../Method.dart';
|
||||
import 'Platform.dart';
|
||||
|
||||
const _propertyName = "chooserRoot";
|
||||
late String _chooserRoot;
|
||||
|
@ -30,7 +31,13 @@ Future<dynamic> initChooserRoot() async {
|
|||
|
||||
Future<String> currentChooserRoot() async {
|
||||
if (Platform.isAndroid) {
|
||||
if (!(await Permission.storage.request()).isGranted) {
|
||||
late bool g;
|
||||
if (androidVersion < 30) {
|
||||
g = await Permission.storage.request().isGranted;
|
||||
}else{
|
||||
g = await Permission.manageExternalStorage.request().isGranted;
|
||||
}
|
||||
if (!g) {
|
||||
throw Exception("申请权限被拒绝");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:permission_handler/permission_handler.dart';
|
||||
import '../Cross.dart';
|
||||
import '../Method.dart';
|
||||
import 'Platform.dart';
|
||||
|
||||
const _propertyName = "exportPath";
|
||||
late String _exportPath;
|
||||
|
@ -35,7 +36,13 @@ Future<String> attachExportPath() async {
|
|||
path = await method.iosGetDocumentDir();
|
||||
} else {
|
||||
if (Platform.isAndroid) {
|
||||
if (!(await Permission.storage.request()).isGranted) {
|
||||
late bool g;
|
||||
if (androidVersion < 30) {
|
||||
g = await Permission.storage.request().isGranted;
|
||||
}else{
|
||||
g = await Permission.manageExternalStorage.request().isGranted;
|
||||
}
|
||||
if (!g) {
|
||||
throw Exception("申请权限被拒绝");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:pikapika/basic/Method.dart';
|
||||
import 'package:pikapika/screens/components/ContentLoading.dart';
|
||||
|
||||
import '../basic/config/IsPro.dart';
|
||||
|
||||
class AccessKeyReplaceScreen extends StatefulWidget {
|
||||
final String accessKey;
|
||||
|
||||
const AccessKeyReplaceScreen({Key? key, required this.accessKey})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _AccessKeyReplaceScreenState();
|
||||
}
|
||||
|
||||
class _AccessKeyReplaceScreenState extends State<AccessKeyReplaceScreen> {
|
||||
var _loading = false;
|
||||
var _message = "";
|
||||
var _success = false;
|
||||
|
||||
_set() async {
|
||||
setState(() {
|
||||
_loading = true;
|
||||
});
|
||||
try {
|
||||
await method.setPatAccessKey(widget.accessKey);
|
||||
await reloadIsPro();
|
||||
_success = true;
|
||||
} catch (e) {
|
||||
_message = "错误 : $e";
|
||||
} finally {
|
||||
setState(() {
|
||||
_loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget _content() {
|
||||
if (_loading) {
|
||||
return const ContentLoading(label: "加载中");
|
||||
}
|
||||
if (_success) {
|
||||
return const Text("您的赞助登录成功, 请返回");
|
||||
}
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(child: Container()),
|
||||
Text(widget.accessKey),
|
||||
Text(_message),
|
||||
Container(
|
||||
height: 10,
|
||||
),
|
||||
MaterialButton(
|
||||
color: Colors.grey,
|
||||
onPressed: _set,
|
||||
child: const Text("确认"),
|
||||
),
|
||||
Expanded(child: Container()),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("更换PAT账户"),
|
||||
),
|
||||
body: Center(
|
||||
child: _content(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -160,7 +160,11 @@ class _ComicsScreenState extends State<ComicsScreen> {
|
|||
appBar = AppBar(
|
||||
title: Text(title),
|
||||
actions: [
|
||||
commonPopMenu(context),
|
||||
commonPopMenu(
|
||||
context,
|
||||
setState: setState,
|
||||
comicListController: _comicListController,
|
||||
),
|
||||
addressPopMenu(context),
|
||||
_chooseCategoryAction(),
|
||||
],
|
||||
|
|
|
@ -37,6 +37,7 @@ import 'package:pikapika/basic/config/Version.dart';
|
|||
import 'package:pikapika/basic/config/VolumeController.dart';
|
||||
import 'package:pikapika/basic/config/ShadowCategoriesMode.dart';
|
||||
import 'package:pikapika/basic/config/WillPopNotice.dart';
|
||||
import 'package:pikapika/screens/AccessKeyReplaceScreen.dart';
|
||||
import 'package:pikapika/screens/ComicInfoScreen.dart';
|
||||
import 'package:pikapika/screens/PkzArchiveScreen.dart';
|
||||
import 'package:uni_links/uni_links.dart';
|
||||
|
@ -126,15 +127,37 @@ class _InitScreenState extends State<InitScreen> {
|
|||
}
|
||||
if (initUrl != null) {
|
||||
var parsed = Uri.parse(initUrl!);
|
||||
if (RegExp(r"^pika://comic/([0-9A-z]+)/$").allMatches(initUrl!).isNotEmpty) {
|
||||
String comicId = RegExp(r"^pika://comic/([0-9A-z]+)/$").allMatches(initUrl!).first.group(1)!;
|
||||
if (RegExp(r"^pika://access_key/([0-9A-z:\-]+)/$")
|
||||
.allMatches(initUrl!)
|
||||
.isNotEmpty) {
|
||||
String accessKey = RegExp(r"^pika://access_key/([0-9A-z:\-]+)/$")
|
||||
.allMatches(initUrl!)
|
||||
.first
|
||||
.group(1)!;
|
||||
Navigator.of(context).pushReplacement(mixRoute(
|
||||
builder: (BuildContext context) =>
|
||||
AccessKeyReplaceScreen(accessKey: accessKey),
|
||||
));
|
||||
return;
|
||||
} else if (RegExp(r"^pika://comic/([0-9A-z]+)/$")
|
||||
.allMatches(initUrl!)
|
||||
.isNotEmpty) {
|
||||
String comicId = RegExp(r"^pika://comic/([0-9A-z]+)/$")
|
||||
.allMatches(initUrl!)
|
||||
.first
|
||||
.group(1)!;
|
||||
Navigator.of(context).pushReplacement(mixRoute(
|
||||
builder: (BuildContext context) =>
|
||||
ComicInfoScreen(comicId: comicId, holdPkz: true),
|
||||
));
|
||||
return;
|
||||
} if (RegExp(r"^https?://pika/comic/([0-9A-z]+)/$").allMatches(initUrl!).isNotEmpty) {
|
||||
String comicId = RegExp(r"^https?://pika/comic/([0-9A-z]+)/$").allMatches(initUrl!).first.group(1)!;
|
||||
} else if (RegExp(r"^https?://pika/comic/([0-9A-z]+)/$")
|
||||
.allMatches(initUrl!)
|
||||
.isNotEmpty) {
|
||||
String comicId = RegExp(r"^https?://pika/comic/([0-9A-z]+)/$")
|
||||
.allMatches(initUrl!)
|
||||
.first
|
||||
.group(1)!;
|
||||
Navigator.of(context).pushReplacement(mixRoute(
|
||||
builder: (BuildContext context) =>
|
||||
ComicInfoScreen(comicId: comicId, holdPkz: true),
|
||||
|
@ -147,7 +170,9 @@ class _InitScreenState extends State<InitScreen> {
|
|||
PkzArchiveScreen(pkzPath: file.path, holdPkz: true),
|
||||
));
|
||||
return;
|
||||
} else if (RegExp(r"^.*\.((pki)|(zip))$").allMatches(parsed.path).isNotEmpty) {
|
||||
} else if (RegExp(r"^.*\.((pki)|(zip))$")
|
||||
.allMatches(parsed.path)
|
||||
.isNotEmpty) {
|
||||
File file = await toFile(initUrl!);
|
||||
Navigator.of(context).pushReplacement(
|
||||
mixRoute(
|
||||
|
|
|
@ -14,6 +14,7 @@ import 'package:uri_to_file/uri_to_file.dart';
|
|||
import '../basic/Common.dart';
|
||||
import '../basic/Navigator.dart';
|
||||
import '../basic/config/IconLoading.dart';
|
||||
import '../basic/config/Platform.dart';
|
||||
import 'PkzComicInfoScreen.dart';
|
||||
|
||||
class PkzArchiveScreen extends StatefulWidget {
|
||||
|
@ -75,10 +76,17 @@ class _PkzArchiveScreenState extends State<PkzArchiveScreen> with RouteAware {
|
|||
|
||||
Future _load() async {
|
||||
await method.viewPkz(_fileName, widget.pkzPath);
|
||||
var p = await Permission.storage.request();
|
||||
if (!p.isGranted) {
|
||||
if (Platform.isAndroid) {
|
||||
late bool g;
|
||||
if (androidVersion < 30) {
|
||||
g = await Permission.storage.request().isGranted;
|
||||
}else{
|
||||
g = await Permission.manageExternalStorage.request().isGranted;
|
||||
}
|
||||
if (!g) {
|
||||
throw 'error permission';
|
||||
}
|
||||
}
|
||||
_info = await method.pkzInfo(widget.pkzPath);
|
||||
if (_info.comics.length == 1) {
|
||||
Navigator.of(context).pushReplacement(mixRoute(
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:pikapika/basic/Common.dart';
|
||||
import 'package:pikapika/basic/Method.dart';
|
||||
import 'package:pikapika/screens/AccessKeyReplaceScreen.dart';
|
||||
|
||||
import '../basic/config/IconLoading.dart';
|
||||
import '../basic/config/IsPro.dart';
|
||||
|
||||
class ProScreen extends StatefulWidget {
|
||||
|
@ -21,9 +26,20 @@ class _ProScreenState extends State<ProScreen> {
|
|||
_username = value;
|
||||
});
|
||||
});
|
||||
proEvent.subscribe(_setState);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
proEvent.unsubscribe(_setState);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
_setState(_) {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var size = MediaQuery.of(context).size;
|
||||
|
@ -51,43 +67,25 @@ class _ProScreenState extends State<ProScreen> {
|
|||
const Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Text(
|
||||
"点击\"我曾经发过电\"进同步发电状态\n"
|
||||
"点击\"我刚才发了电\"兑换作者给您的礼物卡\n"
|
||||
"去\"关于\"界面找到维护地址用爱发电",
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Text(
|
||||
"发电小功能 \n"
|
||||
" 多线程下载\n"
|
||||
" 批量导入导出\n"
|
||||
" 跳页",
|
||||
"去\"关于\"界面找到维护地址可获得发电指引\n\n"
|
||||
"1. \"签到/游戏/兑换\" \n"
|
||||
" (1). \"我曾经发过电\"可同步相应发电状态\n"
|
||||
" (2). \"我刚才发了电\"兑换作者给您的礼物卡\n"
|
||||
"\n"
|
||||
"2. \"PAT入会\"\n"
|
||||
" 🔗将社区账号链接到软件, 同步成员状态, 订阅式发电"
|
||||
"",
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
title: const Text("签到或礼物卡"),
|
||||
title: const Text("签到/游戏/兑换"),
|
||||
subtitle: Text(
|
||||
proInfoAf.isPro
|
||||
? "发电中 (${DateTime.fromMillisecondsSinceEpoch(1000 * proInfoAf.expire).toString()})"
|
||||
: "未发电",
|
||||
),
|
||||
),
|
||||
...(proInfoPat.patId.isNotEmpty ? [
|
||||
ListTile(
|
||||
onTap: () {
|
||||
managementPat();
|
||||
},
|
||||
title: const Text("P站支持"),
|
||||
subtitle: Text((
|
||||
proInfoPat.isPro
|
||||
? "发电中"
|
||||
: "未发电") + ("(点击管理)"),
|
||||
),
|
||||
),
|
||||
] : []),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
title: const Text("我曾经发过电"),
|
||||
|
@ -120,12 +118,156 @@ class _ProScreenState extends State<ProScreen> {
|
|||
},
|
||||
),
|
||||
const Divider(),
|
||||
...patPro(),
|
||||
const Divider(),
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Text(
|
||||
"发电小功能 \n"
|
||||
" 多线程下载\n"
|
||||
" 批量导入导出\n"
|
||||
" 跳页",
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
const Divider(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void managementPat() {
|
||||
// todo
|
||||
List<Widget> patPro() {
|
||||
List<Widget> widgets = [];
|
||||
if (proInfoPat.accessKey.isNotEmpty) {
|
||||
var text = "密钥 : 已录入";
|
||||
if (proInfoPat.patId.isNotEmpty) {
|
||||
text += "\nPAT账号 : ${proInfoPat.patId}";
|
||||
}
|
||||
if (proInfoPat.bindUid.isNotEmpty) {
|
||||
text += "\n绑定PIKA账号 : ${proInfoPat.bindUid}";
|
||||
}
|
||||
if (proInfoPat.requestDelete > 0) {
|
||||
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||
proInfoPat.requestDelete * 1000,
|
||||
isUtc: true,
|
||||
);
|
||||
String formattedDate =
|
||||
DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime.toLocal());
|
||||
text += "\n绑定账号时间 : $formattedDate";
|
||||
}
|
||||
if (proInfoPat.reBind > 0) {
|
||||
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(
|
||||
proInfoPat.reBind * 1000,
|
||||
isUtc: true,
|
||||
);
|
||||
String formattedDate =
|
||||
DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime.toLocal());
|
||||
text += "\n可以换绑时间 : $formattedDate";
|
||||
}
|
||||
List<TextSpan> append = [];
|
||||
if (proInfoPat.bindUid == "") {
|
||||
append.add(const TextSpan(
|
||||
text: "\n(请点击这里绑定到当前账号发电)",
|
||||
style: TextStyle(color: Colors.blue),
|
||||
));
|
||||
} else if (proInfoPat.bindUid != _username) {
|
||||
append.add(const TextSpan(
|
||||
text: "\n(请点换绑到当前账号发电)",
|
||||
style: TextStyle(color: Colors.red),
|
||||
));
|
||||
} else if (proInfoPat.isPro == false) {
|
||||
append.add(const TextSpan(
|
||||
text: "\n(未检测到入会, 请到下载页入会)",
|
||||
style: TextStyle(color: Colors.orange),
|
||||
));
|
||||
} else {
|
||||
append.add(const TextSpan(
|
||||
text: "\n(PAT正常)",
|
||||
style: TextStyle(color: Colors.green),
|
||||
));
|
||||
}
|
||||
widgets.add(ListTile(
|
||||
onTap: () async {
|
||||
print(jsonEncode(proInfoPat));
|
||||
var choose = await chooseMapDialog<int>(
|
||||
context,
|
||||
{
|
||||
"更新PAT发电状态": 2,
|
||||
"绑定到此账号": 3,
|
||||
"更换PAT密钥": 1,
|
||||
"清除PAT信息": 4,
|
||||
},
|
||||
"请选择",
|
||||
);
|
||||
switch (choose) {
|
||||
case 1:
|
||||
addPatAccount();
|
||||
break;
|
||||
case 2:
|
||||
reloadPatAccount();
|
||||
break;
|
||||
case 3:
|
||||
bindThisAccount();
|
||||
break;
|
||||
case 4:
|
||||
clearPat();
|
||||
break;
|
||||
}
|
||||
},
|
||||
title: const Text("PAT入会"),
|
||||
subtitle: Text.rich(TextSpan(children: [
|
||||
TextSpan(text: text),
|
||||
...append,
|
||||
])),
|
||||
));
|
||||
} else {
|
||||
widgets.add(ListTile(
|
||||
onTap: () {
|
||||
addPatAccount();
|
||||
},
|
||||
title: const Text("PAT入会"),
|
||||
subtitle: const Text("点击绑定"),
|
||||
));
|
||||
}
|
||||
return widgets;
|
||||
}
|
||||
|
||||
void addPatAccount() async {
|
||||
print(jsonEncode(proInfoPat));
|
||||
String? key = await inputString(context, "请输入授权代码");
|
||||
if (key != null) {
|
||||
await Navigator.of(context)
|
||||
.push(mixRoute(builder: (BuildContext context) {
|
||||
return AccessKeyReplaceScreen(accessKey: key);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
reloadPatAccount() async {
|
||||
defaultToast(context, "请稍后");
|
||||
try {
|
||||
await method.reloadPatAccount();
|
||||
await reloadIsPro();
|
||||
defaultToast(context, "SUCCESS");
|
||||
} catch (e) {
|
||||
defaultToast(context, "FAIL : $e");
|
||||
} finally {}
|
||||
}
|
||||
|
||||
bindThisAccount() async {
|
||||
defaultToast(context, "请稍后");
|
||||
try {
|
||||
await method.bindThisAccount();
|
||||
await reloadIsPro();
|
||||
defaultToast(context, "SUCCESS");
|
||||
} catch (e) {
|
||||
defaultToast(context, "FAIL : $e");
|
||||
} finally {}
|
||||
}
|
||||
|
||||
clearPat() async {
|
||||
await method.clearPat();
|
||||
await reloadIsPro();
|
||||
defaultToast(context, "Success");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,10 @@ import 'package:pikapika/screens/components/RightClickPop.dart';
|
|||
import '../basic/Entities.dart';
|
||||
import '../basic/config/Address.dart';
|
||||
import '../basic/config/IconLoading.dart';
|
||||
import 'components/ComicList.dart';
|
||||
import 'components/ComicPager.dart';
|
||||
import 'components/Common.dart';
|
||||
import 'components/GoDownloadSelect.dart';
|
||||
|
||||
// 搜索页面
|
||||
class SearchScreen extends StatefulWidget {
|
||||
|
@ -27,6 +29,7 @@ class SearchScreen extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _SearchScreenState extends State<SearchScreen> {
|
||||
late final _comicListController = ComicListController();
|
||||
late final TextEditingController _textEditController =
|
||||
TextEditingController(text: widget.keyword);
|
||||
late final SearchBar _searchBar = SearchBar(
|
||||
|
@ -51,7 +54,11 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
return AppBar(
|
||||
title: Text("${categoryTitle(widget.category)} ${widget.keyword}"),
|
||||
actions: [
|
||||
commonPopMenu(context),
|
||||
commonPopMenu(
|
||||
context,
|
||||
setState: setState,
|
||||
comicListController: _comicListController,
|
||||
),
|
||||
addressPopMenu(context),
|
||||
_chooseCategoryAction(),
|
||||
_searchBar.getSearchAction(context),
|
||||
|
@ -100,7 +107,7 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context){
|
||||
Widget build(BuildContext context) {
|
||||
return rightClickPop(
|
||||
child: buildScreen(context),
|
||||
context: context,
|
||||
|
@ -110,7 +117,9 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
|
||||
Widget buildScreen(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: _searchBar.build(context),
|
||||
appBar: _comicListController.selecting
|
||||
? downAppBar(context, _comicListController, setState)
|
||||
: _searchBar.build(context),
|
||||
body: ComicPager(
|
||||
fetchPage: _fetch,
|
||||
),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:pikapika/basic/Common.dart';
|
||||
import 'package:pikapika/screens/components/ComicList.dart';
|
||||
|
||||
import '../../basic/config/IsPro.dart';
|
||||
|
@ -39,9 +40,12 @@ Widget commonPopMenu(
|
|||
PopupMenuItem<int>(
|
||||
value: 3,
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.download),
|
||||
leading: Icon(
|
||||
Icons.download,
|
||||
color: isPro ? null : Colors.grey,
|
||||
),
|
||||
title: Text(
|
||||
"下载" + (isPro ? "" : "Pro"),
|
||||
"批量下载" + (isPro ? "" : "(发电)"),
|
||||
style: TextStyle(
|
||||
color: isPro ? null : Colors.grey,
|
||||
),
|
||||
|
@ -63,6 +67,10 @@ Widget commonPopMenu(
|
|||
chooseShadowCategories(context);
|
||||
break;
|
||||
case 3:
|
||||
if (!isPro) {
|
||||
defaultToast(context, "请先发电呀");
|
||||
return;
|
||||
}
|
||||
if (setState != null) {
|
||||
if (comicListController != null) {
|
||||
setState(() {
|
||||
|
|
|
@ -58,13 +58,15 @@ AppBar downAppBar(
|
|||
MaterialButton(
|
||||
minWidth: 0,
|
||||
onPressed: () async {
|
||||
// todo
|
||||
final list = _comicListController.selected;
|
||||
var list = _comicListController.selected;
|
||||
if (list.isEmpty) {
|
||||
defaultToast(context, "请选择漫画");
|
||||
return;
|
||||
}
|
||||
list = list.toList();
|
||||
setState((){
|
||||
_comicListController.selecting = false;
|
||||
});
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return DownloadComicsScreen(list);
|
||||
|
|
18
pubspec.lock
18
pubspec.lock
|
@ -13,10 +13,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: d6347d54a2d8028e0437e3c099f66fdb8ae02c4720c1e7534c9f24c10351f85d
|
||||
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.6"
|
||||
version: "3.3.7"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -273,10 +273,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_ios
|
||||
sha256: d4cb8ab04f770dab9d04c7959e5f6d22e8c5280343d425f9344f93832cf58445
|
||||
sha256: a1546ff5861fc15812953d4733b520c3d371cec3d2859a001ff04c46c4d81883
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.7+2"
|
||||
version: "0.8.7+3"
|
||||
image_picker_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -286,7 +286,7 @@ packages:
|
|||
source: hosted
|
||||
version: "2.6.3"
|
||||
intl:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
|
||||
|
@ -574,10 +574,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "3dedc66ca3c0bef9e6a93c0999aee102556a450afcc1b7bcfeace7a424927d92"
|
||||
sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.3"
|
||||
version: "6.1.4"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -630,10 +630,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
|
||||
sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
version: "3.1.4"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -51,6 +51,7 @@ dependencies:
|
|||
uri_to_file: ^0.2.0
|
||||
uni_links: ^0.5.1
|
||||
filesystem_picker: ^3.0.0-beta.1
|
||||
intl: ^0.17.0
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
|
Loading…
Reference in New Issue