v1.5.5
This commit is contained in:
parent
ef4ce20587
commit
d02510c3cf
|
@ -4,7 +4,7 @@ on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
go_version: '1.17'
|
go_version: '1.18'
|
||||||
flutter_channel: 'stable'
|
flutter_channel: 'stable'
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,12 @@ if (flutterRoot == null) {
|
||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||||
if (flutterVersionCode == null) {
|
if (flutterVersionCode == null) {
|
||||||
flutterVersionCode = '1'
|
flutterVersionCode = '2'
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||||
if (flutterVersionName == null) {
|
if (flutterVersionName == null) {
|
||||||
flutterVersionName = '1.0'
|
flutterVersionName = '1.0.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
v1.5.4
|
v1.5.5
|
|
@ -1,11 +1,13 @@
|
||||||
更新
|
更新
|
||||||
|
|
||||||
- [x] 苹果手机支持导出导出了
|
- [x] 对历史记录页面进行优化
|
||||||
- [x] 修复了安卓导入时不能选择文件 (AOSP个别机型的问题)
|
- [x] 对导入进行优化
|
||||||
- [x] 增加了导出 PKI/PKZ 等格式
|
- [x] 增加了批量导出ZIP/PKI到文件夹
|
||||||
- [x] 苹果/安卓 在文件管理器中可以直接打开 PKI/PKZ 导入或观看
|
- [x] 增加了从一个文件夹中导入所有ZIP/PKI的功能
|
||||||
- [x] 增加了骑士榜
|
- [x] 增加了发电页面, 对作者发过电的用户会展示发电特权图标
|
||||||
|
|
||||||
计划
|
计划
|
||||||
|
|
||||||
- [ ] 本地骑士书签 (漫画书签?/快捷搜索书签?)
|
- [ ] 本地骑士书签 (漫画书签?/快捷搜索书签?)
|
||||||
|
- [ ] 将Jasmine导出的PKI/JMI/导入, 阅读Jasmine导出的PKI
|
||||||
|
|
||||||
|
|
|
@ -359,7 +359,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
@ -368,10 +368,12 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 1.0.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = niuhuan.pikapika;
|
PRODUCT_BUNDLE_IDENTIFIER = niuhuan.pikapika;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Profile;
|
name = Profile;
|
||||||
|
@ -491,7 +493,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
@ -500,11 +502,13 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 1.0.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = niuhuan.pikapika;
|
PRODUCT_BUNDLE_IDENTIFIER = niuhuan.pikapika;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
@ -515,7 +519,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
@ -524,10 +528,12 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 1.0.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = niuhuan.pikapika;
|
PRODUCT_BUNDLE_IDENTIFIER = niuhuan.pikapika;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|
|
@ -2,15 +2,6 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleURLTypes</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleURLSchemes</key>
|
|
||||||
<array>
|
|
||||||
<string>pika</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
@ -31,36 +22,6 @@
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>UTExportedTypeDeclarations</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>UTTypeIdentifier</key>
|
|
||||||
<string>niuhuan.pkz</string>
|
|
||||||
<key>UTTypeConformsTo</key>
|
|
||||||
<array>
|
|
||||||
<string>public.data</string>
|
|
||||||
<string>public.content</string>
|
|
||||||
<string>com.apple.package</string>
|
|
||||||
</array>
|
|
||||||
<key>UTTypeDescription</key>
|
|
||||||
<string>PKZ Archive</string>
|
|
||||||
<key>UTTypeTagSpecification</key>
|
|
||||||
<dict>
|
|
||||||
<key>public.filename-extension</key>
|
|
||||||
<array>
|
|
||||||
<string>pkz</string>
|
|
||||||
<string>pki</string>
|
|
||||||
<string>zip</string>
|
|
||||||
</array>
|
|
||||||
<key>public.mime-type</key>
|
|
||||||
<array>
|
|
||||||
<string>text/vnd.niuhuan.pkz</string>
|
|
||||||
<string>text/vnd.niuhuan.pki</string>
|
|
||||||
<string>text/vnd.niuhuan.zip</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
|
@ -72,11 +33,20 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
<string>$(MARKETING_VERSION)</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>pika</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.entertainment</string>
|
<string>public.app-category.entertainment</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
@ -104,5 +74,35 @@
|
||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>UTExportedTypeDeclarations</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>UTTypeConformsTo</key>
|
||||||
|
<array>
|
||||||
|
<string>public.data</string>
|
||||||
|
<string>public.content</string>
|
||||||
|
<string>com.apple.package</string>
|
||||||
|
</array>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>PKZ Archive</string>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>niuhuan.pkz</string>
|
||||||
|
<key>UTTypeTagSpecification</key>
|
||||||
|
<dict>
|
||||||
|
<key>public.filename-extension</key>
|
||||||
|
<array>
|
||||||
|
<string>pkz</string>
|
||||||
|
<string>pki</string>
|
||||||
|
<string>zip</string>
|
||||||
|
</array>
|
||||||
|
<key>public.mime-type</key>
|
||||||
|
<array>
|
||||||
|
<string>text/vnd.niuhuan.pkz</string>
|
||||||
|
<string>text/vnd.niuhuan.pki</string>
|
||||||
|
<string>text/vnd.niuhuan.zip</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -1012,3 +1012,13 @@ class PkzComicViewLog {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IsPro {
|
||||||
|
late bool isPro;
|
||||||
|
late int expire;
|
||||||
|
|
||||||
|
IsPro.fromJson(Map<String, dynamic> json) {
|
||||||
|
this.isPro = json["isPro"];
|
||||||
|
this.expire = json["expire"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -548,7 +548,8 @@ class Method {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 导出下载的漫画到pki
|
/// 导出下载的漫画到pki
|
||||||
Future<dynamic> exportComicDownloadToPki(String comicId, String dir, String name) {
|
Future<dynamic> exportComicDownloadToPki(
|
||||||
|
String comicId, String dir, String name) {
|
||||||
return _flatInvoke("exportComicDownloadToPki", {
|
return _flatInvoke("exportComicDownloadToPki", {
|
||||||
"comicId": comicId,
|
"comicId": comicId,
|
||||||
"dir": dir,
|
"dir": dir,
|
||||||
|
@ -582,6 +583,35 @@ class Method {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 导出zip
|
||||||
|
Future<dynamic> exportAnyComicDownloadsToZip(
|
||||||
|
List<String> comicIds,
|
||||||
|
String dir,
|
||||||
|
) {
|
||||||
|
return _flatInvoke("exportAnyComicDownloadsToZip", {
|
||||||
|
"comicIds": comicIds,
|
||||||
|
"dir": dir,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 导出pki
|
||||||
|
Future<dynamic> exportAnyComicDownloadsToPki(
|
||||||
|
List<String> comicIds,
|
||||||
|
String dir,
|
||||||
|
) {
|
||||||
|
return _flatInvoke("exportAnyComicDownloadsToPki", {
|
||||||
|
"comicIds": comicIds,
|
||||||
|
"dir": dir,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 导入文件夹所有的文件
|
||||||
|
Future<dynamic> importComicDownloadDir(
|
||||||
|
String dir,
|
||||||
|
) {
|
||||||
|
return _flatInvoke("importComicDownloadDir", dir);
|
||||||
|
}
|
||||||
|
|
||||||
/// 使用网络将下载传输到其他设备
|
/// 使用网络将下载传输到其他设备
|
||||||
Future<int> exportComicUsingSocket(String comicId) async {
|
Future<int> exportComicUsingSocket(String comicId) async {
|
||||||
return int.parse(await _flatInvoke("exportComicUsingSocket", comicId));
|
return int.parse(await _flatInvoke("exportComicUsingSocket", comicId));
|
||||||
|
@ -833,4 +863,16 @@ class Method {
|
||||||
.map((e) => Knight.fromJson(e))
|
.map((e) => Knight.fromJson(e))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<IsPro> isPro() async {
|
||||||
|
return IsPro.fromJson(jsonDecode(await _flatInvoke("isPro", "")));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future reloadPro() {
|
||||||
|
return _flatInvoke("reloadPro", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
Future inputCdKey(String cdKey) {
|
||||||
|
return _flatInvoke("inputCdKey", cdKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
|
||||||
import '../Common.dart';
|
import '../Common.dart';
|
||||||
|
import 'IsPro.dart';
|
||||||
|
|
||||||
const _propertyName = "androidDisplayMode";
|
const _propertyName = "androidDisplayMode";
|
||||||
List<String> _modes = [];
|
List<String> _modes = [];
|
||||||
|
@ -27,7 +28,11 @@ Future<void> _chooseAndroidDisplayMode(BuildContext context) async {
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
List<String> list = [""];
|
List<String> list = [""];
|
||||||
list.addAll(_modes);
|
list.addAll(_modes);
|
||||||
String? result = await chooseListDialog<String>(context, "安卓屏幕刷新率", list);
|
String? result = await chooseListDialog<String>(
|
||||||
|
context,
|
||||||
|
"安卓屏幕刷新率 \n(省电模式下不会高刷)",
|
||||||
|
list,
|
||||||
|
);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
await method.saveProperty(_propertyName, result);
|
await method.saveProperty(_propertyName, result);
|
||||||
_androidDisplayMode = result;
|
_androidDisplayMode = result;
|
||||||
|
@ -41,9 +46,18 @@ Widget androidDisplayModeSetting() {
|
||||||
return StatefulBuilder(
|
return StatefulBuilder(
|
||||||
builder: (BuildContext context, void Function(void Function()) setState) {
|
builder: (BuildContext context, void Function(void Function()) setState) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text("屏幕刷新率(安卓)"),
|
title: Text(
|
||||||
|
"屏幕刷新率(安卓)" + (!isPro ? "(发电)" : ""),
|
||||||
|
style: TextStyle(
|
||||||
|
color: !isPro ? Colors.grey : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
subtitle: Text(_androidDisplayMode),
|
subtitle: Text(_androidDisplayMode),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
|
if (!isPro) {
|
||||||
|
defaultToast(context, "请先发电再使用");
|
||||||
|
return;
|
||||||
|
}
|
||||||
await _chooseAndroidDisplayMode(context);
|
await _chooseAndroidDisplayMode(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../Common.dart';
|
import '../Common.dart';
|
||||||
import '../Method.dart';
|
import '../Method.dart';
|
||||||
|
import 'IsPro.dart';
|
||||||
|
|
||||||
const _propertyName = "androidSecureFlag";
|
const _propertyName = "androidSecureFlag";
|
||||||
|
|
||||||
|
@ -37,9 +38,20 @@ Widget androidSecureFlagSetting() {
|
||||||
return StatefulBuilder(builder:
|
return StatefulBuilder(builder:
|
||||||
(BuildContext context, void Function(void Function()) setState) {
|
(BuildContext context, void Function(void Function()) setState) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text("禁止截图/禁止显示在任务视图"),
|
title: Text(
|
||||||
subtitle: Text(_androidSecureFlag ? "是" : "否"),
|
"禁止截图/禁止显示在任务视图" + (!isPro ? "(发电)" : ""),
|
||||||
|
style: TextStyle(
|
||||||
|
color: !isPro ? Colors.grey : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
_androidSecureFlag ? "是" : "否",
|
||||||
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
|
if (!isPro) {
|
||||||
|
defaultToast(context, "请先发电再使用");
|
||||||
|
return;
|
||||||
|
}
|
||||||
await _chooseAndroidSecureFlag(context);
|
await _chooseAndroidSecureFlag(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:pikapika/basic/Common.dart';
|
import 'package:pikapika/basic/Common.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
|
||||||
|
import 'IsPro.dart';
|
||||||
|
|
||||||
late int _downloadThreadCount;
|
late int _downloadThreadCount;
|
||||||
const _values = [1, 2, 3, 4, 5];
|
const _values = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
@ -15,9 +17,18 @@ Widget downloadThreadCountSetting() {
|
||||||
return StatefulBuilder(
|
return StatefulBuilder(
|
||||||
builder: (BuildContext context, void Function(void Function()) setState) {
|
builder: (BuildContext context, void Function(void Function()) setState) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text("下载线程数"),
|
title: Text(
|
||||||
|
"下载线程数" + (!isPro ? "(发电)" : ""),
|
||||||
|
style: TextStyle(
|
||||||
|
color: !isPro ? Colors.grey : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
subtitle: Text("$_downloadThreadCount"),
|
subtitle: Text("$_downloadThreadCount"),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
|
if (!isPro) {
|
||||||
|
defaultToast(context, "请先发电再使用");
|
||||||
|
return;
|
||||||
|
}
|
||||||
int? value = await chooseListDialog(context, "选择下载线程数", _values);
|
int? value = await chooseListDialog(context, "选择下载线程数", _values);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
await method.saveDownloadThreadCount(value);
|
await method.saveDownloadThreadCount(value);
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../Common.dart';
|
import '../Common.dart';
|
||||||
import '../Method.dart';
|
import '../Method.dart';
|
||||||
|
import 'IsPro.dart';
|
||||||
|
|
||||||
const _propertyName = "exportRename";
|
const _propertyName = "exportRename";
|
||||||
late bool _exportRename;
|
late bool _exportRename;
|
||||||
|
@ -29,9 +30,18 @@ Widget exportRenameSetting() {
|
||||||
return StatefulBuilder(
|
return StatefulBuilder(
|
||||||
builder: (BuildContext context, void Function(void Function()) setState) {
|
builder: (BuildContext context, void Function(void Function()) setState) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text("导出时进行重命名"),
|
title: Text(
|
||||||
|
"导出时进行重命名" + (!isPro ? "(发电)" : ""),
|
||||||
|
style: TextStyle(
|
||||||
|
color: !isPro ? Colors.grey : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
subtitle: Text(_exportRename ? "是" : "否"),
|
subtitle: Text(_exportRename ? "是" : "否"),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
|
if (!isPro) {
|
||||||
|
defaultToast(context, "请先发电再使用");
|
||||||
|
return;
|
||||||
|
}
|
||||||
await _chooseExportRename(context);
|
await _chooseExportRename(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import 'package:event/event.dart';
|
||||||
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
|
||||||
|
var isPro = false;
|
||||||
|
var isProEx = 0;
|
||||||
|
|
||||||
|
final proEvent = Event();
|
||||||
|
|
||||||
|
Future reloadIsPro() async {
|
||||||
|
final p = await method.isPro();
|
||||||
|
isPro = p.isPro;
|
||||||
|
isProEx = p.expire;
|
||||||
|
proEvent.broadcast();
|
||||||
|
}
|
|
@ -15,9 +15,6 @@ late String _version;
|
||||||
String? _latestVersion;
|
String? _latestVersion;
|
||||||
String? _latestVersionInfo;
|
String? _latestVersionInfo;
|
||||||
|
|
||||||
const _propertyName = "checkVersionPeriod";
|
|
||||||
late int _period = -1;
|
|
||||||
|
|
||||||
Future initVersion() async {
|
Future initVersion() async {
|
||||||
// 当前版本
|
// 当前版本
|
||||||
try {
|
try {
|
||||||
|
@ -25,14 +22,6 @@ Future initVersion() async {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_version = "dirty";
|
_version = "dirty";
|
||||||
}
|
}
|
||||||
// 检查周期
|
|
||||||
_period = int.parse(await method.loadProperty(_propertyName, "0"));
|
|
||||||
if (_period > 0) {
|
|
||||||
if (DateTime.now().millisecondsSinceEpoch > _period) {
|
|
||||||
await method.saveProperty(_propertyName, "0");
|
|
||||||
_period = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var versionEvent = Event<EventArgs>();
|
var versionEvent = Event<EventArgs>();
|
||||||
|
@ -50,10 +39,6 @@ String? latestVersionInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future autoCheckNewVersion() {
|
Future autoCheckNewVersion() {
|
||||||
if (_period != 0) {
|
|
||||||
// -1 不检查, >0 未到检查时间
|
|
||||||
return Future.value();
|
|
||||||
}
|
|
||||||
return _versionCheck();
|
return _versionCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,75 +71,3 @@ Future _versionCheck() async {
|
||||||
} // else dirtyVersion
|
} // else dirtyVersion
|
||||||
versionEvent.broadcast();
|
versionEvent.broadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
String _periodText() {
|
|
||||||
if (_period < 0) {
|
|
||||||
return "自动检查更新已关闭";
|
|
||||||
}
|
|
||||||
if (_period == 0) {
|
|
||||||
return "自动检查更新已开启";
|
|
||||||
}
|
|
||||||
return "下次检查时间 : " +
|
|
||||||
formatDateTimeToDateTime(
|
|
||||||
DateTime.fromMillisecondsSinceEpoch(_period),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future _choosePeriod(BuildContext context) async {
|
|
||||||
var result = await chooseListDialog(
|
|
||||||
context,
|
|
||||||
"自动检查更新",
|
|
||||||
["开启", "一周后", "一个月后", "一年后", "关闭"],
|
|
||||||
tips: "重启后红点会消失",
|
|
||||||
);
|
|
||||||
switch (result) {
|
|
||||||
case "开启":
|
|
||||||
await method.saveProperty(_propertyName, "0");
|
|
||||||
_period = 0;
|
|
||||||
break;
|
|
||||||
case "一周后":
|
|
||||||
var time = DateTime.now().millisecondsSinceEpoch + (1000 * 3600 * 24 * 7);
|
|
||||||
await method.saveProperty(_propertyName, "$time");
|
|
||||||
_period = time;
|
|
||||||
break;
|
|
||||||
case "一个月后":
|
|
||||||
var time =
|
|
||||||
DateTime.now().millisecondsSinceEpoch + (1000 * 3600 * 24 * 30);
|
|
||||||
await method.saveProperty(_propertyName, "$time");
|
|
||||||
_period = time;
|
|
||||||
break;
|
|
||||||
case "一年后":
|
|
||||||
var time =
|
|
||||||
DateTime.now().millisecondsSinceEpoch + (1000 * 3600 * 24 * 365);
|
|
||||||
await method.saveProperty(_propertyName, "$time");
|
|
||||||
_period = time;
|
|
||||||
break;
|
|
||||||
case "关闭":
|
|
||||||
await method.saveProperty(_propertyName, "-1");
|
|
||||||
_period = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget autoUpdateCheckSetting() {
|
|
||||||
return StatefulBuilder(
|
|
||||||
builder: (BuildContext context, void Function(void Function()) setState) {
|
|
||||||
return ListTile(
|
|
||||||
title: const Text("自动检查更新"),
|
|
||||||
subtitle: Text(_periodText()),
|
|
||||||
onTap: () async {
|
|
||||||
await _choosePeriod(context);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String formatDateTimeToDateTime(DateTime c) {
|
|
||||||
try {
|
|
||||||
return "${add0(c.year, 4)}-${add0(c.month, 2)}-${add0(c.day, 2)} ${add0(c.hour, 2)}:${add0(c.minute, 2)}";
|
|
||||||
} catch (e) {
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -98,8 +98,6 @@ class _AboutScreenState extends State<AboutScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
autoUpdateCheckSetting(),
|
|
||||||
const Divider(),
|
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
child: const SelectableText(
|
child: const SelectableText(
|
||||||
|
|
|
@ -5,18 +5,15 @@ import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pikapika/basic/Common.dart';
|
import 'package:pikapika/basic/Common.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
import 'package:pikapika/basic/config/IsPro.dart';
|
||||||
import 'package:pikapika/basic/config/Themes.dart';
|
import 'package:pikapika/basic/config/Themes.dart';
|
||||||
import 'package:pikapika/basic/enum/ErrorTypes.dart';
|
import 'package:pikapika/basic/enum/ErrorTypes.dart';
|
||||||
import 'package:pikapika/screens/RegisterScreen.dart';
|
import 'package:pikapika/screens/RegisterScreen.dart';
|
||||||
import 'package:pikapika/screens/SettingsScreen.dart';
|
import 'package:pikapika/screens/SettingsScreen.dart';
|
||||||
import 'package:pikapika/screens/components/NetworkSetting.dart';
|
import 'package:pikapika/screens/components/NetworkSetting.dart';
|
||||||
import 'package:uni_links/uni_links.dart';
|
|
||||||
import 'package:uri_to_file/uri_to_file.dart';
|
|
||||||
|
|
||||||
import '../basic/Navigator.dart';
|
|
||||||
import 'AppScreen.dart';
|
import 'AppScreen.dart';
|
||||||
import 'DownloadListScreen.dart';
|
import 'DownloadListScreen.dart';
|
||||||
import 'PkzArchiveScreen.dart';
|
|
||||||
import 'ThemeScreen.dart';
|
import 'ThemeScreen.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
|
||||||
|
@ -186,6 +183,7 @@ class _AccountScreenState extends State<AccountScreen> {
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await method.login();
|
await method.login();
|
||||||
|
await reloadIsPro();
|
||||||
Navigator.pushReplacement(
|
Navigator.pushReplacement(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => const AppScreen()),
|
MaterialPageRoute(builder: (context) => const AppScreen()),
|
||||||
|
|
|
@ -87,20 +87,24 @@ class _DownloadConfirmScreenState extends State<DownloadConfirmScreen> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果之前下载过就将EP加入下载
|
try {
|
||||||
// 如果之前没有下载过就创建下载
|
// 如果之前下载过就将EP加入下载
|
||||||
if (_task != null) {
|
// 如果之前没有下载过就创建下载
|
||||||
await method.addDownload(create, list);
|
if (_task != null) {
|
||||||
} else {
|
await method.addDownload(create, list);
|
||||||
await method.createDownload(create, list);
|
} else {
|
||||||
|
await method.createDownload(create, list);
|
||||||
|
}
|
||||||
|
// 退出
|
||||||
|
defaultToast(context, "已经加入下载列表");
|
||||||
|
Navigator.pop(context);
|
||||||
|
} catch (e, s) {
|
||||||
|
defaultToast(context, e.toString());
|
||||||
}
|
}
|
||||||
// 退出
|
|
||||||
defaultToast(context, "已经加入下载列表");
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context){
|
Widget build(BuildContext context) {
|
||||||
return rightClickPop(
|
return rightClickPop(
|
||||||
child: buildScreen(context),
|
child: buildScreen(context),
|
||||||
context: context,
|
context: context,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import '../basic/Channels.dart';
|
||||||
import '../basic/Cross.dart';
|
import '../basic/Cross.dart';
|
||||||
import '../basic/Method.dart';
|
import '../basic/Method.dart';
|
||||||
import '../basic/config/ExportRename.dart';
|
import '../basic/config/ExportRename.dart';
|
||||||
|
import '../basic/config/IsPro.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
|
|
||||||
class DownloadExportingGroupScreen extends StatefulWidget {
|
class DownloadExportingGroupScreen extends StatefulWidget {
|
||||||
|
@ -51,17 +52,31 @@ class _DownloadExportingGroupScreenState
|
||||||
return Center(child: Text("导出失败\n$e"));
|
return Center(child: Text("导出失败\n$e"));
|
||||||
}
|
}
|
||||||
if (exported) {
|
if (exported) {
|
||||||
return Center(child: Text("导出成功"));
|
return const Center(child: Text("导出成功"));
|
||||||
}
|
}
|
||||||
return Center(
|
return ListView(
|
||||||
child: MaterialButton(
|
children: [
|
||||||
onPressed: _export,
|
Container(height: 20),
|
||||||
child: const Text("选择导出位置"),
|
MaterialButton(
|
||||||
),
|
onPressed: _exportPkz,
|
||||||
|
child: const Text("导出PKZ"),
|
||||||
|
),
|
||||||
|
Container(height: 20),
|
||||||
|
MaterialButton(
|
||||||
|
onPressed: _exportPkis,
|
||||||
|
child: Text("分别导出PKI" + (!isPro ? "\n(发电后使用)" : "")),
|
||||||
|
),
|
||||||
|
Container(height: 20),
|
||||||
|
MaterialButton(
|
||||||
|
onPressed: _exportZips,
|
||||||
|
child: Text("分别导出ZIP" + (!isPro ? "\n(发电后使用)" : "")),
|
||||||
|
),
|
||||||
|
Container(height: 20),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_export() async {
|
_exportPkz() async {
|
||||||
late String? path;
|
late String? path;
|
||||||
try {
|
try {
|
||||||
path = await chooseFolder(context);
|
path = await chooseFolder(context);
|
||||||
|
@ -105,6 +120,74 @@ class _DownloadExportingGroupScreenState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_exportPkis() async {
|
||||||
|
if (!isPro) {
|
||||||
|
defaultToast(context, "请先发电鸭");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
late String? path;
|
||||||
|
try {
|
||||||
|
path = await chooseFolder(context);
|
||||||
|
} catch (e) {
|
||||||
|
defaultToast(context, "$e");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print("path $path");
|
||||||
|
if (path != null) {
|
||||||
|
try {
|
||||||
|
setState(() {
|
||||||
|
exporting = true;
|
||||||
|
});
|
||||||
|
await method.exportAnyComicDownloadsToPki(
|
||||||
|
widget.idList,
|
||||||
|
path,
|
||||||
|
);
|
||||||
|
exported = true;
|
||||||
|
} catch (err) {
|
||||||
|
e = err;
|
||||||
|
exportFail = true;
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
exporting = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_exportZips() async {
|
||||||
|
if (!isPro) {
|
||||||
|
defaultToast(context, "请先发电鸭");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
late String? path;
|
||||||
|
try {
|
||||||
|
path = await chooseFolder(context);
|
||||||
|
} catch (e) {
|
||||||
|
defaultToast(context, "$e");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print("path $path");
|
||||||
|
if (path != null) {
|
||||||
|
try {
|
||||||
|
setState(() {
|
||||||
|
exporting = true;
|
||||||
|
});
|
||||||
|
await method.exportAnyComicDownloadsToZip(
|
||||||
|
widget.idList,
|
||||||
|
path,
|
||||||
|
);
|
||||||
|
exported = true;
|
||||||
|
} catch (err) {
|
||||||
|
e = err;
|
||||||
|
exportFail = true;
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
exporting = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
|
|
|
@ -8,6 +8,8 @@ import 'package:pikapika/basic/Common.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
import 'package:pikapika/basic/config/ChooserRoot.dart';
|
import 'package:pikapika/basic/config/ChooserRoot.dart';
|
||||||
|
|
||||||
|
import '../basic/Cross.dart';
|
||||||
|
import '../basic/config/IsPro.dart';
|
||||||
import 'PkzArchiveScreen.dart';
|
import 'PkzArchiveScreen.dart';
|
||||||
import 'components/ContentLoading.dart';
|
import 'components/ContentLoading.dart';
|
||||||
import 'components/RightClickPop.dart';
|
import 'components/RightClickPop.dart';
|
||||||
|
@ -64,6 +66,7 @@ class _DownloadImportScreenState extends State<DownloadImportScreen> {
|
||||||
|
|
||||||
actions.add(_fileImportButton());
|
actions.add(_fileImportButton());
|
||||||
actions.add(_networkImportButton());
|
actions.add(_networkImportButton());
|
||||||
|
actions.add(_importDirFilesZipButton());
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
@ -103,7 +106,7 @@ class _DownloadImportScreenState extends State<DownloadImportScreen> {
|
||||||
allowedExtensions: ['.pkz', '.zip', '.pki'],
|
allowedExtensions: ['.pkz', '.zip', '.pki'],
|
||||||
fileTileSelectMode: FileTileSelectMode.wholeTile,
|
fileTileSelectMode: FileTileSelectMode.wholeTile,
|
||||||
);
|
);
|
||||||
}else{
|
} else {
|
||||||
var ls = await FilePicker.platform.pickFiles(
|
var ls = await FilePicker.platform.pickFiles(
|
||||||
dialogTitle: '选择要导入的文件',
|
dialogTitle: '选择要导入的文件',
|
||||||
allowMultiple: false,
|
allowMultiple: false,
|
||||||
|
@ -127,9 +130,9 @@ class _DownloadImportScreenState extends State<DownloadImportScreen> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_importing = true;
|
_importing = true;
|
||||||
});
|
});
|
||||||
if(path.endsWith(".zip")){
|
if (path.endsWith(".zip")) {
|
||||||
await method.importComicDownload(path);
|
await method.importComicDownload(path);
|
||||||
} else if(path.endsWith(".pki")){
|
} else if (path.endsWith(".pki")) {
|
||||||
await method.importComicDownloadPki(path);
|
await method.importComicDownloadPki(path);
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -184,4 +187,43 @@ class _DownloadImportScreenState extends State<DownloadImportScreen> {
|
||||||
child: const Text('从其他设备导入'),
|
child: const Text('从其他设备导入'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _importDirFilesZipButton() {
|
||||||
|
return MaterialButton(
|
||||||
|
height: 80,
|
||||||
|
onPressed: () async {
|
||||||
|
late String? path;
|
||||||
|
try {
|
||||||
|
path = await chooseFolder(context);
|
||||||
|
} catch (e) {
|
||||||
|
defaultToast(context, "$e");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (path != null) {
|
||||||
|
try {
|
||||||
|
setState(() {
|
||||||
|
_importing = true;
|
||||||
|
});
|
||||||
|
await method.importComicDownloadDir(path);
|
||||||
|
setState(() {
|
||||||
|
_importMessage = "导入成功";
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
setState(() {
|
||||||
|
_importMessage = "导入失败 $e";
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
_importing = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'选择文件夹\n(导入里面所有的zip)' + (!isPro ? "\n(发电后使用)" : ""),
|
||||||
|
style: TextStyle(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import 'package:pikapika/screens/PkzArchiveScreen.dart';
|
||||||
import 'package:uni_links/uni_links.dart';
|
import 'package:uni_links/uni_links.dart';
|
||||||
import 'package:uri_to_file/uri_to_file.dart';
|
import 'package:uri_to_file/uri_to_file.dart';
|
||||||
import '../basic/config/ExportRename.dart';
|
import '../basic/config/ExportRename.dart';
|
||||||
|
import '../basic/config/IsPro.dart';
|
||||||
import 'AccountScreen.dart';
|
import 'AccountScreen.dart';
|
||||||
import 'AppScreen.dart';
|
import 'AppScreen.dart';
|
||||||
import 'DownloadOnlyImportScreen.dart';
|
import 'DownloadOnlyImportScreen.dart';
|
||||||
|
@ -94,6 +95,7 @@ class _InitScreenState extends State<InitScreen> {
|
||||||
await initVersion();
|
await initVersion();
|
||||||
await initUsingRightClickPop();
|
await initUsingRightClickPop();
|
||||||
await initAuthentication();
|
await initAuthentication();
|
||||||
|
await reloadIsPro();
|
||||||
autoCheckNewVersion();
|
autoCheckNewVersion();
|
||||||
|
|
||||||
String? initUrl;
|
String? initUrl;
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pikapika/basic/Common.dart';
|
||||||
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
|
||||||
|
import '../basic/config/IsPro.dart';
|
||||||
|
|
||||||
|
class ProScreen extends StatefulWidget {
|
||||||
|
const ProScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _ProScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ProScreenState extends State<ProScreen> {
|
||||||
|
String _username = "";
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
method.getUsername().then((value) {
|
||||||
|
setState(() {
|
||||||
|
_username = value;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var size = MediaQuery.of(context).size;
|
||||||
|
var min = size.width < size.height ? size.width : size.height;
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("发电中心"),
|
||||||
|
),
|
||||||
|
body: ListView(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: min / 2,
|
||||||
|
height: min / 2,
|
||||||
|
child: Center(
|
||||||
|
child: Icon(
|
||||||
|
isPro ? Icons.offline_bolt : Icons.offline_bolt_outlined,
|
||||||
|
size: min / 3,
|
||||||
|
color: Colors.grey.shade500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(child: Text(_username)),
|
||||||
|
Container(height: 20),
|
||||||
|
const Divider(),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(20),
|
||||||
|
child: Text(
|
||||||
|
"点击\"我曾经发过电\"进同步发电状态\n"
|
||||||
|
"点击\"我刚才发了电\"兑换作者给您的礼物卡\n"
|
||||||
|
"去\"关于\"界面找到维护地址用爱发电",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
ListTile(
|
||||||
|
title: const Text("发电详情"),
|
||||||
|
subtitle: Text(
|
||||||
|
isPro
|
||||||
|
? "发电中 (${DateTime.fromMillisecondsSinceEpoch(1000 * isProEx).toString()})"
|
||||||
|
: "未发电",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
ListTile(
|
||||||
|
title: const Text("我曾经发过电"),
|
||||||
|
onTap: () async {
|
||||||
|
try {
|
||||||
|
await method.reloadPro();
|
||||||
|
defaultToast(context, "SUCCESS");
|
||||||
|
} catch (e, s) {
|
||||||
|
defaultToast(context, "FAIL");
|
||||||
|
}
|
||||||
|
await reloadIsPro();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
ListTile(
|
||||||
|
title: const Text("我刚才发了电"),
|
||||||
|
onTap: () async {
|
||||||
|
final code = await inputString(context, "输入代码");
|
||||||
|
if (code != null && code.isNotEmpty) {
|
||||||
|
try {
|
||||||
|
await method.inputCdKey(code);
|
||||||
|
defaultToast(context, "SUCCESS");
|
||||||
|
} catch (e, s) {
|
||||||
|
defaultToast(context, "FAIL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await reloadIsPro();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import 'package:pikapika/basic/config/DownloadThreadCount.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';
|
||||||
|
import 'package:pikapika/basic/config/IsPro.dart';
|
||||||
import 'package:pikapika/basic/config/KeyboardController.dart';
|
import 'package:pikapika/basic/config/KeyboardController.dart';
|
||||||
import 'package:pikapika/basic/config/NoAnimation.dart';
|
import 'package:pikapika/basic/config/NoAnimation.dart';
|
||||||
import 'package:pikapika/basic/config/PagerAction.dart';
|
import 'package:pikapika/basic/config/PagerAction.dart';
|
||||||
|
@ -113,8 +114,6 @@ class SettingsScreen extends StatelessWidget {
|
||||||
const Divider(),
|
const Divider(),
|
||||||
migrate(context),
|
migrate(context),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
autoUpdateCheckSetting(),
|
|
||||||
const Divider(),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -122,9 +121,18 @@ class SettingsScreen extends StatelessWidget {
|
||||||
Widget migrate(BuildContext context) {
|
Widget migrate(BuildContext context) {
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text("文件迁移"),
|
title: Text(
|
||||||
subtitle: const Text("更换您的数据文件夹"),
|
"文件迁移" + (!isPro ? "(发电)" : ""),
|
||||||
|
style: TextStyle(
|
||||||
|
color: !isPro ? Colors.grey : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: const Text("更换您的数据文件夹到内存卡"),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
|
if (!isPro) {
|
||||||
|
defaultToast(context, "请先发电再使用");
|
||||||
|
return;
|
||||||
|
}
|
||||||
var f =
|
var f =
|
||||||
await confirmDialog(context, "文件迁移", "此功能菜单保存后, 需要重启程序, 您确认吗");
|
await confirmDialog(context, "文件迁移", "此功能菜单保存后, 需要重启程序, 您确认吗");
|
||||||
if (f) {
|
if (f) {
|
||||||
|
|
|
@ -5,10 +5,12 @@ import 'package:pikapika/screens/AboutScreen.dart';
|
||||||
import 'package:pikapika/screens/AccountScreen.dart';
|
import 'package:pikapika/screens/AccountScreen.dart';
|
||||||
import 'package:pikapika/screens/DownloadListScreen.dart';
|
import 'package:pikapika/screens/DownloadListScreen.dart';
|
||||||
import 'package:pikapika/screens/FavouritePaperScreen.dart';
|
import 'package:pikapika/screens/FavouritePaperScreen.dart';
|
||||||
|
import 'package:pikapika/screens/ProScreen.dart';
|
||||||
import 'package:pikapika/screens/ThemeScreen.dart';
|
import 'package:pikapika/screens/ThemeScreen.dart';
|
||||||
import 'package:pikapika/screens/ViewLogsScreen.dart';
|
import 'package:pikapika/screens/ViewLogsScreen.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
|
||||||
|
import '../basic/config/IsPro.dart';
|
||||||
import '../basic/config/Themes.dart';
|
import '../basic/config/Themes.dart';
|
||||||
import 'SettingsScreen.dart';
|
import 'SettingsScreen.dart';
|
||||||
import 'components/Badge.dart';
|
import 'components/Badge.dart';
|
||||||
|
@ -25,17 +27,19 @@ class SpaceScreen extends StatefulWidget {
|
||||||
class _SpaceScreenState extends State<SpaceScreen> {
|
class _SpaceScreenState extends State<SpaceScreen> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
versionEvent.subscribe(_onVersion);
|
versionEvent.subscribe(_onEvent);
|
||||||
|
proEvent.subscribe(_onEvent);
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
versionEvent.unsubscribe(_onVersion);
|
versionEvent.unsubscribe(_onEvent);
|
||||||
|
proEvent.unsubscribe(_onEvent);
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onVersion(dynamic a) {
|
void _onEvent(dynamic a) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +77,17 @@ class _SpaceScreenState extends State<SpaceScreen> {
|
||||||
badge: latestVersion() == null ? null : "1",
|
badge: latestVersion() == null ? null : "1",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context)
|
||||||
|
.push(MaterialPageRoute(builder: (BuildContext context) {
|
||||||
|
return const ProScreen();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
isPro ? Icons.offline_bolt : Icons.offline_bolt_outlined,
|
||||||
|
),
|
||||||
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pikapika/basic/Common.dart';
|
import 'package:pikapika/basic/Common.dart';
|
||||||
import 'package:pikapika/basic/Method.dart';
|
import 'package:pikapika/basic/Method.dart';
|
||||||
|
import 'package:pikapika/screens/components/ComicInfoCard.dart';
|
||||||
import 'package:pikapika/screens/components/RightClickPop.dart';
|
import 'package:pikapika/screens/components/RightClickPop.dart';
|
||||||
|
|
||||||
|
import '../basic/Entities.dart';
|
||||||
import 'ComicInfoScreen.dart';
|
import 'ComicInfoScreen.dart';
|
||||||
import 'components/Images.dart';
|
import 'components/Images.dart';
|
||||||
|
|
||||||
|
@ -19,7 +23,7 @@ class _ViewLogsScreenState extends State<ViewLogsScreen> {
|
||||||
static const _scrollPhysics = AlwaysScrollableScrollPhysics(); // 即使不足一页仍可滚动
|
static const _scrollPhysics = AlwaysScrollableScrollPhysics(); // 即使不足一页仍可滚动
|
||||||
|
|
||||||
final _scrollController = ScrollController();
|
final _scrollController = ScrollController();
|
||||||
final _comicList = <ViewLogWrapEntity>[];
|
final _comicList = <ViewLog>[];
|
||||||
|
|
||||||
var _isLoading = false; // 是否加载中
|
var _isLoading = false; // 是否加载中
|
||||||
var _scrollOvered = false; // 滚动到最后
|
var _scrollOvered = false; // 滚动到最后
|
||||||
|
@ -70,8 +74,7 @@ class _ViewLogsScreenState extends State<ViewLogsScreen> {
|
||||||
if (page.isEmpty) {
|
if (page.isEmpty) {
|
||||||
_scrollOvered = true;
|
_scrollOvered = true;
|
||||||
} else {
|
} else {
|
||||||
_comicList.addAll(page.map((e) =>
|
_comicList.addAll(page);
|
||||||
ViewLogWrapEntity(e.id, e.title, e.thumbFileServer, e.thumbPath)));
|
|
||||||
}
|
}
|
||||||
_offset += _pageSize;
|
_offset += _pageSize;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -106,25 +109,37 @@ class _ViewLogsScreenState extends State<ViewLogsScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
var entries = _comicList.map((e) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
_chooseComic(e.id);
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
_clearOnce(e.id);
|
||||||
|
},
|
||||||
|
child: ViewInfoCard(
|
||||||
|
fileServer: e.thumbFileServer,
|
||||||
|
author: e.author,
|
||||||
|
categories: _decodeCate(e.categories),
|
||||||
|
path: e.thumbPath,
|
||||||
|
title: e.title,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
final screen = NotificationListener(
|
final screen = NotificationListener(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('浏览记录'),
|
title: const Text('浏览记录'),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(onPressed: _clearAll, icon: const Icon(Icons.auto_delete)),
|
IconButton(
|
||||||
|
onPressed: _clearAll, icon: const Icon(Icons.auto_delete)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: ListView(
|
||||||
physics: _scrollPhysics,
|
physics: _scrollPhysics,
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
children: [
|
children: entries.toList(),
|
||||||
Container(height: 10),
|
|
||||||
ViewLogWrap(
|
|
||||||
onTapComic: _chooseComic,
|
|
||||||
comics: _comicList,
|
|
||||||
onDelete: _clearOnce,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onNotification: (scrollNotification) {
|
onNotification: (scrollNotification) {
|
||||||
|
@ -151,88 +166,90 @@ class _ViewLogsScreenState extends State<ViewLogsScreen> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> _decodeCate(String categories) {
|
||||||
|
try {
|
||||||
|
var decode = jsonDecode(categories);
|
||||||
|
if (decode is List) {
|
||||||
|
return List.of(decode).cast();
|
||||||
|
}
|
||||||
|
return [decode];
|
||||||
|
} catch (e) {
|
||||||
|
return [categories];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewLogWrap extends StatelessWidget {
|
class ViewInfoCard extends StatelessWidget {
|
||||||
final Function(String) onTapComic;
|
final String fileServer;
|
||||||
final List<ViewLogWrapEntity> comics;
|
final String path;
|
||||||
final Function(String id) onDelete;
|
final String title;
|
||||||
|
final String author;
|
||||||
|
final List<String> categories;
|
||||||
|
|
||||||
const ViewLogWrap({
|
const ViewInfoCard({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.onTapComic,
|
required this.fileServer,
|
||||||
required this.comics,
|
required this.path,
|
||||||
required this.onDelete,
|
required this.title,
|
||||||
|
required this.author,
|
||||||
|
required this.categories,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var size = MediaQuery.of(context).size;
|
var theme = Theme.of(context);
|
||||||
var min = size.width < size.height ? size.width : size.height;
|
return Container(
|
||||||
var width = (min - 45) / 4;
|
padding: const EdgeInsets.all(5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
var entries = comics.map((e) {
|
border: Border(
|
||||||
return InkWell(
|
bottom: BorderSide(
|
||||||
key: e.key,
|
color: theme.dividerColor,
|
||||||
onTap: () {
|
),
|
||||||
onTapComic(e.id);
|
),
|
||||||
},
|
),
|
||||||
onLongPress: () {
|
child: Row(
|
||||||
onDelete(e.id);
|
children: [
|
||||||
},
|
Container(
|
||||||
child: Card(
|
padding: const EdgeInsets.only(right: 10),
|
||||||
child: SizedBox(
|
child: RemoteImage(
|
||||||
width: width,
|
fileServer: fileServer,
|
||||||
child: Column(
|
path: path,
|
||||||
|
width: imageWidth,
|
||||||
|
height: imageHeight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
LayoutBuilder(builder:
|
Expanded(
|
||||||
(BuildContext context, BoxConstraints constraints) {
|
child: Column(
|
||||||
return RemoteImage(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
width: constraints.maxWidth,
|
children: [
|
||||||
fileServer: e.fileServer,
|
Text(title, style: titleStyle),
|
||||||
path: e.path);
|
Container(height: 5),
|
||||||
}),
|
Text(author, style: authorStyle),
|
||||||
Text(
|
Container(height: 5),
|
||||||
e.title + '\n',
|
Text.rich(
|
||||||
maxLines: 2,
|
TextSpan(text: "分类 : ${categories.join(' ')}"),
|
||||||
overflow: TextOverflow.ellipsis,
|
style: TextStyle(
|
||||||
style: const TextStyle(height: 1.4),
|
fontSize: 13,
|
||||||
strutStyle: const StrutStyle(height: 1.4),
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyText1!
|
||||||
|
.color!
|
||||||
|
.withAlpha(0xCC),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(height: 5),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
);
|
),
|
||||||
});
|
|
||||||
|
|
||||||
Map<int, List<Widget>> map = {};
|
|
||||||
for (var i = 0; i < entries.length; i++) {
|
|
||||||
late List<Widget> list;
|
|
||||||
if (i % 4 == 0) {
|
|
||||||
list = [];
|
|
||||||
map[i ~/ 4] = list;
|
|
||||||
} else {
|
|
||||||
list = map[i ~/ 4]!;
|
|
||||||
}
|
|
||||||
list.add(entries.elementAt(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children: map.values.map((e) => Wrap(
|
|
||||||
alignment: WrapAlignment.spaceAround,
|
|
||||||
children: e,
|
|
||||||
)).toList(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewLogWrapEntity {
|
|
||||||
final Key key = UniqueKey();
|
|
||||||
final String id;
|
|
||||||
final String title;
|
|
||||||
final String fileServer;
|
|
||||||
final String path;
|
|
||||||
|
|
||||||
ViewLogWrapEntity(this.id, this.title, this.fileServer, this.path);
|
|
||||||
}
|
|
||||||
|
|
|
@ -253,6 +253,8 @@ class StreamComicPager extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _StreamComicPagerState extends State<StreamComicPager> {
|
class _StreamComicPagerState extends State<StreamComicPager> {
|
||||||
|
final TextEditingController _textEditController =
|
||||||
|
TextEditingController(text: '');
|
||||||
final _scrollController = ScrollController();
|
final _scrollController = ScrollController();
|
||||||
late String _currentSort = SORT_DEFAULT;
|
late String _currentSort = SORT_DEFAULT;
|
||||||
late int _currentPage = 1;
|
late int _currentPage = 1;
|
||||||
|
@ -264,6 +266,12 @@ class _StreamComicPagerState extends State<StreamComicPager> {
|
||||||
|
|
||||||
// late Future<dynamic> _pageFuture;
|
// late Future<dynamic> _pageFuture;
|
||||||
|
|
||||||
|
_onSetOffset(int i) {
|
||||||
|
_list.clear();
|
||||||
|
_currentPage = i;
|
||||||
|
_load();
|
||||||
|
}
|
||||||
|
|
||||||
void _onScroll() {
|
void _onScroll() {
|
||||||
if (_over || _error || _loading) {
|
if (_over || _error || _loading) {
|
||||||
return;
|
return;
|
||||||
|
@ -317,6 +325,7 @@ class _StreamComicPagerState extends State<StreamComicPager> {
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_scrollController.removeListener(_onScroll);
|
_scrollController.removeListener(_onScroll);
|
||||||
_scrollController.dispose();
|
_scrollController.dispose();
|
||||||
|
_textEditController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +376,60 @@ class _StreamComicPagerState extends State<StreamComicPager> {
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text("已经加载 ${_currentPage - 1} / $_maxPage 页"),
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
_textEditController.clear();
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return AlertDialog(
|
||||||
|
content: Card(
|
||||||
|
child: TextField(
|
||||||
|
controller: _textEditController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "请输入页数:",
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: <TextInputFormatter>[
|
||||||
|
FilteringTextInputFormatter.allow(RegExp(r'\d+')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
MaterialButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: const Text('取消'),
|
||||||
|
),
|
||||||
|
MaterialButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
var text = _textEditController.text;
|
||||||
|
if (text.isEmpty || text.length > 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var num = int.parse(text);
|
||||||
|
if (num == 0 || num > _maxPage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_currentPage = num;
|
||||||
|
_onSetOffset(num);
|
||||||
|
},
|
||||||
|
child: const Text('确定'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text("已经加载 ${_currentPage - 1} / $_maxPage 页"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -178,7 +178,7 @@ packages:
|
||||||
name: flutter_svg
|
name: flutter_svg
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1+1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -244,7 +244,7 @@ packages:
|
||||||
name: image_picker_ios
|
name: image_picker_ios
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.5+5"
|
version: "0.8.5+6"
|
||||||
image_picker_platform_interface:
|
image_picker_platform_interface:
|
||||||
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.0.0+1
|
version: 1.0.1+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
|
Loading…
Reference in New Issue