mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2026-03-28 05:59:46 +08:00
112 lines
3.5 KiB
Vue
112 lines
3.5 KiB
Vue
<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>
|