mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
@@ -34,6 +34,7 @@ pub async fn create_mhy_client(handle: AppHandle, func: String, url: String) {
|
|||||||
mhy_window_config.url = get_mhy_client_url(func.clone());
|
mhy_window_config.url = get_mhy_client_url(func.clone());
|
||||||
}
|
}
|
||||||
if func == "birthday"
|
if func == "birthday"
|
||||||
|
|| func == "web_act"
|
||||||
|| url.starts_with("https://webstatic.mihoyo.com/ys/event/e20220303-birthday/index.html")
|
|| url.starts_with("https://webstatic.mihoyo.com/ys/event/e20220303-birthday/index.html")
|
||||||
{
|
{
|
||||||
mhy_window_config.width = 1280.0;
|
mhy_window_config.width = 1280.0;
|
||||||
|
|||||||
@@ -1,19 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="props.data.insert.lottery" @click="toLottery()" class="mys-post-link">
|
<div
|
||||||
|
v-if="props.data.insert.lottery"
|
||||||
|
@click="toLottery()"
|
||||||
|
class="tp-backup-lottery"
|
||||||
|
:title="`ID: ${props.data.insert.lottery.id}`"
|
||||||
|
>
|
||||||
<v-icon size="small">mdi-gift</v-icon>
|
<v-icon size="small">mdi-gift</v-icon>
|
||||||
<span>{{ props.data.insert.lottery.toast }}</span>
|
<span>{{ props.data.insert.lottery.toast }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="props.data.insert.fold" class="mys-post-div">
|
<details v-else-if="props.data.insert.fold" class="tp-backup-fold">
|
||||||
<details class="mys-post-details">
|
<summary class="tp-backup-summary">
|
||||||
<summary>
|
<TpParser :data="JSON.parse(props.data.insert.fold.title)" />
|
||||||
<TpParser :data="JSON.parse(props.data.insert.fold.title)" />
|
</summary>
|
||||||
</summary>
|
<div class="tp-backup-details">
|
||||||
<TpParser :data="JSON.parse(props.data.insert.fold.content)" />
|
<TpParser :data="JSON.parse(props.data.insert.fold.content)" />
|
||||||
</details>
|
</div>
|
||||||
</div>
|
</details>
|
||||||
<TpUnknown v-else :data="<TGApp.Plugins.Mys.SctPost.Empty>props.data" />
|
<TpUnknown v-else :data="<TGApp.Plugins.Mys.SctPost.Empty>props.data" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { toRaw } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
import TpParser from "./tp-parser.vue";
|
import TpParser from "./tp-parser.vue";
|
||||||
@@ -40,6 +46,8 @@ interface TpBackupTextProps {
|
|||||||
const props = defineProps<TpBackupTextProps>();
|
const props = defineProps<TpBackupTextProps>();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
console.log("tpBackupText", props.data.insert.backup_text, toRaw(props.data));
|
||||||
|
|
||||||
async function toLottery() {
|
async function toLottery() {
|
||||||
if (!props.data.insert.lottery) return;
|
if (!props.data.insert.lottery) return;
|
||||||
await router.push({
|
await router.push({
|
||||||
@@ -50,3 +58,34 @@ async function toLottery() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.tp-backup-lottery {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #00c3ff;
|
||||||
|
column-gap: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-backup-fold {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid var(--common-shadow-2);
|
||||||
|
border-radius: 10px;
|
||||||
|
margin: 10px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-backup-fold ::marker {
|
||||||
|
color: var(--common-shadow-4);
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-backup-summary {
|
||||||
|
margin-left: 5px;
|
||||||
|
font-family: var(--font-title);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-backup-details {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mys-post-divider" v-if="isInclude">
|
<div class="tp-divider-box" v-if="isInclude">
|
||||||
<img alt="divider" :src="`/source/post/divider_${props.data.insert.divider}.webp`" />
|
<img
|
||||||
|
alt="divider"
|
||||||
|
:src="`/source/post/divider_${props.data.insert.divider}.webp`"
|
||||||
|
:title="props.data.insert.divider"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<TpUnknown v-else :data="props.data" />
|
<TpUnknown v-else :data="emptyData" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
@@ -20,8 +24,21 @@ interface TpDividerProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<TpDividerProps>();
|
const props = defineProps<TpDividerProps>();
|
||||||
|
const emptyData: TGApp.Plugins.Mys.SctPost.Empty = <TGApp.Plugins.Mys.SctPost.Empty>props.data;
|
||||||
|
|
||||||
|
console.log("tpDivider", props.data.insert.divider);
|
||||||
|
|
||||||
const isInclude = computed(() => {
|
const isInclude = computed(() => {
|
||||||
const list = ["line_1", "line_2", "line_3", "line_4"];
|
const list = ["line_1", "line_2", "line_3", "line_4"];
|
||||||
return list.includes(props.data.insert.divider);
|
return list.includes(props.data.insert.divider);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.tp-divider-box {
|
||||||
|
margin: 10px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-divider-box img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mys-post-div">
|
<div class="tp-image-box">
|
||||||
<img
|
<img
|
||||||
class="mys-post-img"
|
:style="getImageStyle()"
|
||||||
:src="props.data.insert.image"
|
:src="props.data.insert.image"
|
||||||
:alt="props.data.insert.image"
|
:alt="props.data.insert.image"
|
||||||
:title="props.data.insert.image"
|
:title="getImageTitle()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { StyleValue, toRaw } from "vue";
|
||||||
|
|
||||||
|
import { bytesToSize } from "../../utils/toolFunc";
|
||||||
|
|
||||||
interface TpImage {
|
interface TpImage {
|
||||||
insert: {
|
insert: {
|
||||||
image: string;
|
image: string;
|
||||||
@@ -16,8 +20,9 @@ interface TpImage {
|
|||||||
attributes?: {
|
attributes?: {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
size: number | undefined;
|
size?: number;
|
||||||
ext: string | undefined;
|
ext?: "png" | "jpg"; // 待补充
|
||||||
|
align?: "center"; // 待补充
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,4 +31,42 @@ interface TpImageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<TpImageProps>();
|
const props = defineProps<TpImageProps>();
|
||||||
|
|
||||||
|
console.log("tp-image", props.data.insert.image, toRaw(props.data).attributes);
|
||||||
|
|
||||||
|
function getImageStyle(): StyleValue {
|
||||||
|
let style: StyleValue = <Array<StyleValue>>[];
|
||||||
|
if (props.data.attributes == undefined) return style;
|
||||||
|
if (props.data.attributes.width < 800) {
|
||||||
|
const widthFullRule: StyleValue = "width: 100%";
|
||||||
|
style.push(widthFullRule);
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getImageTitle(): string {
|
||||||
|
if (props.data.attributes == undefined) return "";
|
||||||
|
const res: string[] = [];
|
||||||
|
res.push(`宽度:${props.data.attributes.width}px`);
|
||||||
|
res.push(`高度:${props.data.attributes.height}px`);
|
||||||
|
if (props.data.attributes.size) {
|
||||||
|
const size = bytesToSize(props.data.attributes.size);
|
||||||
|
res.push(`大小:${size}`);
|
||||||
|
}
|
||||||
|
if (props.data.attributes.ext) {
|
||||||
|
res.push(`格式:${props.data.attributes.ext}`);
|
||||||
|
}
|
||||||
|
return res.join("\n");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.tp-image-box {
|
||||||
|
margin: 10px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-image-box img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,29 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<span v-if="mode == 'link'" class="mys-post-link" @click="toLink()">
|
<span v-if="mode == 'link'" class="tp-text-link" @click="toLink()">
|
||||||
<v-icon size="small">mdi-link-variant</v-icon>{{ props.data.insert }}
|
<v-icon size="small">mdi-link-variant</v-icon>{{ props.data.insert }}
|
||||||
</span>
|
</span>
|
||||||
<img
|
<span v-else-if="mode == 'emoji'" class="tp-text-emoji">
|
||||||
v-else-if="mode == 'emoji'"
|
<img :src="getEmojiUrl()" :alt="getEmojiName()" :title="getEmojiName()" />
|
||||||
class="mys-post-emoji"
|
</span>
|
||||||
:src="getEmojiUrl()"
|
<span v-else :style="getTextStyle()" class="tp-text-span">
|
||||||
:alt="getEmojiName()"
|
{{ props.data.insert }}
|
||||||
:title="getEmojiName()"
|
|
||||||
/>
|
|
||||||
<span v-else :style="getTextStyle()">
|
|
||||||
<span
|
|
||||||
v-if="props.data.insert.includes('\n')"
|
|
||||||
v-html="props.data.insert.replace(/\n/g, '<br />')"
|
|
||||||
/>
|
|
||||||
<span v-else>{{ props.data.insert }}</span>
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref, StyleValue, toRaw } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
import { getEmojis } from "../../plugins/Mys/request/getEmojis";
|
import { getEmojis } from "../../plugins/Mys/request/getEmojis";
|
||||||
import { isColorSimilar, isMysPost } from "../../plugins/Mys/utils/parsePost";
|
import { isColorSimilar, isMysPost } from "../../plugins/Mys/utils/parsePost";
|
||||||
import { useAppStore } from "../../store/modules/app";
|
|
||||||
import TGClient from "../../utils/TGClient";
|
import TGClient from "../../utils/TGClient";
|
||||||
import showConfirm from "../func/confirm";
|
import showConfirm from "../func/confirm";
|
||||||
import showSnackbar from "../func/snackbar";
|
import showSnackbar from "../func/snackbar";
|
||||||
@@ -46,6 +37,8 @@ const props = defineProps<TpTextProps>();
|
|||||||
const mode = ref<string>("text");
|
const mode = ref<string>("text");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
console.log("tpText", JSON.stringify(props.data.insert), toRaw(props.data)?.attributes);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.data.attributes && "link" in props.data.attributes) {
|
if (props.data.attributes && "link" in props.data.attributes) {
|
||||||
mode.value = "link";
|
mode.value = "link";
|
||||||
@@ -57,30 +50,30 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 解析文本样式
|
// 解析文本样式
|
||||||
function getTextStyle(): string {
|
function getTextStyle(): StyleValue {
|
||||||
const style: CSSStyleDeclaration = <CSSStyleDeclaration>{};
|
const style = <Array<StyleValue>>[];
|
||||||
const data: TpText = <TpText>props.data;
|
const data: TpText = <TpText>props.data;
|
||||||
if (data.attributes) {
|
if (data.attributes) {
|
||||||
if (data.attributes.bold) {
|
if (data.attributes.bold) {
|
||||||
style.fontWeight = "bold";
|
const ruleBold: StyleValue = "fontFamily: var(--font-title)";
|
||||||
|
style.push(ruleBold);
|
||||||
}
|
}
|
||||||
if (data.attributes.color) {
|
if (data.attributes.color) {
|
||||||
let colorGet = data.attributes.color;
|
let colorGet = data.attributes.color;
|
||||||
if (isColorSimilar("#000000", data.attributes.color)) {
|
if (isColorSimilar("#000000", data.attributes.color)) {
|
||||||
colorGet = "var(--app-page-content);";
|
colorGet = "var(--app-page-content)";
|
||||||
}
|
}
|
||||||
style.color = colorGet;
|
const ruleColor: StyleValue = `color: ${colorGet}`;
|
||||||
|
style.push(ruleColor);
|
||||||
}
|
}
|
||||||
|
// todo 这边效果不是很好
|
||||||
|
// refer: 45245869
|
||||||
if (data.attributes.align) {
|
if (data.attributes.align) {
|
||||||
style.textAlign = data.attributes.align;
|
const ruleAlign: StyleValue = `textAlign: ${data.attributes.align}`;
|
||||||
}
|
style.push(ruleAlign);
|
||||||
if (props.data.insert.includes("\n")) {
|
|
||||||
style.whiteSpace = "pre-wrap";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Object.keys(style)
|
return style;
|
||||||
.map((key) => `${key}: ${style[key]}`)
|
|
||||||
.join(";");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析链接目标
|
// 解析链接目标
|
||||||
@@ -95,19 +88,26 @@ async function toLink() {
|
|||||||
post_id: link.split("/").pop(),
|
post_id: link.split("/").pop(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else if (link.startsWith("https://webstatic.mihoyo.com/ys/event/e20220303-birthday/")) {
|
} else if (
|
||||||
if (useAppStore().isLogin) {
|
link.startsWith("https://webstatic.mihoyo.com/ys/event/e20220303-birthday/") ||
|
||||||
await TGClient.open("birthday");
|
link.startsWith("https://act.mihoyo.com")
|
||||||
} else {
|
) {
|
||||||
const res = await showConfirm({
|
const resOpen = await showConfirm({
|
||||||
title: "跳转确认",
|
title: "采用内置 JSBridge?",
|
||||||
text: "未登录,是否采用内置 JSBridge 打开?(取消则使用浏览器打开)",
|
text: "取消则使用外部浏览器打开",
|
||||||
|
});
|
||||||
|
if (resOpen) {
|
||||||
|
const resType = await showConfirm({
|
||||||
|
title: "采用宽屏模式?",
|
||||||
|
text: "取消则使用默认竖屏",
|
||||||
});
|
});
|
||||||
if (res) {
|
if (resType) {
|
||||||
await TGClient.open("birthday");
|
await TGClient.open("web_act", link);
|
||||||
} else {
|
} else {
|
||||||
window.open(link);
|
await TGClient.open("web_act_thin", link);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
window.open(link);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
window.open(props.data.attributes.link);
|
window.open(props.data.attributes.link);
|
||||||
@@ -134,10 +134,36 @@ function getEmojiUrl(): string {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const emojiName = getEmojiName();
|
const emojiName = getEmojiName();
|
||||||
return JSON.parse(emojis)[emojiName];
|
return JSON.parse(<string>emojis)[emojiName];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEmojiName() {
|
function getEmojiName() {
|
||||||
return props.data.insert.slice(2, -1);
|
return props.data.insert.slice(2, -1);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.tp-text-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #00c3ff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-text-emoji {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
transform: translateY(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-text-emoji img {
|
||||||
|
width: 45px;
|
||||||
|
height: 45px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tp-text-span {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user