mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-14 09:38:13 +08:00
✨ 添加 emoji 解析
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
"https://api-static.mihoyo.com/*",
|
"https://api-static.mihoyo.com/*",
|
||||||
"https://bbs-api.mihoyo.com/*",
|
"https://bbs-api.mihoyo.com/*",
|
||||||
"https://bbs-api.miyoushe.com/*",
|
"https://bbs-api.miyoushe.com/*",
|
||||||
|
"https://bbs-api-static.miyoushe.com/*",
|
||||||
"https://bbs.mihoyo.com/*",
|
"https://bbs.mihoyo.com/*",
|
||||||
"https://hk4e-api.mihoyo.com/*",
|
"https://hk4e-api.mihoyo.com/*",
|
||||||
"https://hk4e-sdk.mihoyo.com/*",
|
"https://hk4e-sdk.mihoyo.com/*",
|
||||||
|
|||||||
18
src/App.vue
18
src/App.vue
@@ -19,6 +19,9 @@ import TBackTop from "./components/app/t-backTop.vue";
|
|||||||
import { app, event, fs, window } from "@tauri-apps/api";
|
import { app, event, fs, window } from "@tauri-apps/api";
|
||||||
// store
|
// store
|
||||||
import { useAppStore } from "./store/modules/app";
|
import { useAppStore } from "./store/modules/app";
|
||||||
|
// utils
|
||||||
|
import { getEmojis } from "./plugins/Mys/request/getEmojis";
|
||||||
|
import showSnackbar from "./components/func/snackbar";
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const isMain = ref<boolean>(false);
|
const isMain = ref<boolean>(false);
|
||||||
@@ -31,6 +34,7 @@ onBeforeMount(async () => {
|
|||||||
if (isMain.value) {
|
if (isMain.value) {
|
||||||
const title = "Tauri.Genshin v" + (await app.getVersion()) + " Beta";
|
const title = "Tauri.Genshin v" + (await app.getVersion()) + " Beta";
|
||||||
await win.setTitle(title);
|
await win.setTitle(title);
|
||||||
|
await emojiLoad();
|
||||||
await checkLoad();
|
await checkLoad();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -52,6 +56,20 @@ async function listenOnTheme(): Promise<void> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function emojiLoad(): Promise<void> {
|
||||||
|
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<void> {
|
async function checkLoad(): Promise<void> {
|
||||||
if (appStore.loading) {
|
if (appStore.loading) {
|
||||||
console.info("数据已加载!");
|
console.info("数据已加载!");
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-div) {
|
:deep(.mys-post-div) {
|
||||||
margin: 20px auto;
|
margin: 10px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-span) {
|
:deep(.mys-post-span) {
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-divider) {
|
:deep(.mys-post-divider) {
|
||||||
margin: 20px auto;
|
margin: 10px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-divider) img {
|
:deep(.mys-post-divider) img {
|
||||||
@@ -89,6 +89,7 @@
|
|||||||
border: 1px solid var(--common-shadow-1);
|
border: 1px solid var(--common-shadow-1);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: var(--box-bg-1);
|
background: var(--box-bg-1);
|
||||||
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-unknown) {
|
:deep(.mys-post-unknown) {
|
||||||
@@ -113,16 +114,24 @@
|
|||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
border-radius: 10px;
|
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) {
|
:deep(.mys-post-link-card-content) {
|
||||||
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
padding-left: 20px;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.mys-post-link-card-title) {
|
:deep(.mys-post-link-card-title) {
|
||||||
height: 150px;
|
|
||||||
color: var(--common-text-title);
|
color: var(--common-text-title);
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@@ -137,8 +146,14 @@
|
|||||||
|
|
||||||
:deep(.mys-post-link-card-btn) {
|
:deep(.mys-post-link-card-btn) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 20px;
|
margin-left: auto;
|
||||||
color: #00c3ff;
|
color: #00c3ff;
|
||||||
float: right;
|
text-align: right;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.mys-post-emoji) {
|
||||||
|
width: 45px;
|
||||||
|
height: 45px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|||||||
30
src/plugins/Mys/request/getEmojis.ts
Normal file
30
src/plugins/Mys/request/getEmojis.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins Mys request getEmojis.ts
|
||||||
|
* @description Mys 表情包请求函数集合
|
||||||
|
* @author BTMuli <bt-muli@outlook.com>
|
||||||
|
* @since Beta v0.3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// tauri
|
||||||
|
import { http } from "@tauri-apps/api";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取表情包列表
|
||||||
|
* @since Beta v0.3.0
|
||||||
|
* @return {Promise<Record<string,string>|TGApp.BBS.Response.Base>}
|
||||||
|
*/
|
||||||
|
export async function getEmojis(): Promise<Record<string, string> | TGApp.BBS.Response.Base> {
|
||||||
|
const url = "https://bbs-api-static.miyoushe.com/misc/api/emoticon_set";
|
||||||
|
return await http.fetch<TGApp.Plugins.Mys.Emoji.Response>(url).then((res) => {
|
||||||
|
if (res.data.retcode === 0) {
|
||||||
|
const emojis: Record<string, string> = {};
|
||||||
|
res.data.data.list.forEach((series) => {
|
||||||
|
series.list.forEach((emoji) => {
|
||||||
|
emojis[emoji.name] = emoji.icon;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return emojis;
|
||||||
|
}
|
||||||
|
return res.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
84
src/plugins/Mys/types/Emoji.d.ts
vendored
Normal file
84
src/plugins/Mys/types/Emoji.d.ts
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins Mys types Emoji.d.ts
|
||||||
|
* @description Mys 表情包类型声明文件
|
||||||
|
* @author BTMuli <bt-muli@outlook.com>
|
||||||
|
* @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[];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -185,7 +185,7 @@ function parseText(data: TGApp.Plugins.Mys.Post.StructuredContent): HTMLSpanElem
|
|||||||
if (data.attributes.color) {
|
if (data.attributes.color) {
|
||||||
let colorGet = data.attributes.color;
|
let colorGet = data.attributes.color;
|
||||||
// 如果 colorGet 在 darkColorList 中,就设置为对应的颜色
|
// 如果 colorGet 在 darkColorList 中,就设置为对应的颜色
|
||||||
if (isColorSimilar("#000000", colorGet)) {
|
if (isColorSimilar("#1E1E1E", colorGet)) {
|
||||||
colorGet = "var(--app-page-content)";
|
colorGet = "var(--app-page-content)";
|
||||||
}
|
}
|
||||||
text.style.color = colorGet;
|
text.style.color = colorGet;
|
||||||
@@ -194,6 +194,10 @@ function parseText(data: TGApp.Plugins.Mys.Post.StructuredContent): HTMLSpanElem
|
|||||||
return LinkTextParser(data);
|
return LinkTextParser(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (data.insert.startsWith("_")) {
|
||||||
|
console.log(data.insert);
|
||||||
|
return emojiParser(data);
|
||||||
|
}
|
||||||
// 添加 class
|
// 添加 class
|
||||||
text.classList.add("mys-post-span");
|
text.classList.add("mys-post-span");
|
||||||
// 设置 span 内容
|
// 设置 span 内容
|
||||||
@@ -542,4 +546,33 @@ function parseMention(data: TGApp.Plugins.Mys.Post.StructuredContent): HTMLAncho
|
|||||||
return link;
|
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<string, string> = 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;
|
export default parsePost;
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ onMounted(async () => {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
loadingEmpty.value = true;
|
loadingEmpty.value = true;
|
||||||
loadingTitle.value = "帖子不存在或解析失败";
|
loadingTitle.value = "帖子不存在或解析失败";
|
||||||
|
loadingSub.value = error instanceof Error ? error.message : <string>error;
|
||||||
await appWindow.setTitle(`【帖子】${postId}-解析失败`);
|
await appWindow.setTitle(`【帖子】${postId}-解析失败`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user