mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-13 09:28:14 +08:00
💄 调整公告页样式
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @file assets/css/post-parser.css
|
||||
* @description 游戏公告解析 css
|
||||
* @since Beta v0.4.0
|
||||
* @since Beta v0.4.4
|
||||
*/
|
||||
|
||||
.anno-body {
|
||||
@@ -17,12 +17,12 @@
|
||||
}
|
||||
|
||||
.anno-title {
|
||||
font-size: 24px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.anno-subtitle {
|
||||
font-size: 18px;
|
||||
opacity: 0.5;
|
||||
font-size: 16px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.anno-img {
|
||||
|
||||
@@ -376,8 +376,6 @@ function createAnno(item: TGApp.App.Announcement.ListCard): void {
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 5px;
|
||||
border-bottom: 1px dotted var(--tgc-white-4);
|
||||
border-left: 1px dotted var(--tgc-white-4);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
backdrop-filter: blur(20px);
|
||||
background: rgb(0 0 0/20%);
|
||||
|
||||
@@ -10,19 +10,21 @@
|
||||
/>
|
||||
<ToLoading v-model="loading" :title="loadingTitle" :subtitle="loadingSub" :empty="loadingEmpty" />
|
||||
<div class="anno-body">
|
||||
<div class="anno-info">AnnoID: {{ annoId }} | Render by TeyvatGuide v{{ appVersion }}</div>
|
||||
<div class="anno-title">
|
||||
{{ annoData.title }}
|
||||
</div>
|
||||
<div class="anno-subtitle">
|
||||
{{ annoData.subtitle }}
|
||||
{{ parseText(annoData.subtitle) }}
|
||||
</div>
|
||||
<img v-if="annoData.banner !== ''" :src="annoBanner" alt="cover" class="anno-img" />
|
||||
<div class="anno-content" v-html="annoHtml" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { app } from "@tauri-apps/api";
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
import { ref, onMounted, watch, onUnmounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import TSwitchTheme from "../components/app/t-switchTheme.vue";
|
||||
@@ -44,7 +46,7 @@ const loadingSub = ref<string>();
|
||||
const loadingEmpty = ref<boolean>(false);
|
||||
|
||||
// share
|
||||
const annoRef = ref<HTMLElement>(<HTMLElement>{});
|
||||
const annoRef = ref<HTMLElement | null | undefined>();
|
||||
const annoTitle = ref<string>("");
|
||||
|
||||
// 数据
|
||||
@@ -52,12 +54,14 @@ const route = useRoute();
|
||||
const annoId = Number(route.params.anno_id);
|
||||
const region = <AnnoServer>route.params.region;
|
||||
const lang = <AnnoLang>route.params.lang;
|
||||
const appVersion = ref<string>();
|
||||
const annoData = ref<TGApp.BBS.Announcement.ContentItem>(<TGApp.BBS.Announcement.ContentItem>{});
|
||||
const annoHtml = ref<string>();
|
||||
const annoBanner = ref<string>();
|
||||
|
||||
onMounted(async () => {
|
||||
await appWindow.show();
|
||||
appVersion.value = await app.getVersion();
|
||||
// 检查数据
|
||||
if (!annoId || !region) {
|
||||
loadingEmpty.value = true;
|
||||
@@ -103,10 +107,38 @@ watch(loadShare, (value) => {
|
||||
}
|
||||
});
|
||||
|
||||
function parseText(title: string): string {
|
||||
const div = document.createElement("div");
|
||||
div.innerHTML = title;
|
||||
return div.innerText;
|
||||
}
|
||||
|
||||
function createAnnoJson(annoId: number, region: AnnoServer, lang: AnnoLang) {
|
||||
const jsonPath = `/anno_detail_json/${region}/${annoId}/${lang}`;
|
||||
const jsonTitle = `Anno_${region}_${annoId}_${lang}_JSON`;
|
||||
createTGWindow(jsonPath, "Dev_JSON", jsonTitle, 960, 720, false, false);
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
document
|
||||
.querySelector(".anno-body")
|
||||
?.querySelectorAll("img")
|
||||
.forEach((img) => {
|
||||
if (img.src.startsWith("blob:")) URL.revokeObjectURL(img.src);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.anno-info {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px dashed var(--common-shadow-2);
|
||||
margin-bottom: 10px;
|
||||
color: var(--box-text-4);
|
||||
font-family: var(--font-title);
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
<style lang="css" src="../assets/css/anno-parser.css" scoped></style>
|
||||
|
||||
@@ -1,53 +1,105 @@
|
||||
/**
|
||||
* @file web/utils/parseAnno.ts
|
||||
* @description 解析游戏内公告数据
|
||||
* @since Beta v0.4.0
|
||||
* @since Beta v0.4.4
|
||||
*/
|
||||
|
||||
import { decodeRegExp } from "./tools";
|
||||
import { saveImgLocal } from "../../utils/TGShare";
|
||||
import { isColorSimilar } from "../../utils/toolFunc";
|
||||
|
||||
/**
|
||||
* @description 解析 a
|
||||
* @since Beta v0.4.4
|
||||
* @param {HTMLAnchorElement} a a 元素
|
||||
* @returns {HTMLAnchorElement} 解析后的 a 元素
|
||||
*/
|
||||
function parseAnnoA(a: HTMLAnchorElement): HTMLAnchorElement {
|
||||
const span = document.createElement("i");
|
||||
span.classList.add("mdi", "mdi-link-variant", "anno-link-icon");
|
||||
a.prepend(span);
|
||||
const regex = /javascript:miHoYoGameJSSDK.openIn(Browser|Webview)\('(.+)'\);/;
|
||||
if (regex.test(a.getAttribute("href") ?? "")) {
|
||||
const href = a.getAttribute("href")?.match(regex);
|
||||
if (href) {
|
||||
a.setAttribute("href", href[2]);
|
||||
a.target = "_blank";
|
||||
a.title = href[2];
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析 p
|
||||
* @since Beta v0.4.4
|
||||
* @param {HTMLParagraphElement} p p 元素
|
||||
* @returns {HTMLParagraphElement} 解析后的 p 元素
|
||||
*/
|
||||
function parseAnnoP(p: HTMLParagraphElement): HTMLParagraphElement {
|
||||
if (p.children.length === 0) {
|
||||
p.innerHTML = decodeRegExp(p.innerHTML);
|
||||
} else {
|
||||
p.querySelectorAll("*").forEach((child) => {
|
||||
if (child.children.length === 0) {
|
||||
child.innerHTML = decodeRegExp(child.innerHTML);
|
||||
}
|
||||
});
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析 span
|
||||
* @since Beta v0.4.4
|
||||
* @param {HTMLSpanElement} span span 元素
|
||||
* @returns {HTMLSpanElement} 解析后的 span 元素
|
||||
*/
|
||||
function parseAnnoSpan(span: HTMLSpanElement): HTMLSpanElement {
|
||||
if (span.style.fontSize) {
|
||||
span.style.fontSize = "";
|
||||
}
|
||||
if (span.style.color) {
|
||||
if (isColorSimilar("#000000", span.style.color)) {
|
||||
span.style.color = "var(--app-page-content)";
|
||||
}
|
||||
}
|
||||
if (span.children.length === 0) {
|
||||
span.innerHTML = decodeRegExp(span.innerHTML);
|
||||
} else {
|
||||
span.querySelectorAll("*").forEach((child) => {
|
||||
if (child.children.length === 0) {
|
||||
child.innerHTML = decodeRegExp(child.innerHTML);
|
||||
}
|
||||
});
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析 table
|
||||
* @since Beta v0.4.4
|
||||
* @param {HTMLTableElement} table table 元素
|
||||
* @returns {HTMLTableElement} 解析后的 table 元素
|
||||
*/
|
||||
function parseAnnoTable(table: HTMLTableElement): HTMLTableElement {
|
||||
table.style.borderColor = "var(--common-shadow-2)";
|
||||
table.querySelectorAll("td").forEach((td) => {
|
||||
if (td.style.backgroundColor) td.style.backgroundColor = "var(--box-bg-1)";
|
||||
});
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析游戏内公告数据
|
||||
* @since Beta v0.4.0
|
||||
* @since Beta v0.4.4
|
||||
* @todo 需要完善
|
||||
* @param {string} data 游戏内公告数据
|
||||
* @returns {Promise<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) {
|
||||
span.style.fontSize = "";
|
||||
}
|
||||
// 获取color
|
||||
if (span.style.color) {
|
||||
if (isColorSimilar("#000000", span.style.color)) {
|
||||
span.style.color = "var(--app-page-content)";
|
||||
}
|
||||
}
|
||||
if (span.children.length === 0) {
|
||||
return (span.innerHTML = decodeRegExp(span.innerHTML));
|
||||
} else {
|
||||
span.querySelectorAll("*").forEach((child) => {
|
||||
if (child.children.length === 0) {
|
||||
return (child.innerHTML = decodeRegExp(child.innerHTML));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
htmlBase.querySelectorAll("p").forEach((p) => {
|
||||
if (p.children.length === 0) {
|
||||
return (p.innerHTML = decodeRegExp(p.innerHTML));
|
||||
} else {
|
||||
p.querySelectorAll("*").forEach((child) => {
|
||||
if (child.children.length === 0) {
|
||||
return (child.innerHTML = decodeRegExp(child.innerHTML));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
htmlBase.querySelectorAll("a").forEach((a) => parseAnnoA(a));
|
||||
const imgList = Array.from(htmlBase.querySelectorAll("img"));
|
||||
for (const img of imgList) {
|
||||
img.style.maxWidth = "100%";
|
||||
@@ -58,23 +110,8 @@ export async function parseAnnoContent(data: string): Promise<string> {
|
||||
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");
|
||||
a.prepend(span);
|
||||
if (a.href.startsWith("javascript:miHoYoGameJSSDK.openInBrowser")) {
|
||||
a.href = a.href.replace("javascript:miHoYoGameJSSDK.openInBrowser('", "").replace("');", "");
|
||||
a.target = "_blank";
|
||||
} else if (a.href.startsWith("javascript:miHoYoGameJSSDK.openInWebview")) {
|
||||
a.href = a.href.replace("javascript:miHoYoGameJSSDK.openInWebview('", "").replace("');", "");
|
||||
a.target = "_blank";
|
||||
}
|
||||
});
|
||||
htmlBase.querySelectorAll("table").forEach((table) => {
|
||||
table.style.borderColor = "var(--common-shadow-2)";
|
||||
table.querySelectorAll("td").forEach((td) => {
|
||||
if (td.style.backgroundColor) td.style.backgroundColor = "var(--box-bg-1)";
|
||||
});
|
||||
});
|
||||
htmlBase.querySelectorAll("p").forEach((p) => parseAnnoP(p));
|
||||
htmlBase.querySelectorAll("span").forEach((span) => parseAnnoSpan(span));
|
||||
htmlBase.querySelectorAll("table").forEach((table) => parseAnnoTable(table));
|
||||
return htmlBase.body.innerHTML;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user