♻️ 姑且没登录的功能都给试了下

This commit is contained in:
目棃
2024-07-03 17:49:15 +08:00
parent 367307029b
commit 8a2c7d13c6
47 changed files with 1135 additions and 315 deletions

View File

@@ -2,7 +2,7 @@
<v-list class="config-list">
<v-list-subheader :inset="true" class="config-header" title="相关信息" />
<v-divider :inset="true" class="border-opacity-75" />
<v-list-item title="Tauri 版本" @click="toOuter('https://next--tauri.netlify.app/')">
<v-list-item title="Tauri 版本" @click="toOuter('https://v2.tauri.app/')">
<template #prepend>
<v-img class="config-icon" src="/platforms/tauri.webp" alt="Tauri" />
</template>
@@ -73,7 +73,8 @@
</v-list>
</template>
<script lang="ts" setup>
import { app, os } from "@tauri-apps/api";
import { app } from "@tauri-apps/api";
import { platform, version } from "@tauri-apps/plugin-os";
import { onMounted, ref } from "vue";
import TGSqlite from "../../plugins/Sqlite/index.js";
@@ -92,25 +93,25 @@ const dbInfo = ref<Array<TGApp.Sqlite.AppData.Item>>([]);
onMounted(async () => {
versionApp.value = await app.getVersion();
versionTauri.value = await app.getTauriVersion();
osPlatform.value = `${await os.platform()}`;
osPlatform.value = platform();
switch (osPlatform.value) {
case "linux":
iconPlatform.value = "mdi-linux";
break;
case "darwin":
case "macos":
iconPlatform.value = "mdi-apple";
break;
case "ios":
iconPlatform.value = "mdi-apple-ios";
break;
case "win32":
case "windows":
iconPlatform.value = "mdi-microsoft-windows";
break;
default:
iconPlatform.value = "mdi-desktop-classic";
break;
}
osVersion.value = await os.version();
osVersion.value = version();
try {
dbInfo.value = await TGSqlite.getAppData();
} catch (e) {

View File

@@ -193,7 +193,7 @@ async function toOuter(
});
return;
}
createTGWindow(url, "Sub_window", `Pool_${title}`, 1200, 800, true, true);
await createTGWindow(url, "Sub_window", `Pool_${title}`, 1200, 800, true, true);
}
function getCBox(info: TGApp.App.Character.WikiBriefInfo): TItemBoxData {

View File

@@ -8,7 +8,7 @@ import TGSqlite from "../../plugins/Sqlite/index.js";
import TItemBox, { type TItemBoxData } from "../main/t-itembox.vue";
interface TibWikiAbyssProps {
modelValue: string;
modelValue: string | number;
}
const props = defineProps<TibWikiAbyssProps>();

View File

@@ -80,6 +80,10 @@ function onCancel(): void {
text: "已取消登录",
color: "cancel",
});
if (cycleTimer !== null) {
clearInterval(cycleTimer);
cycleTimer = null;
}
}
async function freshQr(): Promise<void> {

View File

@@ -9,7 +9,8 @@
</div>
</template>
<script lang="ts" setup>
import { Component, StyleValue } from "vue";
import { StyleValue } from "vue";
import type { Component } from "vue";
import TpMention, { type TpMention as TpMentionType } from "./tp-mention.vue";
import TpText, { type TpText as TpTextType } from "./tp-text.vue";

View File

@@ -93,8 +93,8 @@
</template>
</v-expansion-panel>
</v-expansion-panels>
<ToNamecard v-if="hasNc" v-model="showNc" :data="nameCard" />
</div>
<ToNamecard v-if="hasNc" v-model="showNc" :data="nameCard" />
</template>
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
@@ -181,7 +181,7 @@ async function toWiki(): Promise<void> {
return;
}
const url = Mys.Api.Obc.replace("{contentId}", props.item.contentId.toString());
createTGWindow(
await createTGWindow(
url,
"Sub_window",
`Content_${props.item.contentId} ${props.item.name}`,

View File

@@ -41,7 +41,8 @@
</div>
</template>
<script lang="ts" setup>
import { dialog, path } from "@tauri-apps/api";
import { path } from "@tauri-apps/api";
import { open, save } from "@tauri-apps/plugin-dialog";
import { storeToRefs } from "pinia";
import { onMounted, ref, watch } from "vue";
@@ -270,7 +271,7 @@ async function handleImportBtn(savePath?: string): Promise<void> {
await TGLogger.Info("[UserGacha][handleImportBtn] 导入祈愿数据");
let selectedFile;
if (savePath) {
selectedFile = await dialog.open({
selectedFile = await open({
multiple: false,
title: "选择要导入的祈愿数据文件",
filters: [
@@ -283,7 +284,7 @@ async function handleImportBtn(savePath?: string): Promise<void> {
directory: false,
});
} else {
selectedFile = await dialog.open({
selectedFile = await open({
multiple: false,
title: "选择要导入的祈愿数据文件",
filters: [
@@ -303,9 +304,9 @@ async function handleImportBtn(savePath?: string): Promise<void> {
});
return;
}
const check = await verifyUigfData(<string>selectedFile);
const check = await verifyUigfData(selectedFile.path);
if (!check) return;
const remoteData = await readUigfData(<string>selectedFile);
const remoteData = await readUigfData(selectedFile.path);
const res = await showConfirm({
title: "是否导入祈愿数据?",
text: `UID${remoteData.info.uid}${remoteData.list.length} 条数据`,
@@ -363,7 +364,7 @@ async function handleExportBtn(): Promise<void> {
});
return;
}
const file = await dialog.save({
const file = await save({
title: "选择导出祈愿数据的文件路径",
filters: [
{

View File

@@ -106,7 +106,9 @@
</template>
<script lang="ts" setup>
import { dialog, fs, path } from "@tauri-apps/api";
import { path } from "@tauri-apps/api";
import { open, save } from "@tauri-apps/plugin-dialog";
import { writeTextFile } from "@tauri-apps/plugin-fs";
import { computed, nextTick, onMounted, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
@@ -338,7 +340,7 @@ async function searchCard(): Promise<void> {
// 导入 UIAF 数据,进行数据合并、刷新
async function importJson(): Promise<void> {
await TGLogger.Info("[Achievements][importJson] 导入 UIAF 数据");
const selectedFile = await dialog.open({
const selectedFile = await open({
title: "选择 UIAF 数据文件",
multiple: false,
filters: [
@@ -358,9 +360,9 @@ async function importJson(): Promise<void> {
await TGLogger.Info("[Achievements][importJson] 已取消文件选择");
return;
}
const check = await verifyUiafData(<string>selectedFile);
const check = await verifyUiafData(selectedFile.path);
if (!check) return;
const remoteRaw = await readUiafData(<string>selectedFile);
const remoteRaw = await readUiafData(selectedFile.path);
await TGLogger.Info("[Achievements][importJson] 读取 UIAF 数据成功");
await TGLogger.Info(`[Achievements][importJson] 导入来源:${remoteRaw.info.export_app}`);
await TGLogger.Info(`[Achievements][importJson] 导入版本:${remoteRaw.info.export_app_version}`);
@@ -394,7 +396,7 @@ async function exportJson(): Promise<void> {
list: await TSUserAchi.getUIAF(),
};
const fileName = `UIAF_${UiafData.info.export_app}_${UiafData.info.export_app_version}_${UiafData.info.export_timestamp}`;
const isSave = await dialog.save({
const isSave = await save({
title: "导出 UIAF 数据",
filters: [
{
@@ -412,7 +414,7 @@ async function exportJson(): Promise<void> {
await TGLogger.Info("[Achievements][exportJson] 已取消导出");
return;
}
await fs.writeTextFile(isSave, JSON.stringify(UiafData));
await writeTextFile(isSave, JSON.stringify(UiafData));
showSnackbar({ text: "导出成功" });
await TGLogger.Info("[Achievements][exportJson] 导出成功");
await TGLogger.Info(`[Achievements][exportJson] 导出路径:${isSave}`);

View File

@@ -87,7 +87,10 @@
</template>
<script lang="ts" setup>
import { dialog, fs, invoke, process as TauriProcess } from "@tauri-apps/api";
import { core } from "@tauri-apps/api";
import { open } from "@tauri-apps/plugin-dialog";
import { remove } from "@tauri-apps/plugin-fs";
import { relaunch } from "@tauri-apps/plugin-process";
import { onMounted, ref } from "vue";
import TcAppBadge from "../../components/config/tc-appBadge.vue";
@@ -141,7 +144,7 @@ async function confirmBackup(): Promise<void> {
}
let saveDir = appStore.userDir;
if (res === false) {
const dir = await dialog.open({
const dir: string | null = await open({
directory: true,
defaultPath: saveDir,
multiple: false,
@@ -154,13 +157,6 @@ async function confirmBackup(): Promise<void> {
return;
}
await TGLogger.Info(`[Config][confirmBackup] 选择备份路径 ${dir.toString()}`);
if (typeof dir !== "string") {
showSnackbar({
color: "error",
text: "路径错误!",
});
return;
}
saveDir = dir;
} else {
await TGLogger.Info(`[Config][confirmBackup] 备份到默认路径 ${saveDir}`);
@@ -188,7 +184,7 @@ async function confirmRestore(): Promise<void> {
}
let saveDir = appStore.userDir;
if (resConfirm === false) {
const dir = await dialog.open({
const dir: string | null = await open({
directory: true,
defaultPath: saveDir,
multiple: false,
@@ -201,13 +197,6 @@ async function confirmRestore(): Promise<void> {
return;
}
await TGLogger.Info(`[Config][confirmRestore] 选择恢复路径 ${dir.toString()}`);
if (typeof dir !== "string") {
showSnackbar({
color: "error",
text: "路径错误!",
});
return;
}
saveDir = dir;
} else {
await TGLogger.Info(`[Config][confirmRestore] 恢复到默认路径 ${saveDir}`);
@@ -332,7 +321,7 @@ async function confirmDelCache(): Promise<void> {
loading.value = true;
const timeStart = Date.now();
for (const dir of CacheDir) {
const size: number = await invoke("get_dir_size", { path: dir });
const size: number = await core.invoke("get_dir_size", { path: dir });
cacheBSize += size;
}
const cacheSize = bytesToSize(cacheBSize);
@@ -354,7 +343,7 @@ async function confirmDelCache(): Promise<void> {
loadingTitle.value = "正在清除缓存...";
loading.value = true;
for (const dir of CacheDir) {
await fs.removeDir(dir, { recursive: true });
await remove(dir, { recursive: true });
}
await TGLogger.Info("[Config][confirmDelCache] 缓存清除完成");
loading.value = false;
@@ -362,7 +351,7 @@ async function confirmDelCache(): Promise<void> {
text: "缓存已清除!即将退出应用!",
});
setTimeout(async () => {
await TauriProcess.exit();
await relaunch();
}, 1000);
}

View File

@@ -1,22 +1,20 @@
/**
* @file plugins/Bili/request/getNav.ts
* @description Bili 插件导航请求文件
* @since Beta v0.4.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
/**
* @description Bili 插件导航请求
* @since Beta v0.4.0
* @since Beta v0.5.0
* @return {Promise<TGApp.Plugins.Bili.Nav.NavData>} Bili 插件导航请求返回
*/
async function getNav(): Promise<TGApp.Plugins.Bili.Nav.NavData> {
const url = "https://api.bilibili.com/x/web-interface/nav";
return await http.fetch(url).then((res: Response<TGApp.Plugins.Bili.Nav.NavResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Bili.Nav.NavResponse>(url, { method: "GET" });
return resp.data;
}
export default getNav;

View File

@@ -1,17 +1,15 @@
/**
* @file plugins/Bili/request/getVideoUrl.ts
* @description Bili 插件视频请求文件
* @since Beta v0.4.1
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import getWrid from "../utils/getWrid.js";
/**
* @description 获取视频播放地址
* @since Beta v0.4.1
* @since Beta v0.5.0
* @see https://socialsisteryi.github.io/bilibili-API-collect/docs/video/videostream_url.html#dash%E6%A0%BC%E5%BC%8F
* @param {string} bvid 视频BV号
* @param {number} cid 视频分P号
@@ -31,17 +29,12 @@ async function getVideoUrl(cid: number, bvid: string): Promise<TGApp.Plugins.Bil
wts: wridRes[0],
wrid: wridRes[1],
};
return await http
.fetch(url, {
method: "GET",
query: params,
headers: {
referer: "https://www.bilibili.com/",
},
})
.then((res: Response<TGApp.Plugins.Bili.Video.UrlResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Bili.Video.UrlResponse>(url, {
method: "GET",
query: params,
referrer: "https://www.bilibili.com/",
});
return resp.data;
}
export default getVideoUrl;

View File

@@ -1,15 +1,14 @@
/**
* @file plugins/Bili/request/getVideoView.ts
* @description Bili插件-获取视频基本信息
* @since Beta v0.4.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import type { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
/**
* @description 获取视频基本信息
* @since Beta v0.4.0
* @since Beta v0.5.0
* @param {string} [aid] 视频AV号
* @param {string} [bvid] 视频BV号
* @returns {Promise<TGApp.Plugins.Bili.Video.ViewData>} 视频基本信息
@@ -26,11 +25,10 @@ async function getVideoView(
} else {
throw new Error("参数错误");
}
return await http
.fetch(url, { method: "GET" })
.then((res: Response<TGApp.Plugins.Bili.Video.ViewResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Bili.Video.ViewResponse>(url, {
method: "GET",
});
return resp.data;
}
export default getVideoView;

View File

@@ -1,26 +1,23 @@
/**
* @file plugins Hutao request getAvatarCollect.ts
* @file plugins/Hutao/request/getAvatarCollect.ts
* @description 获取角色搭配数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import HutaoApi from "../api/index.js";
/**
* @description 获取角色搭配数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarCollocation[]>}
*/
async function getAvatarCollect(): Promise<TGApp.Plugins.Hutao.Abyss.AvatarCollocation[]> {
const url = HutaoApi.Abyss.avatar.collect;
return await http
.fetch(url, { method: "GET" })
.then((res: Response<TGApp.Plugins.Hutao.Abyss.AvatarCollocationResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarCollocationResponse>(url, {
method: "GET",
});
return resp.data;
}
export default getAvatarCollect;

View File

@@ -1,26 +1,21 @@
/**
* @file plugins Hutao request getAvatarHoldRate.ts
* @file plugins/Hutao/request/getAvatarHoldRate.ts
* @description Hutao API 获取角色持有率数据请求方法
* @since Alpha v0.2.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import HutaoApi from "../api/index.js";
/**
* @description 获取角色持有率数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
* @returns {Promise<TGApp.Plugins.Hutao.Abyss.AvatarHold[]>}
*/
async function getAvatarHoldRate(): Promise<TGApp.Plugins.Hutao.Abyss.AvatarHold[]> {
const url = HutaoApi.Abyss.avatar.holdRate;
return await http
.fetch(url, { method: "GET" })
.then((res: Response<TGApp.Plugins.Hutao.Abyss.AvatarHoldResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarHoldResponse>(url, { method: "GET" });
return resp.data;
}
export default getAvatarHoldRate;

View File

@@ -1,26 +1,21 @@
/**
* @file plugins Hutao request getAvatarUpRate.ts
* @file plugins/Hutao/request/getAvatarUpRate.ts
* @description 获取角色上场率数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import HutaoApi from "../api/index.js";
/**
* @description 获取角色上场率数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarUp[]>}
*/
async function getAvatarUpRate(): Promise<TGApp.Plugins.Hutao.Abyss.AvatarUp[]> {
const url = HutaoApi.Abyss.avatar.upRate;
return await http
.fetch(url, { method: "GET" })
.then((res: Response<TGApp.Plugins.Hutao.Abyss.AvatarUpResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarUpResponse>(url, { method: "GET" });
return resp.data;
}
export default getAvatarUpRate;

View File

@@ -1,26 +1,21 @@
/**
* @file plugins Hutao request getAvatarUseRate.ts
* @file plugins/Hutao/request/getAvatarUseRate.ts
* @description 获取角色使用率
* @since Alpha v0.2.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import HutaoApi from "../api/index.js";
/**
* @description 获取角色使用率
* @since Alpha v0.2.0
* @since Beta v0.5.0
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarUse[]>}
*/
async function getAvatarUseRate(): Promise<TGApp.Plugins.Hutao.Abyss.AvatarUse[]> {
const url = HutaoApi.Abyss.avatar.useRate;
return await http
.fetch(url, { method: "GET" })
.then((res: Response<TGApp.Plugins.Hutao.Abyss.AvatarUseResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarUseResponse>(url, { method: "GET" });
return resp.data;
}
export default getAvatarUseRate;

View File

@@ -1,26 +1,21 @@
/**
* @file plugins Hutao request getOverview.ts
* @file plugins/Hutao/request/getOverview.ts
* @description 获取深渊概览数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import HutaoApi from "../api/index.js";
/**
* @description 获取深渊概览数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
* @return {Promise<TGApp.Plugins.Hutao.Abyss.OverviewData>}
*/
async function getOverview(): Promise<TGApp.Plugins.Hutao.Abyss.OverviewData> {
const url = HutaoApi.Abyss.overview;
return await http
.fetch(url, { method: "GET" })
.then((res: Response<TGApp.Plugins.Hutao.Abyss.OverviewResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.OverviewResponse>(url, { method: "GET" });
return resp.data;
}
export default getOverview;

View File

@@ -1,26 +1,23 @@
/**
* @file plugins Hutao request getTeamCollect.ts
* @file plugins/Hutao/request/getTeamCollect.ts
* @description 获取队伍搭配数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import type { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import HutaoApi from "../api/index.js";
/**
* @description 获取队伍搭配数据
* @since Alpha v0.2.0
* @since Beta v0.5.0
* @return {Promise<TGApp.Plugins.Hutao.Abyss.TeamCombination[]>}
*/
async function getTeamCollect(): Promise<TGApp.Plugins.Hutao.Abyss.TeamCombination[]> {
const url = HutaoApi.Abyss.team;
return await http
.fetch(url, { method: "GET" })
.then((res: Response<TGApp.Plugins.Hutao.Abyss.TeamCombinationResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.TeamCombinationResponse>(url, {
method: "GET",
});
return resp.data;
}
export default getTeamCollect;

View File

@@ -1,26 +1,23 @@
/**
* @file plugins Hutao request getWeaponCollect.ts
* @file plugins/Hutao/request/getWeaponCollect.ts
* @description 获取武器搭配
* @since Alpha v0.2.0
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import type { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import HutaoApi from "../api/index.js";
/**
* @description 获取武器搭配
* @since Alpha v0.2.0
* @since Beta v0.5.0
* @return {Promise<TGApp.Plugins.Hutao.Abyss.WeaponCollocation[]>}
*/
async function getWeaponCollect(): Promise<TGApp.Plugins.Hutao.Abyss.WeaponCollocation[]> {
const url = HutaoApi.Abyss.weapon;
return await http
.fetch(url, { method: "GET" })
.then((res: Response<TGApp.Plugins.Hutao.Abyss.WeaponCollocationResponse>) => {
return res.data.data;
});
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.WeaponCollocationResponse>(url, {
method: "GET",
});
return resp.data;
}
export default getWeaponCollect;

View File

@@ -1,17 +1,15 @@
/**
* @file plugins Hutao request uploadData.ts
* @file plugins/Hutao/request/uploadData.ts
* @description Hutao 数据上传请求函数集合
* @since Alpha v0.2.1
* @since Beta v0.5.0
*/
import { http } from "@tauri-apps/api";
import type { Response } from "@tauri-apps/api/http";
import TGHttp from "../../../utils/TGHttp.js";
import HutaoApi from "../api/index.js";
/**
* @description 上传用户数据
* @since Alpha v0.2.1
* @since Beta v0.5.0
* @param {TGApp.Plugins.Hutao.Abyss.RecordUpload} data 用户数据
* @returns {Promise<TGApp.Plugins.Hutao.Abyss.UploadResponse>} 上传结果
*/
@@ -19,9 +17,10 @@ async function uploadData(
data: TGApp.Plugins.Hutao.Abyss.RecordUpload,
): Promise<TGApp.Plugins.Hutao.Abyss.UploadResponse> {
const url = HutaoApi.Abyss.upload;
return await http
.fetch(url, { method: "POST", body: http.Body.json(data) })
.then((res: Response<TGApp.Plugins.Hutao.Abyss.UploadResponse>) => res.data);
return await TGHttp<TGApp.Plugins.Hutao.Abyss.UploadResponse>(url, {
method: "POST",
body: JSON.stringify(data),
});
}
export default uploadData;

View File

@@ -18,7 +18,7 @@ async function getPostData(postId: number): Promise<TGApp.Plugins.Mys.Post.FullD
const params = { post_id: postId.toString() };
const resp = await TGHttp<TGApp.Plugins.Mys.Post.Response>(url, {
method: "GET",
headers: { "Content-Type": "application/json", Referer: MysApi.PostReferer },
headers: { referer: MysApi.PostReferer },
query: params,
});
return resp.data.post;

View File

@@ -1,7 +1,7 @@
/**
* @file plugins/Mys/utils/getGachaCard.ts
* @description Mys 插件抽卡工具
* @since Beta v0.4.4
* @since Beta v0.5.0
*/
import { AppCharacterData } from "../../../data/index.js";
@@ -9,7 +9,7 @@ import getPostData from "../request/getPostData.js";
/**
* @description 根据单个卡池信息转为渲染用的卡池信息
* @since Beta v0.4.4
* @since Beta v0.5.0
* @param {TGApp.Plugins.Mys.Gacha.Data} data 卡池信息
* @param {string} poolCover 卡池封面
* @returns {Promise<TGApp.Plugins.Mys.Gacha.RenderCard>}

View File

@@ -1,11 +1,11 @@
/**
* @file plugins/Sqlite/index.ts
* @description Sqlite 数据库操作类
* @since Beta v0.4.7
* @since Beta v0.5.0
*/
import { app } from "@tauri-apps/api";
import Database from "tauri-plugin-sql-api";
import Database from "@tauri-apps/plugin-sql";
import initDataSql from "./sql/initData.js";
import {

View File

@@ -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}`);

View File

@@ -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 日志工具

View File

@@ -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);

View File

@@ -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();
}
}

View File

@@ -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);
});

View File

@@ -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);
}

View File

@@ -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`);
}

View File

@@ -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;
}

View File

@@ -22,8 +22,7 @@
</div>
</template>
<script lang="ts" setup>
import { app } from "@tauri-apps/api";
import { appWindow } from "@tauri-apps/api/window";
import { app, webviewWindow } from "@tauri-apps/api";
import { ref, onMounted, watch, onUnmounted } from "vue";
import { useRoute } from "vue-router";
@@ -60,7 +59,7 @@ const annoHtml = ref<string>();
const annoBanner = ref<string>();
onMounted(async () => {
await appWindow.show();
await webviewWindow.getCurrent().show();
appVersion.value = await app.getVersion();
// 检查数据
if (!annoId || !region) {
@@ -77,7 +76,7 @@ onMounted(async () => {
annoHtml.value = await TGUtils.Anno.parseContent(annoData.value.content);
if (annoData.value.banner !== "") annoBanner.value = await saveImgLocal(annoData.value.banner);
annoTitle.value = `Anno_${annoId}`;
await appWindow.setTitle(`Anno_${annoId} ${annoData.value.title}`);
await webviewWindow.getCurrent().setTitle(`Anno_${annoId} ${annoData.value.title}`);
annoRef.value = <HTMLElement>document.querySelector(".anno-body");
} catch (error) {
if (error instanceof Error)
@@ -85,7 +84,7 @@ onMounted(async () => {
else console.error(error);
loadingEmpty.value = true;
loadingTitle.value = "公告不存在或解析失败";
await appWindow.setTitle(`Anno_${annoId} Parsing Error`);
await webviewWindow.getCurrent().setTitle(`Anno_${annoId} Parsing Error`);
return;
}
// 打开 json

View File

@@ -82,7 +82,7 @@
</template>
<script lang="ts" setup>
import { app } from "@tauri-apps/api";
import { appWindow } from "@tauri-apps/api/window";
import { webviewWindow } from "@tauri-apps/api";
import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
@@ -123,13 +123,13 @@ const shareTimeTimer = ref<any>();
const showCollection = ref<boolean>(false);
onMounted(async () => {
await appWindow.show();
await webviewWindow.getCurrent().show();
appVersion.value = await app.getVersion();
// 检查数据
if (!postId) {
loadingEmpty.value = true;
loadingTitle.value = "未找到数据";
await appWindow.setTitle("未找到数据");
await webviewWindow.getCurrent().setTitle("未找到数据");
await TGLogger.Error("[t-post][onMounted] PostID 不存在");
return;
}
@@ -140,7 +140,7 @@ onMounted(async () => {
loadingTitle.value = "正在渲染数据...";
renderPost.value = getRenderPost(postData.value);
shareTitle.value = `Post_${postId}`;
await appWindow.setTitle(`Post_${postId} ${postData.value.post.subject}`);
await webviewWindow.getCurrent().setTitle(`Post_${postId} ${postData.value.post.subject}`);
} catch (error) {
if (error instanceof Error) {
await TGLogger.Error(`[t-post][${postId}] ${error.name}: ${error.message}`);
@@ -152,7 +152,7 @@ onMounted(async () => {
loadingSub.value = "请检查帖子是否存在或者是否为合法的帖子";
}
loadingEmpty.value = true;
await appWindow.setTitle(`Post_${postId} Parsing Error`);
await webviewWindow.getCurrent().setTitle(`Post_${postId} Parsing Error`);
return;
}
await TGLogger.Info(`[t-post][${postId}][onMounted] ${postData.value.post.subject}`);