🚸 成就系列未完成/完成区分

This commit is contained in:
目棃
2025-03-31 15:24:02 +08:00
parent d79de499cf
commit 40d46f41c3
3 changed files with 67 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
<template>
<v-list class="top-nc-box" @click="emit('selected', props.data)">
<v-list class="top-nc-box" @click="emit('selected', props.data)" :class="{ grey: isGrey }">
<v-list-item :title="props.data.name">
<template #subtitle>
<span class="desc" :title="props.data.desc">{{ props.data.desc }}</span>
@@ -17,7 +17,7 @@
<script lang="ts" setup>
import { computed } from "vue";
type TopNameCardProps = { data: TGApp.App.NameCard.Item };
type TopNameCardProps = { data: TGApp.App.NameCard.Item; finish?: boolean };
type TopNameCardEmits = (e: "selected", v: TGApp.App.NameCard.Item) => void;
const props = defineProps<TopNameCardProps>();
@@ -27,6 +27,10 @@ const bgImage = computed<string>(() => {
if (props.data.name === "原神·印象") return "none;";
return `url("/WIKI/nameCard/bg/${props.data.name}.webp")`;
});
const isGrey = computed<boolean>(() => {
if (props.finish === undefined) return false;
return !props.finish;
});
</script>
<style lang="scss" scoped>
@use "@styles/github.styles.scss" as github-styles;
@@ -45,6 +49,10 @@ const bgImage = computed<string>(() => {
background-repeat: no-repeat;
cursor: pointer;
font-family: var(--font-title);
&.grey {
filter: grayscale(1);
}
}
.dark .top-nc-box {

View File

@@ -1,7 +1,7 @@
<template>
<div class="tua-al-container">
<div v-if="ncData !== undefined">
<TopNameCard :data="ncData" @selected="showNc = true" />
<TopNameCard :data="ncData" @selected="showNc = true" :finish="isFinish" />
</div>
<v-virtual-scroll :items="renderAchi" :item-height="60" class="tua-al-list">
<template #default="{ item }">
@@ -57,6 +57,7 @@ const emits = defineEmits<TuaAchiListEmits>();
const nameCard = ref<string>();
const showNc = ref<boolean>(false);
const showOverlay = ref<boolean>(false);
const isFinish = ref<boolean>(false);
const ncData = shallowRef<TGApp.App.NameCard.Item>();
const achievements = shallowRef<Array<TGApp.Sqlite.Achievement.RenderAchi>>([]);
const selectedAchi = shallowRef<TGApp.Sqlite.Achievement.RenderAchi>();
@@ -90,6 +91,8 @@ async function searchAchi(): Promise<void> {
async function loadAchi(): Promise<void> {
if (props.isSearch) return;
achievements.value = await TSUserAchi.getAchievements(props.uid, props.series);
const ov = await TSUserAchi.getOverview(props.uid, props.series);
isFinish.value = ov.fin === ov.total;
if (!selectedAchi.value && achievements.value.length > 0) {
selectedAchi.value = achievements.value[0];
} else if (selectedAchi.value !== undefined && achievements.value.length > 0) {
@@ -181,4 +184,8 @@ function switchAchiInfo(next: boolean): void {
.dark .card-arrow {
filter: invert(11%) sepia(73%) saturate(11%) hue-rotate(139deg) brightness(97%) contrast(81%);
}
.unfinish {
filter: grayscale(1);
}
</style>

View File

@@ -3,16 +3,26 @@
class="tuas-card"
@click="selectSeries"
v-if="data"
:class="{ 'tuas-selected': props.cur === props.series }"
:class="{
'tuas-selected': props.cur === props.series,
'tuas-finish': showCard,
}"
>
<div class="tuas-version">v{{ data.version }}</div>
<div class="tuas-reward" v-if="showCard" :title="data.card">
<img
:class="{ finish: progress === 100 }"
alt="card"
:src="`/WIKI/nameCard/bg/${data.card}.webp`"
/>
</div>
<div class="tuas-icon">
<img alt="icon" :src="`/icon/achievement/${data.icon}.webp`" />
<v-progress-circular
class="progress"
bg-color="var(--tgc-od-white)"
color="var(--tgc-yellow-2)"
:model-value="`${(overview.fin / overview.total) * 100}`"
:model-value="progress"
/>
</div>
<div class="tuas-content">
@@ -32,6 +42,7 @@ import { AppAchievementSeriesData } from "@/data/index.js";
type TuaSeriesProps = { uid: number; series: number; cur: number };
type TuaSeriesEmits = (e: "selectSeries", v: number) => void;
let achiListener: UnlistenFn | null = null;
const props = defineProps<TuaSeriesProps>();
const emits = defineEmits<TuaSeriesEmits>();
@@ -39,7 +50,14 @@ const overview = shallowRef<TGApp.Sqlite.Achievement.Overview>({ fin: 0, total:
const data = computed<TGApp.App.Achievement.Series | undefined>(() =>
AppAchievementSeriesData.find((s) => s.id === props.series),
);
let achiListener: UnlistenFn | null = null;
const progress = computed<number>(() => {
if (overview.value.total === 0) return 0;
return Math.round((overview.value.fin / overview.value.total) * 100);
});
const showCard = computed<boolean>(() => {
if (data.value === undefined) return false;
return data.value.card !== "";
});
onMounted(async () => {
await refreshOverview();
@@ -97,6 +115,11 @@ function selectSeries(): void {
&.tuas-selected {
background: var(--box-bg-1);
}
&.tuas-finish {
border-top-right-radius: 30px;
border-bottom-right-radius: 30px;
}
}
.dark .tuas-card {
@@ -120,6 +143,26 @@ function selectSeries(): void {
font-family: var(--font-title);
font-size: 10px;
text-align: center;
z-index: 3;
}
.tuas-reward {
position: absolute;
top: -1px;
right: -2px;
height: 62px;
z-index: 0;
img {
height: 100%;
object-fit: contain;
opacity: 0.3;
filter: grayscale(1);
&.finish {
filter: unset;
}
}
}
.tuas-icon {
@@ -131,6 +174,7 @@ function selectSeries(): void {
border-radius: 50%;
box-sizing: border-box;
background: var(--tgc-dark-7);
z-index: 1;
img {
width: 100%;
@@ -148,6 +192,8 @@ function selectSeries(): void {
}
.tuas-content {
position: relative;
z-index: 1;
display: flex;
width: 100%;
flex-flow: column wrap;