Files
TeyvatGuide/src/components/viewPost/tp-parser.vue
2025-03-08 23:12:11 +08:00

112 lines
3.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<component
v-for="(tp, index) in getParsedData(props.data)"
:key="index"
:is="getTpName(tp)"
:data="tp"
/>
</template>
<script lang="ts" setup>
import type { Component } from "vue";
import TpBackupText from "./tp-backupText.vue";
import TpDivider from "./tp-divider.vue";
import TpEmoticon from "./tp-emoticon.vue";
import TpImage from "./tp-image.vue";
import TpLinkCard from "./tp-linkCard.vue";
import TpMention from "./tp-mention.vue";
import TpText, { type TpText as TpTextType } from "./tp-text.vue";
import TpTexts from "./tp-texts.vue";
import TpUid from "./tp-uid.vue";
import TpUnknown from "./tp-unknown.vue";
import TpVideo from "./tp-video.vue";
import TpVillaCard from "./tp-villaCard.vue";
import TpVod from "./tp-vod.vue";
import TpVote from "./tp-vote.vue";
type SctPostDataArr = Array<TGApp.BBS.SctPost.Base>;
type TpParserProps = { data: SctPostDataArr };
const props = defineProps<TpParserProps>();
function getParsedData(data: SctPostDataArr): SctPostDataArr {
const res: SctPostDataArr = [];
let child: SctPostDataArr = [];
let cur: TGApp.BBS.SctPost.Base | undefined;
for (const tp of data) {
const tpName = getTpName(tp);
// 单独处理 TpMention
if (tpName === TpMention) {
child.push(tp);
continue;
}
if (tpName !== TpText) {
cur = tp;
child = [];
res.push(cur);
continue;
}
if (typeof tp.insert === "string") {
tp.insert = tp.insert.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
}
if (tp.insert === "\n") {
child.push(tp);
cur = { insert: "", attributes: tp.attributes, children: child };
res.push(cur);
child = [];
continue;
}
const parsedText = getParsedText(<TpTextType>tp);
let check = 0;
for (let i = 0; i < parsedText.length; i++) {
const text = parsedText[i];
child.push(text);
if (text.insert === "\n") {
check += child.length;
cur = { insert: "", attributes: text.attributes, children: child };
res.push(cur);
child = [];
}
}
if (check < parsedText.length && check !== 0) {
res.push(...child);
child = [];
}
}
if (res.length === 0 && child.length > 0) res.push(...child);
return res;
}
function getParsedText(data: TpTextType): Array<TpTextType> {
if (data.insert.includes("\n") && data.insert !== "\n") {
const splits = data.insert.split("\n");
const res = [];
for (let i = 0; i < splits.length; i++) {
if (splits[i] !== "") res.push({ insert: splits[i], attributes: data.attributes });
if (i !== splits.length - 1) res.push({ insert: "\n", attributes: data.attributes });
}
return res;
}
return [data];
}
function getTpName(tp: TGApp.BBS.SctPost.Base): Component {
if (tp.children) return TpTexts;
if (typeof tp.insert === "string") return TpText;
// custom_emoticon属于backup_text的一种必须放在backup_text判断的前面
if ("custom_emoticon" in tp.insert) return TpEmoticon;
// game_user_info属于backup_text的一种必须放在backup_text判断的前面
if ("game_user_info" in tp.insert) return TpUid;
if ("backup_text" in tp.insert) return TpBackupText;
if ("divider" in tp.insert) return TpDivider;
if ("image" in tp.insert) return TpImage;
if ("link_card" in tp.insert) return TpLinkCard;
if ("mention" in tp.insert) return TpMention;
if ("video" in tp.insert) return TpVideo;
if ("villa_card" in tp.insert) return TpVillaCard;
if ("vod" in tp.insert) return TpVod;
if ("vote" in tp.insert) return TpVote;
return TpUnknown;
}
</script>