mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
🚸 部分资源释放
This commit is contained in:
@@ -7,7 +7,9 @@
|
||||
@click="emits('click')"
|
||||
:class="props.class"
|
||||
/>
|
||||
<v-progress-circular v-else indeterminate color="primary" size="25" />
|
||||
<div class="progress" v-else>
|
||||
<v-progress-circular indeterminate color="primary" size="25" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref, watch } from "vue";
|
||||
@@ -22,9 +24,7 @@ type TMiImgProps = {
|
||||
class?: string;
|
||||
ori?: boolean;
|
||||
};
|
||||
type TMiImgEmits = {
|
||||
(e: "click"): void;
|
||||
};
|
||||
type TMiImgEmits = (e: "click") => void;
|
||||
const props = defineProps<TMiImgProps>();
|
||||
const emits = defineEmits<TMiImgEmits>();
|
||||
|
||||
@@ -42,6 +42,7 @@ watch(
|
||||
async () => {
|
||||
if (!props.src) return;
|
||||
if (localUrl.value) URL.revokeObjectURL(localUrl.value);
|
||||
localUrl.value = undefined;
|
||||
const link = props.ori ? props.src : appStore.getImageUrl(props.src);
|
||||
localUrl.value = await saveImgLocal(link);
|
||||
},
|
||||
@@ -51,3 +52,13 @@ onUnmounted(() => {
|
||||
if (localUrl.value) URL.revokeObjectURL(localUrl.value);
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.progress {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
display: flex;
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
<div class="tua-abl-skills">
|
||||
<div v-for="skill in skills" :key="skill.skill_id" class="tua-abl-skill">
|
||||
<img :src="skill.icon" alt="skill" />
|
||||
<TMiImg :ori="true" :src="skill.icon" alt="skill" />
|
||||
<span>Lv.{{ skill.level }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,6 +46,7 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TItemBox, { type TItemBoxData } from "@comp/app/t-itemBox.vue";
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import TSUserAvatar from "@Sqlite/modules/userAvatar.js";
|
||||
import { computed } from "vue";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class="tua-dcc-item"
|
||||
:title="`${constellation.pos}命-${constellation.name}`"
|
||||
>
|
||||
<img :src="constellation.icon" alt="constellation" class="tua-dcc-icon" />
|
||||
<TMiImg :ori="true" :src="constellation.icon" alt="constellation" class="tua-dcc-icon" />
|
||||
<div v-if="!constellation.is_actived" class="tua-dcc-lock">
|
||||
<v-icon size="10px" color="var(--tgc-od-white)">mdi-lock</v-icon>
|
||||
</div>
|
||||
@@ -14,6 +14,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
type TuaDcConstellationsProps = { modelValue: Array<TGApp.Game.Avatar.Constellation> };
|
||||
|
||||
const props = defineProps<TuaDcConstellationsProps>();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
v-if="props.modelValue === false"
|
||||
class="empty"
|
||||
/>
|
||||
<img :src="props.modelValue.icon" :alt="props.modelValue.name" v-else />
|
||||
<TMiImg :ori="true" :src="props.modelValue.icon" :alt="props.modelValue.name" v-else />
|
||||
</div>
|
||||
</div>
|
||||
<div class="tua-dcr-right">
|
||||
@@ -59,6 +59,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import { computed } from "vue";
|
||||
|
||||
import { useUserStore } from "@/store/modules/user.js";
|
||||
@@ -188,8 +189,11 @@ function getPropSubStyle(
|
||||
|
||||
.tua-dcr-icon {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
:title="skill.name"
|
||||
class="tua-dct-item"
|
||||
>
|
||||
<img :src="skill.icon" alt="talent" class="tua-dct-icon" />
|
||||
<TMiImg :ori="true" :src="skill.icon" alt="talent" class="tua-dct-icon" />
|
||||
<div v-if="!skill.is_unlock" class="tua-dct-lock">
|
||||
<v-icon size="10px" color="var(--tgc-od-white)">mdi-lock</v-icon>
|
||||
</div>
|
||||
@@ -17,6 +17,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
type TuaDcTalentsProps = { modelValue: Array<TGApp.Game.Avatar.Skill> };
|
||||
|
||||
const props = defineProps<TuaDcTalentsProps>();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div class="tua-dc-container">
|
||||
<img :src="avatar" class="tua-dc-avatar" alt="avatar" />
|
||||
<div class="tua-dc-avatar">
|
||||
<TMiImg :src="props.modelValue.avatar.image" :ori="true" alt="avatar" />
|
||||
</div>
|
||||
<v-btn
|
||||
class="tua-dc-share"
|
||||
prepend-icon="mdi-share-variant"
|
||||
@@ -73,9 +75,10 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import showSnackbar from "@comp/func/snackbar.js";
|
||||
import TSUserAvatar from "@Sqlite/modules/userAvatar.js";
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
|
||||
import TuaDcConstellations from "./tua-dc-constellations.vue";
|
||||
import TuaDcProp from "./tua-dc-prop.vue";
|
||||
@@ -84,7 +87,7 @@ import TuaDcTalents from "./tua-dc-talents.vue";
|
||||
import TuaDcWeapon from "./tua-dc-weapon.vue";
|
||||
|
||||
import { useUserStore } from "@/store/modules/user.js";
|
||||
import { generateShareImg, saveImgLocal } from "@/utils/TGShare.js";
|
||||
import { generateShareImg } from "@/utils/TGShare.js";
|
||||
|
||||
type fixedLenArr<T, N extends number> = [T, ...Array<T>] & { length: N };
|
||||
type RelicList = fixedLenArr<TGApp.Game.Avatar.Relic | false, 5>;
|
||||
@@ -107,36 +110,13 @@ const propMain = computed<Array<TGApp.Game.Avatar.PropMapItem | false>>(() =>
|
||||
);
|
||||
|
||||
const bg = ref<string>("/WIKI/nameCard/profile/原神·印象.webp");
|
||||
const avatar = ref<string>(props.modelValue.avatar.image);
|
||||
const loading = ref<boolean>(false);
|
||||
|
||||
onMounted(async () => {
|
||||
await loadData();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (avatar.value.startsWith("blob:")) {
|
||||
URL.revokeObjectURL(avatar.value);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
async () => {
|
||||
if (avatar.value.startsWith("blob:")) {
|
||||
URL.revokeObjectURL(avatar.value);
|
||||
}
|
||||
avatar.value = props.modelValue.avatar.image;
|
||||
await loadData();
|
||||
},
|
||||
);
|
||||
onMounted(async () => await loadData());
|
||||
|
||||
async function loadData(): Promise<void> {
|
||||
const card = TSUserAvatar.getAvatarCard(props.modelValue.cid);
|
||||
bg.value = `url("/WIKI/nameCard/profile/${card}.webp")`;
|
||||
if (!avatar.value.startsWith("blob:")) {
|
||||
avatar.value = await saveImgLocal(props.modelValue.avatar.image);
|
||||
}
|
||||
}
|
||||
|
||||
async function share(): Promise<void> {
|
||||
@@ -176,9 +156,18 @@ async function share(): Promise<void> {
|
||||
.tua-dc-avatar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -80px;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
object-fit: contain;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.tua-dc-rt {
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
v-if="props.modelValue === false"
|
||||
class="empty"
|
||||
/>
|
||||
<img :src="props.modelValue.icon" :alt="props.modelValue.name" v-else />
|
||||
<TMiImg :ori="true" :src="props.modelValue.icon" :alt="props.modelValue.name" v-else />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
import { useUserStore } from "@/store/modules/user.js";
|
||||
|
||||
type TuaRelicBoxProps = { modelValue: TGApp.Game.Avatar.Relic | false; position: number };
|
||||
@@ -71,8 +73,11 @@ function getRelicTitle(): string {
|
||||
|
||||
.tua-relic-icon {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="duc-dolb-box">
|
||||
<div
|
||||
v-for="constellation in constellations"
|
||||
v-for="constellation in props.modelValue"
|
||||
:key="constellation.pos"
|
||||
:title="constellation.name"
|
||||
class="duc-dolb-item"
|
||||
@@ -9,48 +9,18 @@
|
||||
<div v-if="!constellation.is_actived" class="duc-dolb-lock">
|
||||
<v-icon color="white">mdi-lock</v-icon>
|
||||
</div>
|
||||
<img class="duc-dolb-icon" :src="constellation.icon" alt="constellation" />
|
||||
<div class="duc-dolb-icon">
|
||||
<TMiImg :ori="true" :src="constellation.icon" alt="constellation" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, shallowRef, watch } from "vue";
|
||||
|
||||
import { saveImgLocal } from "@/utils/TGShare.js";
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
type DucDetailOlbProps = { modelValue: Array<TGApp.Game.Avatar.Constellation> };
|
||||
|
||||
const props = defineProps<DucDetailOlbProps>();
|
||||
const constellations = shallowRef<Array<TGApp.Game.Avatar.Constellation>>([]);
|
||||
|
||||
async function loadData() {
|
||||
const tempConstellations = JSON.parse(JSON.stringify(props.modelValue));
|
||||
for (const constellation of tempConstellations) {
|
||||
if (constellation.icon.startsWith("blob:")) return;
|
||||
constellation.icon = await saveImgLocal(constellation.icon);
|
||||
}
|
||||
constellations.value = tempConstellations;
|
||||
}
|
||||
|
||||
onMounted(async () => await loadData());
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
async () => {
|
||||
for (const constellation of constellations.value) {
|
||||
if (constellation.icon.startsWith("blob:")) {
|
||||
URL.revokeObjectURL(constellation.icon);
|
||||
}
|
||||
}
|
||||
await loadData();
|
||||
},
|
||||
);
|
||||
onUnmounted(() => {
|
||||
for (const constellation of constellations.value) {
|
||||
if (constellation.icon.startsWith("blob:")) {
|
||||
URL.revokeObjectURL(constellation.icon);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.duc-dolb-box {
|
||||
@@ -75,6 +45,7 @@ onUnmounted(() => {
|
||||
|
||||
.duc-dolb-lock {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
@@ -88,9 +59,20 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.duc-dolb-icon {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 5px;
|
||||
border-radius: 50%;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,54 +2,24 @@
|
||||
<div class="duc-dort-box">
|
||||
<div
|
||||
:title="talent.name"
|
||||
v-for="talent in talents"
|
||||
v-for="talent in props.modelValue"
|
||||
:key="talent.skill_id"
|
||||
class="duc-dort-item"
|
||||
>
|
||||
<span>{{ talent.name }}</span>
|
||||
<img :src="talent.icon" alt="talent" />
|
||||
<div class="duc-dort-icon">
|
||||
<TMiImg :ori="true" :src="talent.icon" alt="talent" />
|
||||
</div>
|
||||
<span>Lv.{{ talent.level === 0 ? 1 : talent.level }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, shallowRef, watch } from "vue";
|
||||
|
||||
import { saveImgLocal } from "@/utils/TGShare.js";
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
type DucDetailOrtProps = { modelValue: Array<TGApp.Game.Avatar.Skill> };
|
||||
|
||||
const props = defineProps<DucDetailOrtProps>();
|
||||
const talents = shallowRef<Array<TGApp.Game.Avatar.Skill>>([]);
|
||||
|
||||
async function loadData(): Promise<void> {
|
||||
const tempTalent = JSON.parse(JSON.stringify(props.modelValue));
|
||||
for (const talent of tempTalent) {
|
||||
if (talent.icon.startsWith("blob:")) return;
|
||||
talent.icon = await saveImgLocal(talent.icon);
|
||||
}
|
||||
talents.value = tempTalent;
|
||||
}
|
||||
|
||||
onMounted(async () => await loadData());
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
async () => {
|
||||
for (const talent of talents.value) {
|
||||
if (talent.icon.startsWith("blob:")) {
|
||||
URL.revokeObjectURL(talent.icon);
|
||||
}
|
||||
}
|
||||
await loadData();
|
||||
},
|
||||
);
|
||||
onUnmounted(() => {
|
||||
for (const talent of talents.value) {
|
||||
if (talent.icon.startsWith("blob:")) {
|
||||
URL.revokeObjectURL(talent.icon);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.duc-dort-box {
|
||||
@@ -61,17 +31,28 @@ onUnmounted(() => {
|
||||
.duc-dort-item {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
column-gap: 10px;
|
||||
column-gap: 8px;
|
||||
}
|
||||
|
||||
.duc-dort-item img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 5px;
|
||||
.duc-dort-icon {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px;
|
||||
border-radius: 50%;
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
backdrop-filter: blur(5px);
|
||||
background: rgba(0 0 0 /40%);
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.duc-dort-item span {
|
||||
@@ -83,9 +64,4 @@ onUnmounted(() => {
|
||||
font-size: 16px;
|
||||
text-shadow: 0 0 5px rgba(0 0 0/40%);
|
||||
}
|
||||
|
||||
.duc-dort-item :nth-last-child(1) {
|
||||
width: 48px;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<img :src="`/icon/bg/${props.modelValue.rarity}-Star.webp`" alt="bg" />
|
||||
</div>
|
||||
<div v-if="props.modelValue" class="duc-dr-icon">
|
||||
<img :src="props.modelValue.icon" alt="relic" />
|
||||
<TMiImg :ori="true" :src="props.modelValue.icon" alt="relic" />
|
||||
</div>
|
||||
<div v-if="props.modelValue !== false" class="duc-dr-level">
|
||||
{{ props.modelValue.level }}
|
||||
@@ -15,6 +15,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import { computed } from "vue";
|
||||
|
||||
type ducDetailRelicProps = { modelValue: TGApp.Game.Avatar.Relic | false; pos: number };
|
||||
@@ -61,8 +62,11 @@ const relicBg = computed<string>(() => {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.duc-dr-icon img {
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<template>
|
||||
<div class="tuc-dc-box">
|
||||
<div v-if="!modelValue.is_actived" class="tuc-dc-lock">
|
||||
<v-icon color="white"> mdi-lock </v-icon>
|
||||
<v-icon color="white"> mdi-lock</v-icon>
|
||||
</div>
|
||||
<div class="tuc-dc-icon">
|
||||
<img :src="modelValue.icon" alt="constellation" />
|
||||
<TMiImg :ori="true" :src="modelValue.icon" alt="constellation" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
defineProps<{ modelValue: TGApp.Game.Avatar.Constellation }>();
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
@@ -34,8 +36,11 @@ defineProps<{ modelValue: TGApp.Game.Avatar.Constellation }>();
|
||||
}
|
||||
|
||||
.tuc-dc-icon {
|
||||
display: flex;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px;
|
||||
border: 1px solid rgb(0 0 0/20%);
|
||||
border-radius: 50%;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<div class="tuc-do-box">
|
||||
<img :src="bg" alt="role" class="tuc-do-bg" />
|
||||
<div class="tuc-do-bg">
|
||||
<TMiImg :ori="true" :src="bg" alt="role" />
|
||||
</div>
|
||||
<div class="tuc-do-show">
|
||||
<div class="tuc-do-main">
|
||||
<div class="tuc-do-left">
|
||||
@@ -72,6 +74,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import { computed, onMounted, ref, shallowRef, watch } from "vue";
|
||||
|
||||
import TucDetailConstellation from "./tuc-detail-constellation.vue";
|
||||
@@ -160,12 +163,21 @@ function switchBg(): void {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 5px;
|
||||
margin: 0 auto;
|
||||
object-fit: v-bind(bgFit);
|
||||
transform: translateY(v-bind(bgTransY));
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.tuc-do-costume {
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
<img :src="`/icon/bg/${modelValue.rarity}-Star.webp`" alt="bg" />
|
||||
</div>
|
||||
<div v-if="modelValue" class="tuc-dr-icon">
|
||||
<img :src="modelValue.icon" alt="relic" />
|
||||
<TMiImg :ori="true" :src="modelValue.icon" alt="relic" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
|
||||
defineProps<{ modelValue: TGApp.Game.Avatar.Relic | false; pos: number }>();
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
@@ -45,8 +47,11 @@ defineProps<{ modelValue: TGApp.Game.Avatar.Relic | false; pos: number }>();
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tuc-dr-icon img {
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
<div class="tp-avatar-box">
|
||||
<div v-if="props.position === 'right'" class="tpa-text">
|
||||
<div>{{ props.data.nickname }}</div>
|
||||
<div :title="getAuthorDesc()">{{ getAuthorDesc() }}</div>
|
||||
<div :title="authorDesc">{{ authorDesc }}</div>
|
||||
</div>
|
||||
<div class="tpa-img">
|
||||
<img :src="avatarUrl" alt="avatar" class="tpa-icon" v-if="avatarUrl" />
|
||||
<img
|
||||
<TMiImg :ori="true" :src="props.data.avatar_url" alt="avatar" class="tpa-icon" />
|
||||
<TMiImg
|
||||
:ori="true"
|
||||
:src="props.data.pendant"
|
||||
alt="pendant"
|
||||
class="tpa-pendant"
|
||||
@@ -23,36 +24,22 @@
|
||||
</div>
|
||||
<div v-if="props.position === 'left'" class="tpa-text">
|
||||
<div>{{ props.data.nickname }}</div>
|
||||
<div :title="getAuthorDesc()">{{ getAuthorDesc() }}</div>
|
||||
<div :title="authorDesc">{{ authorDesc }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, onUnmounted, ref } from "vue";
|
||||
|
||||
import { useAppStore } from "@/store/modules/app.js";
|
||||
import { saveImgLocal } from "@/utils/TGShare.js";
|
||||
import TMiImg from "@comp/app/t-mi-img.vue";
|
||||
import { computed } from "vue";
|
||||
|
||||
type TpAvatarProps = { data: TGApp.Plugins.Mys.User.Post; position: "left" | "right" };
|
||||
|
||||
const props = defineProps<TpAvatarProps>();
|
||||
const appStore = useAppStore();
|
||||
const avatarUrl = ref<string>();
|
||||
const pendantUrl = ref<string>();
|
||||
|
||||
onMounted(async () => {
|
||||
avatarUrl.value = await saveImgLocal(appStore.getImageUrl(props.data.avatar_url));
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (avatarUrl.value) URL.revokeObjectURL(avatarUrl.value);
|
||||
if (pendantUrl.value) URL.revokeObjectURL(pendantUrl.value);
|
||||
});
|
||||
|
||||
function getAuthorDesc(): string {
|
||||
const authorDesc = computed<string>(() => {
|
||||
if (props.data.certification.label !== "") return props.data.certification.label;
|
||||
return props.data.introduce;
|
||||
}
|
||||
});
|
||||
|
||||
const levelColor = computed<string>(() => {
|
||||
const level = props.data.level_exp.level;
|
||||
|
||||
Reference in New Issue
Block a user