diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 87f88d34..dbd853cd 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -26,6 +26,7 @@ "https://api-static.mihoyo.com/*", "https://bbs-api.mihoyo.com/*", "https://bbs-api.miyoushe.com/*", + "https://bbs-api-static.miyoushe.com/*", "https://bbs.mihoyo.com/*", "https://hk4e-api.mihoyo.com/*", "https://hk4e-sdk.mihoyo.com/*", diff --git a/src/App.vue b/src/App.vue index 894acbcf..5496131a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -19,6 +19,9 @@ import TBackTop from "./components/app/t-backTop.vue"; import { app, event, fs, window } from "@tauri-apps/api"; // store import { useAppStore } from "./store/modules/app"; +// utils +import { getEmojis } from "./plugins/Mys/request/getEmojis"; +import showSnackbar from "./components/func/snackbar"; const appStore = useAppStore(); const isMain = ref(false); @@ -31,6 +34,7 @@ onBeforeMount(async () => { if (isMain.value) { const title = "Tauri.Genshin v" + (await app.getVersion()) + " Beta"; await win.setTitle(title); + await emojiLoad(); await checkLoad(); } }); @@ -52,6 +56,20 @@ async function listenOnTheme(): Promise { }); } +async function emojiLoad(): Promise { + const res = await getEmojis(); + if ("retcode" in res) { + console.error(res); + showSnackbar({ + text: "表情包加载失败!", + color: "error", + timeout: 3000, + }); + } else { + localStorage.setItem("emojis", JSON.stringify(res)); + } +} + async function checkLoad(): Promise { if (appStore.loading) { console.info("数据已加载!"); diff --git a/src/assets/css/post-parser.css b/src/assets/css/post-parser.css index f68b930f..b97544e2 100644 --- a/src/assets/css/post-parser.css +++ b/src/assets/css/post-parser.css @@ -28,7 +28,7 @@ } :deep(.mys-post-div) { - margin: 20px auto; + margin: 10px auto; } :deep(.mys-post-span) { @@ -52,7 +52,7 @@ } :deep(.mys-post-divider) { - margin: 20px auto; + margin: 10px auto; } :deep(.mys-post-divider) img { @@ -89,6 +89,7 @@ border: 1px solid var(--common-shadow-1); border-radius: 10px; background: var(--box-bg-1); + gap: 10px; } :deep(.mys-post-unknown) { @@ -113,16 +114,24 @@ max-width: 400px; height: 180px; border-radius: 10px; + transition: all 0.5s; +} + +:deep(.mys-post-link-card-cover):hover img { + transform: scale(1.05); + transition: all 0.5s; } :deep(.mys-post-link-card-content) { + display: flex; width: 100%; height: 180px; - padding-left: 20px; + flex-direction: column; + align-items: center; + justify-content: space-between; } :deep(.mys-post-link-card-title) { - height: 150px; color: var(--common-text-title); font-family: var(--font-title); font-size: 20px; @@ -137,8 +146,14 @@ :deep(.mys-post-link-card-btn) { display: inline-block; - margin-right: 20px; + margin-left: auto; color: #00c3ff; - float: right; + text-align: right; text-decoration: none; } + +:deep(.mys-post-emoji) { + width: 45px; + height: 45px; + margin: 0 5px; +} diff --git a/src/plugins/Mys/request/getEmojis.ts b/src/plugins/Mys/request/getEmojis.ts new file mode 100644 index 00000000..42eca606 --- /dev/null +++ b/src/plugins/Mys/request/getEmojis.ts @@ -0,0 +1,30 @@ +/** + * @file plugins Mys request getEmojis.ts + * @description Mys 表情包请求函数集合 + * @author BTMuli + * @since Beta v0.3.0 + */ + +// tauri +import { http } from "@tauri-apps/api"; + +/** + * @description 获取表情包列表 + * @since Beta v0.3.0 + * @return {Promise|TGApp.BBS.Response.Base>} + */ +export async function getEmojis(): Promise | TGApp.BBS.Response.Base> { + const url = "https://bbs-api-static.miyoushe.com/misc/api/emoticon_set"; + return await http.fetch(url).then((res) => { + if (res.data.retcode === 0) { + const emojis: Record = {}; + res.data.data.list.forEach((series) => { + series.list.forEach((emoji) => { + emojis[emoji.name] = emoji.icon; + }); + }); + return emojis; + } + return res.data; + }); +} diff --git a/src/plugins/Mys/types/Emoji.d.ts b/src/plugins/Mys/types/Emoji.d.ts new file mode 100644 index 00000000..fc92e4fa --- /dev/null +++ b/src/plugins/Mys/types/Emoji.d.ts @@ -0,0 +1,84 @@ +/** + * @file plugins Mys types Emoji.d.ts + * @description Mys 表情包类型声明文件 + * @author BTMuli + * @since Beta v0.3.0 + */ + +/** + * @description Mys 表情包类型 + * @since Beta v0.3.0 + * @namespace Emoji + * return Emoji + */ +declare namespace TGApp.Plugins.Mys.Emoji { + /** + * @description 获取表情包列表返回 + * @since Beta v0.3.0 + * @interface Response + * @extends TGApp.Plugins.Mys.Base.Response + * @property {Series[]} data.list 表情包列表 + * @property {unknown} data.recently_emoticon 最近使用的表情包 + * @return Response + */ + export interface Response extends TGApp.Plugins.Mys.Base.Response { + data: { + list: Series[]; + recently_emoticon: unknown; + }; + } + + /** + * @description 表情包系列 + * @since Beta v0.3.0 + * @interface Series + * @property {number} id 表情包系列 ID + * @property {string} name 表情包系列名称 + * @property {string} icon 表情包系列图标 + * @property {number} sort_order 表情包系列排序 + * @property {number} num 表情包系列数量 + * @property {string} status 表情包系列状态 + * @property {EmojiItem[]} list 表情包系列列表 + * @property {number} updated_at 表情包系列更新时间 + * @property {boolean} is_available 表情包系列是否可用 + * @return Series + */ + export interface Series { + id: number; + name: string; + icon: string; + sort_order: number; + num: number; + status: string; + list: EmojiItem[]; + updated_at: number; + is_available: boolean; + } + + /** + * @description 表情包 + * @since Beta v0.3.0 + * @interface EmojiItem + * @property {number} id 表情包 ID + * @property {string} name 表情包名称 + * @property {string} icon 表情包图标 + * @property {number} sort_order 表情包排序 + * @property {string} static_icon 表情包静态图标 + * @property {number} updated_at 表情包更新时间 + * @property {boolean} is_available 表情包是否可用 + * @property {string} status 表情包状态 + * @property {unknown[]} keywords 表情包关键词 + * @return EmojiItem + */ + export interface EmojiItem { + id: number; + name: string; + icon: string; + sort_order: number; + static_icon: string; + updated_at: number; + is_available: boolean; + status: string; + keywords: unknown[]; + } +} diff --git a/src/plugins/Mys/utils/parsePost.ts b/src/plugins/Mys/utils/parsePost.ts index 653cf424..1678ad4c 100644 --- a/src/plugins/Mys/utils/parsePost.ts +++ b/src/plugins/Mys/utils/parsePost.ts @@ -185,7 +185,7 @@ function parseText(data: TGApp.Plugins.Mys.Post.StructuredContent): HTMLSpanElem if (data.attributes.color) { let colorGet = data.attributes.color; // 如果 colorGet 在 darkColorList 中,就设置为对应的颜色 - if (isColorSimilar("#000000", colorGet)) { + if (isColorSimilar("#1E1E1E", colorGet)) { colorGet = "var(--app-page-content)"; } text.style.color = colorGet; @@ -194,6 +194,10 @@ function parseText(data: TGApp.Plugins.Mys.Post.StructuredContent): HTMLSpanElem return LinkTextParser(data); } } + if (data.insert.startsWith("_")) { + console.log(data.insert); + return emojiParser(data); + } // 添加 class text.classList.add("mys-post-span"); // 设置 span 内容 @@ -542,4 +546,33 @@ function parseMention(data: TGApp.Plugins.Mys.Post.StructuredContent): HTMLAncho return link; } +/** + * @description 解析 Emoji + * @since Beta v0.3.0 + * @param {TGApp.Plugins.Mys.Post.StructuredContent} data Mys数据 + * @returns {HTMLSpanElement} 解析后的 Emoji + */ +function emojiParser(data: TGApp.Plugins.Mys.Post.StructuredContent): HTMLImageElement { + // 检查数据 + if (typeof data.insert !== "string") { + throw new Error("data.insert is not a string"); + } + const emojis = localStorage.getItem("emojis"); + if (!emojis) { + throw new Error("emojis is not defined"); + } + const emojiList: Record = JSON.parse(emojis); + const emojiName = data.insert.slice(2, -1); + const emoji = emojiList[emojiName]; + if (!emoji) { + throw new Error("emoji is not defined"); + } + // 创建图片 + const img = document.createElement("img"); + img.classList.add("mys-post-emoji"); + img.src = emoji; + // 获取图片地址 + return img; +} + export default parsePost; diff --git a/src/views/t-post.vue b/src/views/t-post.vue index c0732fdb..5e2c9280 100644 --- a/src/views/t-post.vue +++ b/src/views/t-post.vue @@ -78,6 +78,7 @@ onMounted(async () => { console.error(error); loadingEmpty.value = true; loadingTitle.value = "帖子不存在或解析失败"; + loadingSub.value = error instanceof Error ? error.message : error; await appWindow.setTitle(`【帖子】${postId}-解析失败`); return; }