mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
♻️ 姑且没登录的功能都给试了下
This commit is contained in:
@@ -13,6 +13,7 @@ import { fetch } from "@tauri-apps/plugin-http";
|
||||
* @property {Record<string,string>} headers 请求头
|
||||
* @property {Record<string,string>} query 请求参数
|
||||
* @property {string} body 请求体
|
||||
* @property {boolean} isBlob 是否为Blob
|
||||
* @return TGHttpParams
|
||||
*/
|
||||
type TGHttpParams = {
|
||||
@@ -20,6 +21,7 @@ type TGHttpParams = {
|
||||
headers?: Record<string, string>;
|
||||
query?: Record<string, any>;
|
||||
body?: string;
|
||||
isBlob?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -31,24 +33,29 @@ type TGHttpParams = {
|
||||
* @returns {Promise<T>}
|
||||
*/
|
||||
async function TGHttp<T>(url: string, options: TGHttpParams): Promise<T> {
|
||||
let httpHeaders = new Headers();
|
||||
const httpHeaders = new Headers();
|
||||
if (options.headers) {
|
||||
httpHeaders = new Headers(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;
|
||||
}
|
||||
if (options.query) {
|
||||
const query = new URLSearchParams(options.query).toString();
|
||||
url += `?${query}`;
|
||||
}
|
||||
if (options.body) {
|
||||
fetchOptions.body = options.body;
|
||||
}
|
||||
console.log("fetch url: ", url);
|
||||
console.log("fetch options: ", fetchOptions);
|
||||
return await fetch(url, fetchOptions)
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
if (options.isBlob) return res.arrayBuffer();
|
||||
return res.json();
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* @file utils/TGLogger.ts
|
||||
* @description 日志工具
|
||||
* @since Beta v0.4.4
|
||||
* @since Beta v0.5.0
|
||||
*/
|
||||
|
||||
import { info, warn, error, attachConsole } from "tauri-plugin-log-api";
|
||||
import { info, warn, error, attachConsole } from "@tauri-apps/plugin-log";
|
||||
|
||||
/**
|
||||
* @description 日志工具
|
||||
|
||||
@@ -50,7 +50,7 @@ export async function saveCanvasImg(
|
||||
* @returns {Promise<string>} 图片元素
|
||||
*/
|
||||
export async function saveImgLocal(url: string): Promise<string> {
|
||||
const res = await TGHttp<Uint8Array>(url, { method: "GET" });
|
||||
const res = await TGHttp<Uint8Array>(url, { method: "GET", isBlob: true });
|
||||
const buffer = new Uint8Array(res);
|
||||
const blob = new Blob([buffer], { type: "image/png" });
|
||||
return URL.createObjectURL(blob);
|
||||
|
||||
@@ -1,28 +1,35 @@
|
||||
/**
|
||||
* @file utils/TGShell.ts
|
||||
* @description Shell工具
|
||||
* @since Beta v0.4.4
|
||||
* @since Beta v0.5.0
|
||||
*/
|
||||
|
||||
import { os, shell } from "@tauri-apps/api";
|
||||
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.4.4
|
||||
* @since Beta v0.5.0
|
||||
*/
|
||||
class TGShell {
|
||||
/**
|
||||
* @description 打开文件
|
||||
* @since Beta v0.4.4
|
||||
* @since Beta v0.5.0
|
||||
* @param {string} path - 文件路径
|
||||
* @returns {Promise<void>} 无返回值
|
||||
*/
|
||||
async openPath(path: string): Promise<void> {
|
||||
const platform = await os.platform();
|
||||
const plat = platform();
|
||||
let command: string;
|
||||
if (platform === "win32") command = "win_open";
|
||||
else command = "mac_open";
|
||||
await new shell.Command(command, [path]).execute();
|
||||
if (plat === "windows") command = "win_open";
|
||||
else if (plat === "macos") command = "mac_open";
|
||||
else {
|
||||
showSnackbar({ text: "暂不支持该平台", color: "warn" });
|
||||
return;
|
||||
}
|
||||
await Command.create(command, [path]).execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { core, window as TauriWindow } from "@tauri-apps/api";
|
||||
import type { WindowOptions } from "@tauri-apps/api/window";
|
||||
import { WindowOptions } from "@tauri-apps/api/window";
|
||||
|
||||
import TGLogger from "./TGLogger.js";
|
||||
|
||||
@@ -13,7 +13,6 @@ import TGLogger from "./TGLogger.js";
|
||||
* @description 创建TG窗口
|
||||
* @since Beta v0.5.0
|
||||
* @see https://github.com/tauri-apps/tauri/issues/5380
|
||||
* @todo 需要根据 2.0 版本的 Tauri API 进行修改
|
||||
* @param {string} url 窗口地址
|
||||
* @param {string} label 窗口标签
|
||||
* @param {string} title 窗口标题
|
||||
@@ -21,9 +20,9 @@ import TGLogger from "./TGLogger.js";
|
||||
* @param {number} height 窗口高度
|
||||
* @param {boolean} resizable 是否可调整大小
|
||||
* @param {boolean} visible 是否可见
|
||||
* @returns {void}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export function createTGWindow(
|
||||
export async function createTGWindow(
|
||||
url: string,
|
||||
label: string,
|
||||
title: string,
|
||||
@@ -31,47 +30,19 @@ export function createTGWindow(
|
||||
height: number,
|
||||
resizable: boolean,
|
||||
visible: boolean = true,
|
||||
): void {
|
||||
// 计算窗口位置
|
||||
const left = (window.screen.width - width) / 2;
|
||||
const top = (window.screen.height - height) / 2;
|
||||
const option: WindowOptions = {
|
||||
height,
|
||||
width,
|
||||
resizable,
|
||||
// url,
|
||||
): Promise<void> {
|
||||
const windowOpt: WindowOptions = {
|
||||
title,
|
||||
width,
|
||||
height,
|
||||
resizable,
|
||||
visible,
|
||||
x: left,
|
||||
y: top,
|
||||
};
|
||||
const isGet = TauriWindow.WebviewWindow.getByLabel(label);
|
||||
if (isGet === null) {
|
||||
core
|
||||
.invoke("create_window", { label, option })
|
||||
.then(() => {
|
||||
createTGWindow(url, label, title, width, height, resizable, visible);
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
console.error(err);
|
||||
});
|
||||
} else {
|
||||
isGet
|
||||
.close()
|
||||
.then(() => {
|
||||
core
|
||||
.invoke("create_window", { label, option })
|
||||
.then(() => {
|
||||
console.log(`[createTGWindow][${label}] ${title} created.`);
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
console.error(err);
|
||||
});
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
console.error(err);
|
||||
});
|
||||
const window = await TauriWindow.Window.getByLabel(label);
|
||||
if (window !== null) {
|
||||
await window.destroy();
|
||||
}
|
||||
await core.invoke("create_window", { label, url, option: windowOpt });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,12 +50,12 @@ export function createTGWindow(
|
||||
* @since Beta v0.4.2
|
||||
* @param {TGApp.Plugins.Mys.News.RenderCard | string | number | TGApp.Plugins.Mys.Forum.RenderCard} item 帖子内容或ID
|
||||
* @param {string} title 帖子标题
|
||||
* @returns {void}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export function createPost(
|
||||
export async function createPost(
|
||||
item: TGApp.Plugins.Mys.News.RenderCard | string | number | TGApp.Plugins.Mys.Forum.RenderCard,
|
||||
title?: string,
|
||||
): void {
|
||||
): Promise<void> {
|
||||
let postId: string, postTitle: string;
|
||||
if (typeof item === "string" || typeof item === "number") {
|
||||
postId = item.toString();
|
||||
@@ -94,7 +65,7 @@ export function createPost(
|
||||
postTitle = `Post_${postId} ${item.title}`;
|
||||
}
|
||||
const postPath = `/post_detail/${postId}`;
|
||||
createTGWindow(postPath, "Sub_window", postTitle, 960, 720, false, false);
|
||||
await createTGWindow(postPath, "Sub_window", postTitle, 960, 720, false, false);
|
||||
TGLogger.Info(`[createPost][${postId}] 打开帖子`).catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/**
|
||||
* @file utils/UIAF.ts
|
||||
* @description UIAF工具类
|
||||
* @since Beta v0.4.7
|
||||
* @since Beta v0.5.0
|
||||
*/
|
||||
|
||||
import { app, fs } from "@tauri-apps/api";
|
||||
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";
|
||||
|
||||
@@ -48,12 +49,12 @@ export async function getUiafHeader(): Promise<TGApp.Plugins.UIAF.Export> {
|
||||
|
||||
/**
|
||||
* @description 检测是否存在 UIAF 数据,采用 ajv 验证 schema
|
||||
* @since Beta v0.4.7
|
||||
* @since Beta v0.5.0
|
||||
* @param {string} path - UIAF 数据路径
|
||||
* @returns {Promise<boolean>} 是否存在 UIAF 数据
|
||||
*/
|
||||
export async function verifyUiafData(path: string): Promise<boolean> {
|
||||
const fileData: string = await fs.readTextFile(path);
|
||||
const fileData: string = await readTextFile(path);
|
||||
const ajv = new Ajv();
|
||||
const validate = ajv.compile(UiafSchema);
|
||||
try {
|
||||
@@ -111,11 +112,11 @@ export async function verifyUiafDataClipboard(): Promise<boolean> {
|
||||
|
||||
/**
|
||||
* @description 读取 UIAF 数据
|
||||
* @since Alpha v0.2.3
|
||||
* @since Beta v0.5.0
|
||||
* @param {string} userPath - UIAF 数据路径
|
||||
* @returns {Promise<TGApp.Plugins.UIAF.Data>} UIAF 数据
|
||||
*/
|
||||
export async function readUiafData(userPath: string): Promise<TGApp.Plugins.UIAF.Data> {
|
||||
const fileData = await fs.readTextFile(userPath);
|
||||
const fileData = await readTextFile(userPath);
|
||||
return <TGApp.Plugins.UIAF.Data>JSON.parse(fileData);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/**
|
||||
* @file utils/UIGF.ts
|
||||
* @description UIGF工具类
|
||||
* @since Beta v0.4.7
|
||||
* @since Beta v0.5.0
|
||||
*/
|
||||
|
||||
import { app, fs, path } from "@tauri-apps/api";
|
||||
import { app, path } from "@tauri-apps/api";
|
||||
import { mkdir, exists, readTextFile, writeTextFile } from "@tauri-apps/plugin-fs";
|
||||
import Ajv from "ajv";
|
||||
import { ErrorObject } from "ajv/lib/types/index.js";
|
||||
|
||||
@@ -72,12 +73,12 @@ export function convertDataToUigf(
|
||||
|
||||
/**
|
||||
* @description 检测是否存在 UIGF 数据,采用 ajv 验证 schema
|
||||
* @since Beta v0.4.7
|
||||
* @since Beta v0.5.0
|
||||
* @param {string} path - UIGF 数据路径
|
||||
* @returns {Promise<boolean>} 是否存在 UIGF 数据
|
||||
*/
|
||||
export async function verifyUigfData(path: string): Promise<boolean> {
|
||||
const fileData: string = await fs.readTextFile(path);
|
||||
const fileData: string = await readTextFile(path);
|
||||
const ajv = new Ajv();
|
||||
const validate = ajv.compile(UigfSchema);
|
||||
try {
|
||||
@@ -104,18 +105,18 @@ export async function verifyUigfData(path: string): Promise<boolean> {
|
||||
|
||||
/**
|
||||
* @description 读取 UIGF 数据
|
||||
* @since Alpha v0.2.3
|
||||
* @since Beta v0.5.0
|
||||
* @param {string} userPath - UIGF 数据路径
|
||||
* @returns {Promise<TGApp.Plugins.UIGF.FullData>} UIGF 数据
|
||||
*/
|
||||
export async function readUigfData(userPath: string): Promise<TGApp.Plugins.UIGF.FullData> {
|
||||
const fileData = await fs.readTextFile(userPath);
|
||||
const fileData = await readTextFile(userPath);
|
||||
return <TGApp.Plugins.UIGF.FullData>JSON.parse(fileData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 导出 UIGF 数据
|
||||
* @since Alpha v0.2.3
|
||||
* @since Beta v0.5.0
|
||||
* @param {string} uid - UID
|
||||
* @param {TGApp.Sqlite.GachaRecords.SingleTable[]} gachaList - 祈愿列表
|
||||
* @param {string} savePath - 保存路径
|
||||
@@ -131,12 +132,12 @@ export async function exportUigfData(
|
||||
list: convertDataToUigf(gachaList),
|
||||
};
|
||||
const filePath = savePath ?? `${await path.appLocalDataDir()}userData\\UIGF_${uid}.json`;
|
||||
await fs.writeTextFile(filePath, JSON.stringify(UigfData));
|
||||
await writeTextFile(filePath, JSON.stringify(UigfData));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 备份 UIGF 数据
|
||||
* @since Beta v0.4.1
|
||||
* @since Beta v0.5.0
|
||||
* @param {string} dirPath - 备份路径
|
||||
* @param {string} uid - UID
|
||||
* @param {TGApp.Sqlite.GachaRecords.SingleTable[]} gachaList - 祈愿列表
|
||||
@@ -147,6 +148,6 @@ export async function backupUigfData(
|
||||
uid: string,
|
||||
gachaList: TGApp.Sqlite.GachaRecords.SingleTable[],
|
||||
): Promise<void> {
|
||||
if (!(await fs.exists(dirPath))) await fs.createDir(dirPath, { recursive: true });
|
||||
if (!(await exists(dirPath))) await mkdir(dirPath, { recursive: true });
|
||||
await exportUigfData(uid, gachaList, `${dirPath}${path.sep}UIGF_${uid}.json`);
|
||||
}
|
||||
|
||||
@@ -116,12 +116,12 @@ export async function getCacheDir(): Promise<string[] | false> {
|
||||
const cacheDir = await path.appCacheDir();
|
||||
const osType = type().toLowerCase();
|
||||
if (osType === "windows") {
|
||||
const cache = `${cacheDir}EBWebview${path.sep}Default${path.sep}Cache`;
|
||||
const codeCache = `${cacheDir}EBWebview${path.sep}Default${path.sep}Code Cache`;
|
||||
const cache = `${cacheDir}${path.sep()}EBWebview${path.sep()}Default${path.sep()}Cache`;
|
||||
const codeCache = `${cacheDir}${path.sep()}EBWebview${path.sep()}Default${path.sep()}Code Cache`;
|
||||
return [cache, codeCache];
|
||||
}
|
||||
if (osType === "macos") {
|
||||
return [`${cacheDir}WebKit`];
|
||||
return [`${cacheDir}${path.sep()}WebKit`];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user