add comment

This commit is contained in:
niuhuan 2021-10-21 12:08:51 +08:00
parent 8096f517a2
commit 088453f1ad
13 changed files with 239 additions and 191 deletions

View File

@ -92,9 +92,6 @@ class MainActivity : FlutterActivity() {
setMode(call.argument("mode")!!)
}
"androidGetVersion" -> Build.VERSION.SDK_INT
// "exportComicDownloadAndroidQ" -> {
// exportComicDownloadAndroidQ(call.argument("comicId")!!)
// }
// 现在的文件储存路径, 默认路径返回空字符串 ""
"dataLocal" -> androidDataLocal()
// 迁移到那个地方, 如果是空字符串则迁移会默认位置
@ -341,63 +338,4 @@ class MainActivity : FlutterActivity() {
return super.onKeyDown(keyCode, event)
}
// 安卓11以上使用了 MANAGE_EXTERNAL_STORAGE 权限来管理整个外置存储 (危险权限)
// private val resourceQueue: LinkedBlockingQueue<Any?> = LinkedBlockingQueue()
// private var tmpComicId: String? = null
// private val exportComicDownloadAndroidQRequestCode = 2
//
// private fun exportComicDownloadAndroidQ(comicId: String) {
// val title = Mobile.flatInvoke("specialDownloadTitle", comicId)
// var fileName = title
// fileName = fileName.replace('/', '_')
// fileName = fileName.replace('\\', '_')
// fileName = fileName.replace('*', '_')
// fileName = fileName.replace('?', '_')
// fileName = fileName.replace('<', '_')
// fileName = fileName.replace('>', '_')
// fileName = fileName.replace('|', '_')
// fileName = fileName + "_" + System.currentTimeMillis() + ".zip"
// tmpComicId = comicId
// startActivityForResult(Intent(Intent.ACTION_CREATE_DOCUMENT).also {
// it.addCategory(Intent.CATEGORY_OPENABLE)
// it.type = "application/octet-stream"
// it.putExtra(Intent.EXTRA_TITLE, fileName)
// }, exportComicDownloadAndroidQRequestCode)
// val result = resourceQueue.take()
// if (result is Throwable) {
// throw result
// }
// return
// }
//
// override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
// pool.submit {
// try {
// if (resultCode === RESULT_OK && data != null) {
// when (requestCode) {
// exportComicDownloadAndroidQRequestCode -> {
// contentResolver.openOutputStream(data.data!!)?.use { os ->
// val path = Mobile.flatInvoke("exportComicDownload", Gson().toJson(HashMap<Any, Any?>().also { map ->
// map["comicId"] = tmpComicId
// map["dir"] = cacheDir
// }))
// try {
// FileInputStream(path).copyTo(os)
// } finally {
// File(path).delete()
// }
// }
// resourceQueue.put("OK")
// }
// else -> resourceQueue.put(Exception("WTF"))
// }
// } else {
// resourceQueue.put(Exception("NOT OK"))
// }
// } catch (e: Throwable) {
// resourceQueue.put(Exception(e))
// }
// }
// }
}

View File

@ -3,6 +3,10 @@ import 'dart:convert';
import 'package:flutter/services.dart';
// EventChannel
// Flutter的EventChannel只能订阅一次, golang的的通信,
// eventName订阅和取消订阅
var _eventChannel = EventChannel("flatEvent");
StreamSubscription? _eventChannelListen;

View File

@ -3,6 +3,7 @@ import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'config/TimeOffsetHour.dart';
///
double coverWidth = 210;
double coverHeight = 315;

View File

@ -58,6 +58,7 @@ Future<dynamic> saveImage(String path, BuildContext context) async {
}
}
/// ,
Future<dynamic> saveImageQuiet(String path, BuildContext context) async {
if (Platform.isIOS) {
return method.iosSaveFileToImage(path);
@ -98,6 +99,7 @@ Future<String?> chooseFolder(BuildContext context) async {
);
}
///
void confirmCopy(BuildContext context, String content) async {
if (await confirmDialog(context, "复制", content)) {
copyToClipBoard(context, content);

View File

@ -1,3 +1,4 @@
///
class PicaImage {
late String originalName;
late String path;
@ -10,6 +11,7 @@ class PicaImage {
}
}
///
class BasicUser {
late String id;
late String gender;
@ -34,6 +36,7 @@ class BasicUser {
}
}
///
class UserProfile extends BasicUser {
late String birthday;
late String email;
@ -48,6 +51,7 @@ class UserProfile extends BasicUser {
}
}
///
class Page {
late int total;
late int limit;
@ -62,6 +66,7 @@ class Page {
}
}
///
class Category {
late String id;
late String title;
@ -82,6 +87,7 @@ class Category {
}
}
///
class ComicsPage extends Page {
late List<ComicSimple> docs;
@ -93,6 +99,7 @@ class ComicsPage extends Page {
}
}
///
class ComicSimple {
late String id;
late String title;
@ -117,6 +124,7 @@ class ComicSimple {
}
}
///
class ComicInfo extends ComicSimple {
late String description;
late String chineseTeam;
@ -145,6 +153,7 @@ class ComicInfo extends ComicSimple {
}
}
///
class Creator extends BasicUser {
late String slogan;
late String role;
@ -157,6 +166,7 @@ class Creator extends BasicUser {
}
}
///
class Ep {
late String id;
late String title;
@ -171,6 +181,7 @@ class Ep {
}
}
///
class EpPage extends Page {
late List<Ep> docs;
@ -182,6 +193,7 @@ class EpPage extends Page {
}
}
///
class PicturePage extends Page {
late List<Picture> docs;
@ -193,6 +205,7 @@ class PicturePage extends Page {
}
}
///
class Picture {
late String id;
late PicaImage media;
@ -203,6 +216,7 @@ class Picture {
}
}
///
class RemoteImageData {
late int fileSize;
late String format;
@ -227,6 +241,7 @@ class RemoteImageData {
}
}
///
class CommentPage extends Page {
late List<Comment> docs;
@ -238,6 +253,7 @@ class CommentPage extends Page {
}
}
///
class Comment {
late String id;
late String content;
@ -264,6 +280,7 @@ class Comment {
}
}
///
class CommentUser extends BasicUser {
late String role;
@ -272,6 +289,7 @@ class CommentUser extends BasicUser {
}
}
///
class DownloadPicture {
late int rankInEp;
late String fileServer;
@ -294,6 +312,7 @@ class DownloadPicture {
}
}
///
class ViewLog {
late String id;
late String title;
@ -334,6 +353,7 @@ class ViewLog {
}
}
///
class DownloadComic {
late String id;
late String createdAt;
@ -417,6 +437,7 @@ class DownloadComic {
}
}
///
class DownloadEp {
late String comicId;
late String id;
@ -447,6 +468,7 @@ class DownloadEp {
}
}
///
class GamePage extends Page {
late List<GameSimple> docs;
@ -458,6 +480,7 @@ class GamePage extends Page {
}
}
///
class GameSimple {
late String id;
late String title;
@ -484,6 +507,7 @@ class GameSimple {
}
}
///
class GameInfo extends GameSimple {
late String description;
late String updateContent;
@ -519,6 +543,7 @@ class GameInfo extends GameSimple {
}
}
///
class MyCommentsPage extends Page {
late List<MyComment> docs;
@ -528,6 +553,7 @@ class MyCommentsPage extends Page {
}
}
///
class MyComment {
late String id;
late String content;
@ -550,6 +576,7 @@ class MyComment {
}
}
///
class MyCommentComic {
late String id;
late String title;
@ -560,6 +587,7 @@ class MyCommentComic {
}
}
///
class CommentChildrenPage extends Page {
late List<CommentChild> docs;
@ -573,6 +601,7 @@ class CommentChildrenPage extends Page {
}
}
///
class CommentChild extends Comment {
late String parent;

View File

@ -4,13 +4,18 @@ import 'package:flutter/services.dart';
import 'package:pikapi/basic/Entities.dart';
import 'package:pikapi/basic/config/Quality.dart';
/// 使MethodChannel与平台通信
final method = Method._();
class Method {
///
Method._();
/// channel
MethodChannel _channel = MethodChannel("method");
/// , golang进行通信
Future<dynamic> _flatInvoke(String method, dynamic params) {
return _channel.invokeMethod("flatInvoke", {
"method": method,
@ -18,20 +23,7 @@ class Method {
});
}
Future<String> loadTheme() async {
return await _flatInvoke("loadProperty", {
"name": "theme",
"defaultValue": "pink",
});
}
Future<dynamic> saveTheme(String code) async {
return await _flatInvoke("saveProperty", {
"name": "theme",
"value": code,
});
}
///
Future<String> loadProperty(String propertyName, String defaultValue) async {
return await _flatInvoke("loadProperty", {
"name": propertyName,
@ -39,6 +31,7 @@ class Method {
});
}
///
Future<dynamic> saveProperty(String propertyName, String value) {
return _flatInvoke("saveProperty", {
"name": propertyName,
@ -46,61 +39,59 @@ class Method {
});
}
Future<String> loadQuality() async {
return await _flatInvoke("loadProperty", {
"name": "quality",
"defaultValue": ImageQualityOriginal,
});
}
Future<dynamic> saveQuality(String code) async {
return await _flatInvoke("saveProperty", {
"name": "quality",
"value": code,
});
}
///
Future<String> getSwitchAddress() async {
return await _flatInvoke("getSwitchAddress", "");
}
///
Future<dynamic> setSwitchAddress(String switchAddress) async {
return await _flatInvoke("setSwitchAddress", switchAddress);
}
///
Future<String> getProxy() async {
return await _flatInvoke("getProxy", "");
}
///
Future<dynamic> setProxy(String proxy) async {
return await _flatInvoke("setProxy", proxy);
}
///
Future<String> getUsername() async {
return await _flatInvoke("getUsername", "");
}
///
Future<dynamic> setUsername(String username) async {
return await _flatInvoke("setUsername", username);
}
///
Future<String> getPassword() async {
return await _flatInvoke("getPassword", "");
}
///
Future<dynamic> setPassword(String password) async {
return await _flatInvoke("setPassword", password);
}
/// ,
/// token, , true
Future<bool> preLogin() async {
String rsp = await _flatInvoke("preLogin", "");
return rsp == "true";
}
///
Future<dynamic> login() async {
return _flatInvoke("login", "");
}
///
Future<dynamic> register(
String email,
String name,
@ -128,19 +119,24 @@ class Method {
});
}
/// 退
Future<dynamic> clearToken() {
return _flatInvoke("clearToken", "");
}
///
Future<UserProfile> userProfile() async {
String rsp = await _flatInvoke("userProfile", "");
return UserProfile.fromJson(json.decode(rsp));
}
///
Future<dynamic> punchIn() {
return _flatInvoke("punchIn", "");
}
/// 使
/// , ,
Future<RemoteImageData> remoteImageData(
String fileServer, String path) async {
var data = await _flatInvoke("remoteImageData", {
@ -150,6 +146,7 @@ class Method {
return RemoteImageData.fromJson(json.decode(data));
}
/// ,
Future<dynamic> remoteImagePreload(String fileServer, String path) async {
return _flatInvoke("remoteImagePreload", {
"fileServer": fileServer,
@ -157,16 +154,26 @@ class Method {
});
}
///
Future<String> downloadImagePath(String path) async {
return await _flatInvoke("downloadImagePath", path);
}
///
Future<List<Category>> categories() async {
String rsp = await _flatInvoke("categories", "");
List list = json.decode(rsp);
return list.map((e) => Category.fromJson(e)).toList();
}
///
/// [sort]
/// [page]
/// [category]
/// [tag]
/// [creatorId] ID
/// [chineseTeam]
/// * 使
Future<ComicsPage> comics(
String sort,
int page, {
@ -186,10 +193,12 @@ class Method {
return ComicsPage.fromJson(json.decode(rsp));
}
///
Future<ComicsPage> searchComics(String keyword, String sort, int page) {
return searchComicsInCategories(keyword, sort, page, []);
}
/// ,
Future<ComicsPage> searchComicsInCategories(
String keyword, String sort, int page, List<String> categories) async {
String rsp = await _flatInvoke("searchComics", {
@ -201,6 +210,7 @@ class Method {
return ComicsPage.fromJson(json.decode(rsp));
}
///
Future<List<ComicSimple>> randomComics() async {
String data = await _flatInvoke("randomComics", "");
return List.of(jsonDecode(data))
@ -209,6 +219,8 @@ class Method {
.toList();
}
///
/// [type] H24 D7 D30
Future<List<ComicSimple>> leaderboard(String type) async {
String data = await _flatInvoke("leaderboard", type);
return List.of(jsonDecode(data))
@ -217,11 +229,13 @@ class Method {
.toList();
}
///
Future<ComicInfo> comicInfo(String comicId) async {
String rsp = await _flatInvoke("comicInfo", comicId);
return ComicInfo.fromJson(json.decode(rsp));
}
///
Future<EpPage> comicEpPage(String comicId, int page) async {
String rsp = await _flatInvoke("comicEpPage", {
"comicId": comicId,
@ -230,6 +244,7 @@ class Method {
return EpPage.fromJson(json.decode(rsp));
}
/// ,
Future<PicturePage> comicPicturePageWithQuality(
String comicId, int epOrder, int page, String quality) async {
String data = await _flatInvoke("comicPicturePageWithQuality", {
@ -241,14 +256,17 @@ class Method {
return PicturePage.fromJson(json.decode(data));
}
/// /
Future<String> switchLike(String comicId) async {
return await _flatInvoke("switchLike", comicId);
}
/// /
Future<String> switchFavourite(String comicId) async {
return await _flatInvoke("switchFavourite", comicId);
}
///
Future<ComicsPage> favouriteComics(String sort, int page) async {
var rsp = await _flatInvoke("favouriteComics", {
"sort": sort,
@ -257,12 +275,14 @@ class Method {
return ComicsPage.fromJson(json.decode(rsp));
}
/// ...()
Future<List<ComicSimple>> recommendation(String comicId) async {
String rsp = await _flatInvoke("recommendation", comicId);
List list = json.decode(rsp);
return list.map((e) => ComicSimple.fromJson(e)).toList();
}
///
Future<dynamic> postComment(String comicId, String content) {
return _flatInvoke("postComment", {
"comicId": comicId,
@ -270,6 +290,7 @@ class Method {
});
}
///
Future<dynamic> postChildComment(String commentId, String content) {
return _flatInvoke("postChildComment", {
"commentId": commentId,
@ -277,6 +298,7 @@ class Method {
});
}
///
Future<CommentPage> comments(String comicId, int page) async {
var rsp = await _flatInvoke("comments", {
"comicId": comicId,
@ -285,6 +307,7 @@ class Method {
return CommentPage.fromJson(json.decode(rsp));
}
///
Future<CommentChildrenPage> commentChildren(
String comicId,
String commentId,
@ -298,13 +321,13 @@ class Method {
return CommentChildrenPage.fromJson(json.decode(rsp));
}
///
Future<MyCommentsPage> myComments(int page) async {
String response = await _flatInvoke("myComments", "$page");
print("RESPONSE");
print(response);
return MyCommentsPage.fromJson(jsonDecode(response));
}
///
Future<List<ViewLog>> viewLogPage(int offset, int limit) async {
var data = await _flatInvoke("viewLogPage", {
"offset": offset,
@ -314,32 +337,39 @@ class Method {
return list.map((e) => ViewLog.fromJson(e)).toList();
}
///
Future<dynamic> clearAllViewLog() {
return _flatInvoke("clearAllViewLog", "");
}
///
Future<dynamic> deleteViewLog(String id) {
return _flatInvoke("deleteViewLog", id);
}
///
Future<GamePage> games(int page) async {
var data = await _flatInvoke("games", "$page");
return GamePage.fromJson(json.decode(data));
}
///
Future<GameInfo> game(String gameId) async {
var data = await _flatInvoke("game", gameId);
return GameInfo.fromJson(json.decode(data));
}
///
Future clean() {
return _flatInvoke("clean", "");
}
/// [expireSec]
Future autoClean(String expireSec) {
return _flatInvoke("autoClean", expireSec);
}
///
Future storeViewEp(
String comicId, int epOrder, String epTitle, int pictureRank) {
return _flatInvoke("storeViewEp", {
@ -350,6 +380,7 @@ class Method {
});
}
///
Future<ViewLog?> loadView(String comicId) async {
String data = await _flatInvoke("loadView", comicId);
if (data == "") {
@ -358,15 +389,18 @@ class Method {
return ViewLog.fromJson(jsonDecode(data));
}
///
Future<bool> downloadRunning() async {
String rsp = await _flatInvoke("downloadRunning", "");
return rsp == "true";
}
/// /
Future<dynamic> setDownloadRunning(bool status) async {
return _flatInvoke("setDownloadRunning", "$status");
}
///
Future<dynamic> createDownload(
Map<String, dynamic> comic, List<Map<String, dynamic>> epList) async {
return _flatInvoke("createDownload", {
@ -375,6 +409,7 @@ class Method {
});
}
///
Future<dynamic> addDownload(
Map<String, dynamic> comic, List<Map<String, dynamic>> epList) async {
await _flatInvoke("addDownload", {
@ -383,6 +418,7 @@ class Method {
});
}
///
Future<DownloadComic?> loadDownloadComic(String comicId) async {
var data = await _flatInvoke("loadDownloadComic", comicId);
//
@ -392,6 +428,7 @@ class Method {
return DownloadComic.fromJson(json.decode(data));
}
///
Future<List<DownloadComic>> allDownloads() async {
var data = await _flatInvoke("allDownloads", "");
data = jsonDecode(data);
@ -402,26 +439,31 @@ class Method {
return list.map((e) => DownloadComic.fromJson(e)).toList();
}
///
Future<dynamic> deleteDownloadComic(String comicId) async {
return _flatInvoke("deleteDownloadComic", comicId);
}
/// EP
Future<List<DownloadEp>> downloadEpList(String comicId) async {
var data = await _flatInvoke("downloadEpList", comicId);
List list = json.decode(data);
return list.map((e) => DownloadEp.fromJson(e)).toList();
}
/// EP下的图片
Future<List<DownloadPicture>> downloadPicturesByEpId(String epId) async {
var data = await _flatInvoke("downloadPicturesByEpId", epId);
List list = json.decode(data);
return list.map((e) => DownloadPicture.fromJson(e)).toList();
}
///
Future<dynamic> resetFailed() async {
return _flatInvoke("resetAllDownloads", "");
}
/// zip
Future<dynamic> exportComicDownload(String comicId, String dir) {
return _flatInvoke("exportComicDownload", {
"comicId": comicId,
@ -429,12 +471,7 @@ class Method {
});
}
Future<dynamic> exportComicDownloadAndroidQ(String comicId) {
return _channel.invokeMethod("exportComicDownloadAndroidQ", {
"comicId": comicId,
});
}
/// HTML+JPG
Future<dynamic> exportComicDownloadToJPG(String comicId, String dir) {
return _flatInvoke("exportComicDownloadToJPG", {
"comicId": comicId,
@ -442,26 +479,32 @@ class Method {
});
}
/// 使
Future<int> exportComicUsingSocket(String comicId) async {
return int.parse(await _flatInvoke("exportComicUsingSocket", comicId));
}
/// , socket关闭()
Future<dynamic> exportComicUsingSocketExit() {
return _flatInvoke("exportComicUsingSocketExit", "");
}
/// zip导入漫画
Future<dynamic> importComicDownload(String zipPath) {
return _flatInvoke("importComicDownload", zipPath);
}
///
Future<dynamic> importComicDownloadUsingSocket(String addr) {
return _flatInvoke("importComicDownloadUsingSocket", addr);
}
/// ip地址
Future<String> clientIpSet() async {
return await _flatInvoke("clientIpSet", "");
}
///
Future<List<String>> downloadGame(String url) async {
if (url.startsWith("https://game.eroge.xyz/hhh.php")) {
var data = await _flatInvoke("downloadGame", url);
@ -470,18 +513,21 @@ class Method {
return [url];
}
/// (ios)
Future<dynamic> iosSaveFileToImage(String path) async {
return _channel.invokeMethod("iosSaveFileToImage", {
"path": path,
});
}
/// (android)
Future androidSaveFileToImage(String path) async {
return _channel.invokeMethod("androidSaveFileToImage", {
"path": path,
});
}
/// (PC)
Future convertImageToJPEG100(String path, String dir) async {
return _flatInvoke("convertImageToJPEG100", {
"path": path,
@ -489,59 +535,30 @@ class Method {
});
}
Future<bool> getAutoFullScreen() async {
var value = await _flatInvoke("loadProperty", {
"name": "autoFullScreen",
"defaultValue": "false",
});
return value == "true";
}
Future<dynamic> setAutoFullScreen(bool value) async {
return await _flatInvoke("saveProperty", {
"name": "autoFullScreen",
"value": "$value",
});
}
Future<List<String>> getShadowCategories() async {
var value = await _flatInvoke("loadProperty", {
"name": "shadowCategories",
"defaultValue": jsonEncode(<String>[]),
});
return List.of(jsonDecode(value)).map((e) => "$e").toList();
}
Future<dynamic> setShadowCategories(List<String> value) {
return _flatInvoke("saveProperty", {
"name": "shadowCategories",
"value": jsonEncode(value),
});
}
///
Future<List<String>> loadAndroidModes() async {
return List.of(await _channel.invokeMethod("androidGetModes"))
.map((e) => "$e")
.toList();
}
///
Future setAndroidMode(String androidDisplayMode) {
return _channel
.invokeMethod("androidSetMode", {"mode": androidDisplayMode});
}
Future androidGetUiMode() {
return _channel.invokeMethod("androidGetUiMode", {});
}
///
Future<int> androidGetVersion() async {
return await _channel.invokeMethod("androidGetVersion", {});
}
///
Future<String> dataLocal() async {
return await _channel.invokeMethod("dataLocal", {});
}
///
Future<List<String>> androidGetExtendDirs() async {
String? tmp = await _channel.invokeMethod("androidGetExtendDirs", {});
if (tmp != null && tmp.isNotEmpty) {
@ -550,7 +567,9 @@ class Method {
return [];
}
///
Future migrate(String path) async {
return _channel.invokeMethod("migrate", {"path": path});
}
}

View File

@ -5,14 +5,21 @@ import 'package:flutter/material.dart';
import '../Common.dart';
import '../Method.dart';
late bool gAutoFullScreen;
late bool _autoFullScreen;
bool currentAutoFullScreen() {
return _autoFullScreen;
}
const _propertyName = "autoFullScreen";
Future<void> initAutoFullScreen() async {
gAutoFullScreen = await method.getAutoFullScreen();
_autoFullScreen =
(await method.loadProperty(_propertyName, "false")) == "true";
}
String autoFullScreenName() {
return gAutoFullScreen ? "" : "";
return _autoFullScreen ? "" : "";
}
Future<void> chooseAutoFullScreen(BuildContext context) async {
@ -20,7 +27,7 @@ Future<void> chooseAutoFullScreen(BuildContext context) async {
await chooseListDialog<String>(context, "进入阅读器自动全屏", ["", ""]);
if (result != null) {
var target = result == "";
await method.setAutoFullScreen(target);
gAutoFullScreen = target;
await method.saveProperty(_propertyName, "$target");
_autoFullScreen = target;
}
}

View File

@ -1,32 +1,47 @@
///
import 'package:flutter/material.dart';
import '../Method.dart';
late String currentQualityCode;
Future<void> initQuality() async {
currentQualityCode = await method.loadQuality();
}
const ImageQualityOriginal = "original";
const ImageQualityLow = "low";
const ImageQualityMedium = "medium";
const _ImageQualityOriginal = "original";
const _ImageQualityLow = "low";
const _ImageQualityMedium = "medium";
const ImageQualityHigh = "high";
const LabelOriginal = "原图";
const LabelLow = "";
const LabelMedium = "";
const LabelHigh = "";
const _LabelOriginal = "原图";
const _LabelLow = "";
const _LabelMedium = "";
const _LabelHigh = "";
var _qualities = {
LabelOriginal: ImageQualityOriginal,
LabelLow: ImageQualityLow,
LabelMedium: ImageQualityMedium,
LabelHigh: ImageQualityHigh,
_LabelOriginal: _ImageQualityOriginal,
_LabelLow: _ImageQualityLow,
_LabelMedium: _ImageQualityMedium,
_LabelHigh: ImageQualityHigh,
};
late String _currentQualityCode;
String currentQualityCode() {
return _currentQualityCode;
}
String _currentQualityName() {
for (var e in _qualities.entries) {
if (e.value == _currentQualityCode) {
return e.key;
}
}
return '';
}
const _propertyName = "quality";
const _defaultValue = _ImageQualityOriginal;
Future<void> initQuality() async {
_currentQualityCode = await method.loadProperty(_propertyName, _defaultValue);
}
Future<void> chooseQuality(BuildContext context) async {
String? code = await showDialog<String>(
context: context,
@ -47,16 +62,22 @@ Future<void> chooseQuality(BuildContext context) async {
},
);
if (code != null) {
method.saveQuality(code);
currentQualityCode = code;
method.saveProperty(_propertyName, code);
_currentQualityCode = code;
}
}
String currentQualityName() {
for (var e in _qualities.entries) {
if (e.value == currentQualityCode) {
return e.key;
}
}
return '';
Widget qualitySetting() {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile(
title: Text("浏览时的图片质量"),
subtitle: Text(_currentQualityName()),
onTap: () async {
await chooseQuality(context);
setState(() {});
},
);
},
);
}

View File

@ -1,5 +1,7 @@
///
import 'dart:convert';
import 'package:event/event.dart';
import 'package:flutter/material.dart';
import 'package:multi_select_flutter/dialog/mult_select_dialog.dart';
@ -9,14 +11,28 @@ import '../Method.dart';
import '../store/Categories.dart';
late List<String> shadowCategories;
var shadowCategoriesEvent = Event<EventArgs>();
Future<void> initShadowCategories() async {
shadowCategories = await method.getShadowCategories();
// mapper
const _propertyName = "shadowCategories";
///
Future<List<String>> _loadShadowCategories() async {
var value = await method.loadProperty(_propertyName, jsonEncode(<String>[]));
return List.of(jsonDecode(value)).map((e) => "$e").toList();
}
Future<void> chooseShadowCategories(BuildContext context) async {
///
Future<dynamic> _saveShadowCategories(List<String> value) {
return method.saveProperty(_propertyName, jsonEncode(value));
}
Future<void> initShadowCategories() async {
shadowCategories = await _loadShadowCategories();
}
Future<void> _chooseShadowCategories(BuildContext context) async {
await showDialog(
context: context,
builder: (ctx) {
@ -35,7 +51,7 @@ Future<void> chooseShadowCategories(BuildContext context) async {
initialValue: initialValue,
onConfirm: (List<String>? value) async {
if (value != null) {
await method.setShadowCategories(value);
await _saveShadowCategories(value);
shadowCategories = value;
shadowCategoriesEvent.broadcast();
}
@ -48,8 +64,23 @@ Future<void> chooseShadowCategories(BuildContext context) async {
Widget shadowCategoriesActionButton(BuildContext context) {
return IconButton(
onPressed: () {
chooseShadowCategories(context);
_chooseShadowCategories(context);
},
icon: Icon(Icons.hide_source),
);
}
Widget shadowCategoriesSetting() {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile(
title: Text("封印"),
subtitle: Text(jsonEncode(shadowCategories)),
onTap: () async {
await _chooseShadowCategories(context);
setState(() {});
},
);
},
);
}

View File

@ -7,6 +7,9 @@ import 'package:pikapi/basic/Common.dart';
import '../Method.dart';
import 'Platform.dart';
//
const _fontFamilyProperty = "fontFamily";
String? _fontFamily;
@ -50,6 +53,8 @@ Widget fontSetting() {
);
}
//
//
abstract class _ThemePackage {
String code();
@ -168,6 +173,9 @@ final _themePackages = <_ThemePackage>[
//
var themeEvent = Event<EventArgs>();
const _themePropertyName = "theme";
const _defaultThemeCode = "pink";
String? _themeCode;
ThemeData? _themeData;
ThemeData? _currentDarkTheme;
@ -217,7 +225,9 @@ const _nightModePropertyName = "androidNightMode";
Future<dynamic> initTheme() async {
_androidNightMode =
await method.loadProperty(_nightModePropertyName, "true") == "true";
_changeThemeByCode(await method.loadTheme());
_changeThemeByCode(
await method.loadProperty(_themePropertyName, _defaultThemeCode),
);
}
//
@ -292,7 +302,7 @@ Future<dynamic> chooseTheme(BuildContext buildContext) async {
},
);
if (theme != null) {
method.saveTheme(theme);
method.saveProperty(_themePropertyName, theme);
_changeThemeByCode(theme);
}
}

View File

@ -30,7 +30,7 @@ class ComicReaderScreen extends StatefulWidget {
this.initPictureRank,
bool? autoFullScreen,
}) : super(key: key) {
this.autoFullScreen = autoFullScreen ?? gAutoFullScreen;
this.autoFullScreen = autoFullScreen ?? currentAutoFullScreen();
}
@override
@ -56,7 +56,7 @@ class _ComicReaderScreenState extends State<ComicReaderScreen> {
widget.comicInfo.id,
widget.currentEpOrder,
++_needLoadPage,
currentQualityCode,
currentQualityCode(),
);
list.addAll(page.docs.map((element) => element.media));
} while (page.pages > page.page);

View File

@ -29,7 +29,7 @@ class DownloadReaderScreen extends StatefulWidget {
this.initPictureRank,
bool? autoFullScreen,
}) : super(key: key) {
this.autoFullScreen = autoFullScreen ?? gAutoFullScreen;
this.autoFullScreen = autoFullScreen ?? currentAutoFullScreen();
}
@override

View File

@ -38,14 +38,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
Divider(),
NetworkSetting(),
Divider(),
ListTile(
title: Text("浏览时的图片质量"),
subtitle: Text(currentQualityName()),
onTap: () async {
await chooseQuality(context);
setState(() {});
},
),
qualitySetting(),
ListTile(
title: Text("阅读器模式"),
subtitle: Text(currentReaderTypeName()),
@ -81,14 +74,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
volumeControllerSetting(),
keyboardControllerSetting(),
Divider(),
ListTile(
title: Text("封印"),
subtitle: Text(jsonEncode(shadowCategories)),
onTap: () async {
await chooseShadowCategories(context);
setState(() {});
},
),
shadowCategoriesSetting(),
ListTile(
title: Text("列表页加载方式"),
subtitle: Text(currentPagerActionName()),