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")!!) setMode(call.argument("mode")!!)
} }
"androidGetVersion" -> Build.VERSION.SDK_INT "androidGetVersion" -> Build.VERSION.SDK_INT
// "exportComicDownloadAndroidQ" -> {
// exportComicDownloadAndroidQ(call.argument("comicId")!!)
// }
// 现在的文件储存路径, 默认路径返回空字符串 "" // 现在的文件储存路径, 默认路径返回空字符串 ""
"dataLocal" -> androidDataLocal() "dataLocal" -> androidDataLocal()
// 迁移到那个地方, 如果是空字符串则迁移会默认位置 // 迁移到那个地方, 如果是空字符串则迁移会默认位置
@ -341,63 +338,4 @@ class MainActivity : FlutterActivity() {
return super.onKeyDown(keyCode, event) 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'; import 'package:flutter/services.dart';
// EventChannel
// Flutter的EventChannel只能订阅一次, golang的的通信,
// eventName订阅和取消订阅
var _eventChannel = EventChannel("flatEvent"); var _eventChannel = EventChannel("flatEvent");
StreamSubscription? _eventChannelListen; StreamSubscription? _eventChannelListen;

View File

@ -3,6 +3,7 @@ import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'config/TimeOffsetHour.dart'; import 'config/TimeOffsetHour.dart';
///
double coverWidth = 210; double coverWidth = 210;
double coverHeight = 315; 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 { Future<dynamic> saveImageQuiet(String path, BuildContext context) async {
if (Platform.isIOS) { if (Platform.isIOS) {
return method.iosSaveFileToImage(path); return method.iosSaveFileToImage(path);
@ -98,6 +99,7 @@ Future<String?> chooseFolder(BuildContext context) async {
); );
} }
///
void confirmCopy(BuildContext context, String content) async { void confirmCopy(BuildContext context, String content) async {
if (await confirmDialog(context, "复制", content)) { if (await confirmDialog(context, "复制", content)) {
copyToClipBoard(context, content); copyToClipBoard(context, content);

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,7 @@
/// ///
import 'dart:convert';
import 'package:event/event.dart'; import 'package:event/event.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:multi_select_flutter/dialog/mult_select_dialog.dart'; import 'package:multi_select_flutter/dialog/mult_select_dialog.dart';
@ -9,14 +11,28 @@ import '../Method.dart';
import '../store/Categories.dart'; import '../store/Categories.dart';
late List<String> shadowCategories; late List<String> shadowCategories;
var shadowCategoriesEvent = Event<EventArgs>(); var shadowCategoriesEvent = Event<EventArgs>();
Future<void> initShadowCategories() async { // mapper
shadowCategories = await method.getShadowCategories();
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( await showDialog(
context: context, context: context,
builder: (ctx) { builder: (ctx) {
@ -35,7 +51,7 @@ Future<void> chooseShadowCategories(BuildContext context) async {
initialValue: initialValue, initialValue: initialValue,
onConfirm: (List<String>? value) async { onConfirm: (List<String>? value) async {
if (value != null) { if (value != null) {
await method.setShadowCategories(value); await _saveShadowCategories(value);
shadowCategories = value; shadowCategories = value;
shadowCategoriesEvent.broadcast(); shadowCategoriesEvent.broadcast();
} }
@ -48,8 +64,23 @@ Future<void> chooseShadowCategories(BuildContext context) async {
Widget shadowCategoriesActionButton(BuildContext context) { Widget shadowCategoriesActionButton(BuildContext context) {
return IconButton( return IconButton(
onPressed: () { onPressed: () {
chooseShadowCategories(context); _chooseShadowCategories(context);
}, },
icon: Icon(Icons.hide_source), 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 '../Method.dart';
import 'Platform.dart'; import 'Platform.dart';
//
const _fontFamilyProperty = "fontFamily"; const _fontFamilyProperty = "fontFamily";
String? _fontFamily; String? _fontFamily;
@ -50,6 +53,8 @@ Widget fontSetting() {
); );
} }
//
// //
abstract class _ThemePackage { abstract class _ThemePackage {
String code(); String code();
@ -168,6 +173,9 @@ final _themePackages = <_ThemePackage>[
// //
var themeEvent = Event<EventArgs>(); var themeEvent = Event<EventArgs>();
const _themePropertyName = "theme";
const _defaultThemeCode = "pink";
String? _themeCode; String? _themeCode;
ThemeData? _themeData; ThemeData? _themeData;
ThemeData? _currentDarkTheme; ThemeData? _currentDarkTheme;
@ -217,7 +225,9 @@ const _nightModePropertyName = "androidNightMode";
Future<dynamic> initTheme() async { Future<dynamic> initTheme() async {
_androidNightMode = _androidNightMode =
await method.loadProperty(_nightModePropertyName, "true") == "true"; 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) { if (theme != null) {
method.saveTheme(theme); method.saveProperty(_themePropertyName, theme);
_changeThemeByCode(theme); _changeThemeByCode(theme);
} }
} }

View File

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

View File

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

View File

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