支持 post&anno share

This commit is contained in:
BTMuli
2023-06-16 16:01:11 +08:00
parent 1eb78db08c
commit 5393dc1bb5
8 changed files with 99 additions and 18 deletions

View File

@@ -30,7 +30,8 @@
"https://hk4e-api.mihoyo.com/*",
"https://passport-api.mihoyo.com/*",
"https://passport-api-v4.mihoyo.com/*",
"https://act-webstatic.mihoyo.com/*"
"https://act-webstatic.mihoyo.com/*",
"https://sdk-webstatic.mihoyo.com/*"
]
},
"shell": {

View File

@@ -1,12 +1,14 @@
/*
* @file assets css post-parser.css
* @description 游戏公告解析 css
* @since Alpha v0.1.1
* @author BTMuli <bt-muli@outlook.com
* @since Alpha v0.2.0
*/
.anno-body {
margin: 20px auto;
margin: 0 auto;
width: 800px;
font-family: "Genshin-Light", serif;
font-family: var(--font-text);
}
.anno-title {

View File

@@ -1,12 +1,14 @@
/*
* @file assets css post-parser.css
* @description 米游社解析 css
* @since Alpha v0.1.3
* @author BTMuli <bt-muli@outlook.com>
* @since Alpha v0.2.0
*/
.mys-post-body {
margin: 20px auto;
margin: 0 auto;
width: 800px;
font-family: "Genshin-Light", serif;
font-family: var(--font-text);
color: var(--post-default-text);
}

View File

@@ -0,0 +1,48 @@
<template>
<div class="share-box">
<div class="share-btn" @click="shareContent()">
<v-icon style="color:var(--theme-switch-icon)">
mdi-share-variant
</v-icon>
</div>
</div>
</template>
<script lang="ts" setup>
// utils
import { generateShareImg } from "../../utils/TGShare";
interface TShareBtnProps {
modelValue: HTMLElement;
title: string;
}
const props = defineProps<TShareBtnProps>();
async function shareContent () {
await generateShareImg(props.title, props.modelValue);
}
</script>
<style lang="css" scoped>
.share-box {
position: absolute;
top: 20px;
right: 20px;
cursor: pointer;
border-radius: 50%;
border: var(--theme-switch-icon) 2px solid;
}
.share-box:hover {
opacity: 0.8;
}
.share-btn {
width: 24px;
height: 24px;
display: flex;
justify-content: center;
align-items: center;
margin: 5px;
padding-right: 2px;
}
</style>

View File

@@ -1,6 +1,7 @@
<!-- eslint-disable vue/no-v-html -->
<template>
<TSwitchTheme />
<TShareBtn v-show="!loadingEmpty" v-model="annoRef" :title="annoTitle" />
<TOLoading v-model="loading" :title="loadingTitle" :empty="loadingEmpty" />
<div class="anno-body">
<div class="anno-title">
@@ -9,7 +10,7 @@
<div class="anno-subtitle">
{{ annoData.subtitle }}
</div>
<img v-if="annoData.banner !== ''" :src="annoData.banner" alt="cover" class="anno-img">
<img v-if="annoData.banner !== ''" :src="annoBanner" alt="cover" class="anno-img">
<div class="anno-content" v-html="annoHtml" />
</div>
</template>
@@ -19,21 +20,28 @@ import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import TOLoading from "../components/overlay/to-loading.vue";
import TSwitchTheme from "../components/main/t-switchTheme.vue";
import TShareBtn from "../components/main/t-shareBtn.vue";
// tauri
import { appWindow } from "@tauri-apps/api/window";
// plugins
import TGRequest from "../web/request/TGRequest";
import TGUtils from "../web/utils/TGUtils";
import { saveImgLocal } from "../utils/TGShare";
// loading
const loading = ref(true as boolean);
const loadingTitle = ref("正在加载");
const loadingEmpty = ref(false as boolean);
// share
const annoRef = ref({} as HTMLElement);
const annoTitle = ref("");
// 数据
const annoId = Number(useRoute().params.anno_id);
const annoData = ref({} as TGApp.BBS.Announcement.ContentItem);
const annoHtml = ref("");
const annoBanner = ref("");
onMounted(async () => {
await appWindow.show();
@@ -49,8 +57,13 @@ onMounted(async () => {
try {
annoData.value = await TGRequest.Anno.getContent(annoId);
loadingTitle.value = "正在渲染数据...";
annoHtml.value = TGUtils.Anno.parseContent(annoData.value.content);
annoHtml.value = await TGUtils.Anno.parseContent(annoData.value.content);
annoBanner.value = await saveImgLocal(annoData.value.banner);
console.log(annoBanner.value);
annoTitle.value = annoData.value.title;
annoRef.value = document.querySelector(".anno-body") as HTMLElement;
} catch (error) {
console.error(error);
loadingEmpty.value = true;
loadingTitle.value = "公告不存在或解析失败";
return;

View File

@@ -222,7 +222,7 @@ import MysOper from "../plugins/Mys";
// utils
import { createTGWindow } from "../utils/TGWindow";
// interface
import { NewsCard, NewsData } from "../plugins/Mys/interface/news";
import { NewsCard } from "../plugins/Mys/interface/news";
// 路由
const router = useRouter();

View File

@@ -1,6 +1,7 @@
<!-- eslint-disable vue/no-v-html -->
<template>
<TSwitchTheme />
<TShareBtn v-show="!loadingEmpty" v-model="postRef" :title="postTitle" />
<TOLoading v-model="loading" :empty="loadingEmpty" :title="loadingTitle" />
<div class="mys-post-body" v-html="postHtml" />
</template>
@@ -9,21 +10,27 @@
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import TOLoading from "../components/overlay/to-loading.vue";
import TSwitchTheme from "../components/main/t-switchTheme.vue";
import TShareBtn from "../components/main/t-shareBtn.vue";
// tauri
import { appWindow } from "@tauri-apps/api/window";
// plugins
import MysOper from "../plugins/Mys";
import TSwitchTheme from "../components/main/t-switchTheme.vue";
// loading
const loading = ref(true as boolean);
const loadingTitle = ref("正在加载");
const loadingEmpty = ref(false as boolean);
// share
const postRef = ref({} as HTMLElement);
const postTitle = ref("");
// 数据
const postId = Number(useRoute().params.post_id);
const postHtml = ref("");
onMounted(async () => {
await appWindow.show();
// 检查数据
@@ -39,6 +46,8 @@ onMounted(async () => {
const postData = await MysOper.Post.get(postId);
loadingTitle.value = "正在渲染数据...";
postHtml.value = MysOper.Post.parser(postData);
postTitle.value = postData.post.subject;
postRef.value = document.querySelector(".mys-post-body") as HTMLElement;
await appWindow.setTitle(postData.post.subject);
} catch (error) {
console.error(error);

View File

@@ -1,19 +1,20 @@
/**
* @file web utils parseAnno.ts
* @description 解析游戏内公告数据
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.1.5
* @author BTMuli <bt-muli@outlook.com>
* @since Alpha v0.2.0
*/
import { decodeRegExp } from "./tools";
import { saveImgLocal } from "../../utils/TGShare";
/**
* @description 解析游戏内公告数据
* @since Alpha v0.1.5
* @since Alpha v0.2.0
* @param {string} data 游戏内公告数据
* @returns {string} 解析后的数据
* @returns {Promise<string>} 解析后的数据
*/
export function parseAnnoContent (data: string): string {
export async function parseAnnoContent(data: string): Promise<string> {
const htmlBase = new DOMParser().parseFromString(data, "text/html");
htmlBase.querySelectorAll("span").forEach((span) => {
if (span.style.fontSize) {
@@ -40,11 +41,16 @@ export function parseAnnoContent (data: string): string {
});
}
});
htmlBase.querySelectorAll("img").forEach((img) => {
const imgList = Array.from(htmlBase.querySelectorAll("img"));
for (const img of imgList) {
img.style.maxWidth = "100%";
img.style.borderRadius = "10px";
img.style.margin = "10px 0";
});
const src = img.getAttribute("src");
if (src) {
img.setAttribute("src", await saveImgLocal(src));
}
}
htmlBase.querySelectorAll("a").forEach((a) => {
const span = htmlBase.createElement("i");
span.classList.add("mdi", "mdi-link-variant", "anno-link-icon");