mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
♻️ 全面整理重构
This commit is contained in:
@@ -4,41 +4,33 @@
|
||||
* @since Beta v0.6.3
|
||||
*/
|
||||
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import TGSqlite from "@Sqlite/index.js";
|
||||
import { core, event, webviewWindow } from "@tauri-apps/api";
|
||||
import type { Event, UnlistenFn } from "@tauri-apps/api/event";
|
||||
|
||||
import showSnackbar from "../components/func/snackbar.js";
|
||||
import TGSqlite from "../plugins/Sqlite/index.js";
|
||||
import { useAppStore } from "../store/modules/app.js";
|
||||
import { useUserStore } from "../store/modules/user.js";
|
||||
import TGConstant from "../web/constant/TGConstant.js";
|
||||
import BBSApi from "../web/request/bbsReq.js";
|
||||
import OtherApi from "../web/request/otherReq.js";
|
||||
import PassportApi from "../web/request/passportReq.js";
|
||||
import TakumiApi from "../web/request/takumiReq.js";
|
||||
import { getDS4JS } from "../web/utils/getRequestHeader.js";
|
||||
|
||||
import { parseLink } from "./linkParser.js";
|
||||
import TGLogger from "./TGLogger.js";
|
||||
import { createPost } from "./TGWindow.js";
|
||||
import { getDeviceInfo } from "./toolFunc.js";
|
||||
|
||||
// invoke 参数
|
||||
interface InvokeArg {
|
||||
func: string;
|
||||
}
|
||||
import { useAppStore } from "@/store/modules/app.js";
|
||||
import { useUserStore } from "@/store/modules/user.js";
|
||||
import TGConstant from "@/web/constant/TGConstant.js";
|
||||
import BBSApi from "@/web/request/bbsReq.js";
|
||||
import OtherApi from "@/web/request/otherReq.js";
|
||||
import PassportApi from "@/web/request/passportReq.js";
|
||||
import TakumiApi from "@/web/request/takumiReq.js";
|
||||
import { getDS4JS } from "@/web/utils/getRequestHeader.js";
|
||||
|
||||
/**
|
||||
* @class TGClient
|
||||
* @since Beta v0.4.4
|
||||
* @description 米游社客户端
|
||||
*/
|
||||
class TGClient {
|
||||
// invoke 参数
|
||||
type InvokeArg = { func: string };
|
||||
|
||||
class Client {
|
||||
/**
|
||||
* @private 监听实例
|
||||
* @since Beta v0.3.3
|
||||
* @type {EventEmitter}
|
||||
* @memberof TGClient
|
||||
*/
|
||||
private listener: UnlistenFn | undefined;
|
||||
|
||||
@@ -46,7 +38,6 @@ class TGClient {
|
||||
* @private 模拟路由
|
||||
* @since Beta v0.3.4
|
||||
* @type {string[]}
|
||||
* @memberof TGClient
|
||||
*/
|
||||
private route: string[] = [];
|
||||
|
||||
@@ -54,13 +45,19 @@ class TGClient {
|
||||
* @constructor
|
||||
* @since Beta v0.3.4
|
||||
* @description 构造函数
|
||||
* @memberof TGClient
|
||||
*/
|
||||
constructor() {
|
||||
private constructor() {
|
||||
this.route = [];
|
||||
this.listener = undefined;
|
||||
}
|
||||
|
||||
private static instance: Client | null = null;
|
||||
|
||||
static getInstance(): Client {
|
||||
if (this.instance === null) this.instance = new Client();
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @func run
|
||||
* @since Beta v0.3.4
|
||||
@@ -69,7 +66,7 @@ class TGClient {
|
||||
*/
|
||||
async run(): Promise<void> {
|
||||
if (this.listener === undefined) {
|
||||
this.listener = await event.listen("post_mhy_client", async (arg: Event<string>) => {
|
||||
this.listener = await event.listen<string>("post_mhy_client", async (arg: Event<string>) => {
|
||||
await this.handleCallback(arg);
|
||||
});
|
||||
} else {
|
||||
@@ -88,11 +85,7 @@ class TGClient {
|
||||
* @returns {void} - 无返回值
|
||||
*/
|
||||
async callback(callback: string, data: object): Promise<void> {
|
||||
const response = {
|
||||
retcode: 0,
|
||||
message: "success",
|
||||
data: data ?? {},
|
||||
};
|
||||
const response = { retcode: 0, message: "success", data: data ?? {} };
|
||||
const js = `javascript:mhyWebBridge("${callback}", ${JSON.stringify(response)});`;
|
||||
console.info(`[callback] ${js}`);
|
||||
await core.invoke("execute_js", { label: "mhy_client", js });
|
||||
@@ -926,6 +919,6 @@ class TGClient {
|
||||
}
|
||||
}
|
||||
|
||||
const mhyClient = new TGClient();
|
||||
const TGClient = Client.getInstance();
|
||||
|
||||
export default mhyClient;
|
||||
export default TGClient;
|
||||
|
||||
@@ -45,17 +45,10 @@ async function TGHttp<T>(
|
||||
): Promise<T | { data: Promise<T>; resp: Response }> {
|
||||
const httpHeaders = new Headers();
|
||||
if (options.headers) {
|
||||
for (const key in options.headers) {
|
||||
httpHeaders.append(key, options.headers[key]);
|
||||
}
|
||||
}
|
||||
const fetchOptions: RequestInit = {
|
||||
method: options.method,
|
||||
headers: httpHeaders,
|
||||
};
|
||||
if (options.body) {
|
||||
fetchOptions.body = options.body;
|
||||
for (const key in options.headers) httpHeaders.append(key, options.headers[key]);
|
||||
}
|
||||
const fetchOptions: RequestInit = { method: options.method, headers: httpHeaders };
|
||||
if (options.body) fetchOptions.body = options.body;
|
||||
if (options.query) {
|
||||
const query = new URLSearchParams(options.query).toString();
|
||||
url += `?${query}`;
|
||||
@@ -66,9 +59,7 @@ async function TGHttp<T>(
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
const data = options.isBlob ? res.arrayBuffer() : res.json();
|
||||
if (fullResponse) {
|
||||
return { data, resp: res };
|
||||
}
|
||||
if (fullResponse) return { data, resp: res };
|
||||
return data;
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
|
||||
@@ -4,21 +4,26 @@
|
||||
* @since Beta v0.5.0
|
||||
*/
|
||||
|
||||
import { info, warn, error, attachConsole } from "@tauri-apps/plugin-log";
|
||||
import { attachConsole, error, info, warn } from "@tauri-apps/plugin-log";
|
||||
|
||||
/**
|
||||
* @description 日志工具
|
||||
* @since Beta v0.4.4
|
||||
*/
|
||||
class TGLogger {
|
||||
constructor() {
|
||||
class Logger {
|
||||
private constructor() {
|
||||
if (import.meta.env.MODE === "development") {
|
||||
void attachConsole().then(() => {
|
||||
console.log("Console attached");
|
||||
});
|
||||
void attachConsole().then(() => console.log("Console attached"));
|
||||
}
|
||||
}
|
||||
|
||||
private static instance: Logger | null = null;
|
||||
|
||||
static getInstance(): Logger {
|
||||
if (this.instance === null) this.instance = new Logger();
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 输出日志-信息
|
||||
* @since Beta v0.4.2
|
||||
@@ -56,4 +61,6 @@ class TGLogger {
|
||||
}
|
||||
}
|
||||
|
||||
export default new TGLogger();
|
||||
const TGLogger = Logger.getInstance();
|
||||
|
||||
export default TGLogger;
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
* @since Beta v0.6.4
|
||||
*/
|
||||
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import { path } from "@tauri-apps/api";
|
||||
import { save } from "@tauri-apps/plugin-dialog";
|
||||
import { writeFile } from "@tauri-apps/plugin-fs";
|
||||
import html2canvas from "html2canvas";
|
||||
import { storeToRefs } from "pinia";
|
||||
|
||||
import showSnackbar from "../components/func/snackbar.js";
|
||||
import { useAppStore } from "../store/modules/app.js";
|
||||
|
||||
import TGHttp from "./TGHttp.js";
|
||||
import TGLogger from "./TGLogger.js";
|
||||
import { bytesToSize } from "./toolFunc.js";
|
||||
|
||||
import { useAppStore } from "@/store/modules/app.js";
|
||||
|
||||
/**
|
||||
* @description 保存图片-canvas
|
||||
* @since Beta v0.6.4
|
||||
@@ -77,14 +77,9 @@ export async function getImageBuffer(url: string): Promise<Uint8Array> {
|
||||
*/
|
||||
function getShareImgBgColor(): string {
|
||||
let theme = localStorage.getItem("theme");
|
||||
if (theme) {
|
||||
theme = JSON.parse(theme).theme;
|
||||
}
|
||||
if (theme === "dark") {
|
||||
return "#1e1e1e";
|
||||
} else {
|
||||
return "#f9f6f2";
|
||||
}
|
||||
if (theme) theme = JSON.parse(theme).theme;
|
||||
if (theme === "dark") return "#1e1e1e";
|
||||
return "#f9f6f2";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,19 +136,6 @@ export async function generateShareImg(
|
||||
await saveCanvasImg(buffer, fileName);
|
||||
return;
|
||||
}
|
||||
// if (size > 80000000) {
|
||||
// showSnackbar.warn(`图像过大(${sizeStr}),无法保存`, 3000);
|
||||
// return;
|
||||
// }
|
||||
// if (size > 20000000) {
|
||||
// const sizeStr = bytesToSize(size);
|
||||
// const saveCheck = await showDialog.check("图像过大", `图像大小为 ${sizeStr},是否保存到文件?`);
|
||||
// if (saveCheck === true) {
|
||||
// await saveCanvasImg(buffer, fileName);
|
||||
// return;
|
||||
// }
|
||||
// showSnackbar.warn("将尝试保存到剪贴板");
|
||||
// }
|
||||
try {
|
||||
await copyToClipboard(buffer);
|
||||
showSnackbar.success(`已将 ${fileName} 复制到剪贴板,大小为 ${sizeStr}`);
|
||||
@@ -177,10 +159,6 @@ export async function copyToClipboard(buffer: Uint8Array): Promise<void> {
|
||||
// NotAllowedError:
|
||||
// The request is not allowed by the user agent or the platform in the current context,
|
||||
// possibly because the user denied permission.
|
||||
await navigator.clipboard.write([
|
||||
new ClipboardItem({
|
||||
[blob.type]: blob,
|
||||
}),
|
||||
]);
|
||||
await navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
@@ -4,16 +4,24 @@
|
||||
* @since Beta v0.5.0
|
||||
*/
|
||||
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import { platform } from "@tauri-apps/plugin-os";
|
||||
import { Command } from "@tauri-apps/plugin-shell";
|
||||
|
||||
import showSnackbar from "../components/func/snackbar.js";
|
||||
|
||||
/**
|
||||
* @description Shell工具
|
||||
* @since Beta v0.5.0
|
||||
*/
|
||||
class TGShell {
|
||||
class Shell {
|
||||
private constructor() {}
|
||||
|
||||
private static instance: Shell | null = null;
|
||||
|
||||
static getInstance(): Shell {
|
||||
if (this.instance === null) this.instance = new Shell();
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 打开文件
|
||||
* @since Beta v0.5.0
|
||||
@@ -33,4 +41,6 @@ class TGShell {
|
||||
}
|
||||
}
|
||||
|
||||
export default new TGShell();
|
||||
const TGShell = Shell.getInstance();
|
||||
|
||||
export default TGShell;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { core, window as TauriWindow } from "@tauri-apps/api";
|
||||
import { WindowOptions } from "@tauri-apps/api/window";
|
||||
import type { WindowOptions } from "@tauri-apps/api/window";
|
||||
|
||||
import TGLogger from "./TGLogger.js";
|
||||
|
||||
@@ -39,9 +39,7 @@ export async function createTGWindow(
|
||||
visible,
|
||||
};
|
||||
const window = await TauriWindow.Window.getByLabel(label);
|
||||
if (window !== null) {
|
||||
await window.destroy();
|
||||
}
|
||||
if (window !== null) await window.destroy();
|
||||
await core.invoke("create_window", { label, url, option: windowOpt });
|
||||
}
|
||||
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
* @since Beta v0.6.0
|
||||
*/
|
||||
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import { app } from "@tauri-apps/api";
|
||||
import { readTextFile } from "@tauri-apps/plugin-fs";
|
||||
import Ajv from "ajv";
|
||||
import { ErrorObject } from "ajv/lib/types/index.js";
|
||||
|
||||
import showSnackbar from "../components/func/snackbar.js";
|
||||
import { UiafSchema } from "../data/index.js";
|
||||
import type { ErrorObject } from "ajv/lib/types/index.js";
|
||||
|
||||
import TGLogger from "./TGLogger.js";
|
||||
|
||||
import { UiafSchema } from "@/data/index.js";
|
||||
|
||||
/**
|
||||
* @description 获取 UIAF 头部信息
|
||||
* @since Beta v0.3.4
|
||||
@@ -95,5 +95,5 @@ export async function verifyUiafDataClipboard(): Promise<boolean> {
|
||||
*/
|
||||
export async function readUiafData(userPath: string): Promise<TGApp.Plugins.UIAF.Data> {
|
||||
const fileData = await readTextFile(userPath);
|
||||
return <TGApp.Plugins.UIAF.Data>JSON.parse(fileData);
|
||||
return JSON.parse(fileData) satisfies TGApp.Plugins.UIAF.Data;
|
||||
}
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
* @since Beta v0.6.5
|
||||
*/
|
||||
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import TSUserGacha from "@Sqlite/modules/userGacha.js";
|
||||
import { app, path } from "@tauri-apps/api";
|
||||
import { readTextFile, writeTextFile } from "@tauri-apps/plugin-fs";
|
||||
import { Ajv } from "ajv";
|
||||
import { ErrorObject } from "ajv/lib/types/index.js";
|
||||
|
||||
import showSnackbar from "../components/func/snackbar.js";
|
||||
import { Uigf4Schema, UigfSchema } from "../data/index.js";
|
||||
import TSUserGacha from "../plugins/Sqlite/modules/userGacha.js";
|
||||
import type { ErrorObject } from "ajv/lib/types/index.js";
|
||||
|
||||
import TGLogger from "./TGLogger.js";
|
||||
import { timestampToDate } from "./toolFunc.js";
|
||||
|
||||
import { Uigf4Schema, UigfSchema } from "@/data/index.js";
|
||||
|
||||
/**
|
||||
* @description 获取 UIGF 时区
|
||||
* @since Beta v0.3.5
|
||||
@@ -141,13 +141,11 @@ function validateUigfData(data: object): boolean {
|
||||
function validateUigf4Data(data: object): boolean {
|
||||
const ajv = new Ajv();
|
||||
const validate4 = ajv.compile(Uigf4Schema);
|
||||
if (!validate4(data)) {
|
||||
if (!validate4.errors || validate4.errors.length === 0) return false;
|
||||
const error: ErrorObject = validate4.errors[0];
|
||||
showSnackbar.error(`${error.instancePath || error.schemaPath} ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (validate4(data)) return true;
|
||||
if (!validate4.errors || validate4.errors.length === 0) return false;
|
||||
const error: ErrorObject = validate4.errors[0];
|
||||
showSnackbar.error(`${error.instancePath || error.schemaPath} ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +156,7 @@ function validateUigf4Data(data: object): boolean {
|
||||
*/
|
||||
export async function readUigfData(userPath: string): Promise<TGApp.Plugins.UIGF.Schema> {
|
||||
const fileData: string = await readTextFile(userPath);
|
||||
return JSON.parse(fileData);
|
||||
return JSON.parse(fileData) satisfies TGApp.Plugins.UIGF.Schema;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,7 +167,7 @@ export async function readUigfData(userPath: string): Promise<TGApp.Plugins.UIGF
|
||||
*/
|
||||
export async function readUigf4Data(userPath: string): Promise<TGApp.Plugins.UIGF.Schema4> {
|
||||
const fileData: string = await readTextFile(userPath);
|
||||
return JSON.parse(fileData);
|
||||
return JSON.parse(fileData) satisfies TGApp.Plugins.UIGF.Schema4;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,10 +183,7 @@ export async function exportUigfData(
|
||||
gachaList: TGApp.Sqlite.GachaRecords.SingleTable[],
|
||||
savePath?: string,
|
||||
): Promise<void> {
|
||||
const UigfData = {
|
||||
info: await getUigfHeader(uid),
|
||||
list: convertDataToUigf(gachaList),
|
||||
};
|
||||
const UigfData = { info: await getUigfHeader(uid), list: convertDataToUigf(gachaList) };
|
||||
const filePath = savePath ?? `${await path.appLocalDataDir()}userData\\UIGF_${uid}.json`;
|
||||
await writeTextFile(filePath, JSON.stringify(UigfData));
|
||||
}
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
* @description 用户数据的备份、恢复、迁移
|
||||
* @since Beta v0.6.3
|
||||
*/
|
||||
import showLoading from "@comp/func/loading.js";
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import TSUserAbyss from "@Sqlite/modules/userAbyss.js";
|
||||
import TSUserAccount from "@Sqlite/modules/userAccount.js";
|
||||
import TSUserAchi from "@Sqlite/modules/userAchi.js";
|
||||
import TSUserCombat from "@Sqlite/modules/userCombat.js";
|
||||
import TSUserGacha from "@Sqlite/modules/userGacha.js";
|
||||
import { exists, mkdir } from "@tauri-apps/plugin-fs";
|
||||
|
||||
import showLoading from "../components/func/loading.js";
|
||||
import showSnackbar from "../components/func/snackbar.js";
|
||||
import TSUserAbyss from "../plugins/Sqlite/modules/userAbyss.js";
|
||||
import TSUserAccount from "../plugins/Sqlite/modules/userAccount.js";
|
||||
import TSUserAchi from "../plugins/Sqlite/modules/userAchi.js";
|
||||
import TSUserCombat from "../plugins/Sqlite/modules/userCombat.js";
|
||||
import TSUserGacha from "../plugins/Sqlite/modules/userGacha.js";
|
||||
|
||||
import TGLogger from "./TGLogger.js";
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
* @since Beta v0.6.5
|
||||
*/
|
||||
|
||||
import showDialog from "@comp/func/dialog.js";
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import { emit } from "@tauri-apps/api/event";
|
||||
|
||||
import showDialog from "../components/func/dialog.js";
|
||||
import showSnackbar from "../components/func/snackbar.js";
|
||||
import { getGameId } from "../web/utils/tools.js";
|
||||
|
||||
import TGClient from "./TGClient.js";
|
||||
import { createPost } from "./TGWindow.js";
|
||||
|
||||
import { getGameId } from "@/web/utils/tools.js";
|
||||
|
||||
/**
|
||||
* @function parsePost
|
||||
* @since Beta v0.5.5
|
||||
|
||||
@@ -71,9 +71,7 @@ export function getDeviceInfo(key: keyof TGApp.App.Device.DeviceInfo): string {
|
||||
if (localDevice === null) {
|
||||
deviceInfo = getInitDeviceInfo();
|
||||
localStorage.setItem("deviceInfo", JSON.stringify({ deviceInfo }));
|
||||
} else {
|
||||
deviceInfo = JSON.parse(localDevice).deviceInfo;
|
||||
}
|
||||
} else deviceInfo = JSON.parse(localDevice).deviceInfo;
|
||||
return deviceInfo[key];
|
||||
}
|
||||
|
||||
@@ -104,9 +102,7 @@ export async function getCacheDir(): Promise<string[] | false> {
|
||||
const codeCache = `${cacheDir}${path.sep()}EBWebview${path.sep()}Default${path.sep()}Code Cache`;
|
||||
return [cache, codeCache];
|
||||
}
|
||||
if (osType === "macos") {
|
||||
return [`${cacheDir}${path.sep()}WebKit`];
|
||||
}
|
||||
if (osType === "macos") return [`${cacheDir}${path.sep()}WebKit`];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user