Compare commits
2
Commits
cbeb0737ef
...
734f4aed05
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
734f4aed05 | ||
|
|
36f2a45c5e |
No files matched your search
@@ -35,7 +35,7 @@ const showBadges = computed(() => props.group.name === "题单和比赛" && !!pr
|
||||
:to="{ name: 'problemset', params: { problemSetId: b.problemSet.id } }"
|
||||
class="badge"
|
||||
>
|
||||
<AchievementIcon :icon="b.badge.icon" :size="32" />
|
||||
<AchievementIcon :icon="b.badge.icon" :size="24" />
|
||||
<span>{{ b.badge.name }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
@@ -89,24 +89,19 @@ h3 small {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 奖章名最长 9 个字(「有趣和无趣的观察者」),竖排在格子里放不下,横排写全 */
|
||||
.badge {
|
||||
width: 72px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
color: v-bind("theme.textColor1");
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.badge span {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
gap: 6px;
|
||||
height: 34px;
|
||||
padding: 0 10px 0 6px;
|
||||
border-radius: 6px;
|
||||
font-size: var(--oj-fs-sec);
|
||||
white-space: nowrap;
|
||||
color: v-bind("theme.textColor1");
|
||||
background: v-bind("theme.actionColor");
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.compact {
|
||||
|
||||
@@ -24,6 +24,14 @@ const color = computed(() => RARITY_COLOR[props.rarity])
|
||||
const r = computed(() => props.size / 2 + 3)
|
||||
const box = computed(() => props.size + 8)
|
||||
const circumference = computed(() => 2 * Math.PI * r.value)
|
||||
// 底色都是半透明的,下面垫一层卡片底色 —— 不然成就线的进度线会从徽章中间透出来
|
||||
const onBg = computed(
|
||||
() => `linear-gradient(${color.value}26, ${color.value}26), ${theme.value.cardColor}`,
|
||||
)
|
||||
const offBg = computed(
|
||||
() =>
|
||||
`linear-gradient(${theme.value.actionColor}, ${theme.value.actionColor}), ${theme.value.cardColor}`,
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -55,7 +63,7 @@ const circumference = computed(() => 2 * Math.PI * r.value)
|
||||
v-else
|
||||
class="disc"
|
||||
:class="state"
|
||||
:style="state === 'on' ? { borderColor: color, background: `${color}26` } : undefined"
|
||||
:style="state === 'on' ? { borderColor: color, background: onBg } : undefined"
|
||||
>
|
||||
<AchievementIcon :icon="icon" :size="Math.round(size * 0.56)" />
|
||||
</span>
|
||||
@@ -98,7 +106,7 @@ const circumference = computed(() => 2 * Math.PI * r.value)
|
||||
|
||||
.disc.off {
|
||||
border-color: v-bind("theme.borderColor");
|
||||
background: v-bind("theme.actionColor");
|
||||
background: v-bind(offBg);
|
||||
}
|
||||
|
||||
.disc.off :deep(svg),
|
||||
@@ -110,7 +118,7 @@ const circumference = computed(() => 2 * Math.PI * r.value)
|
||||
|
||||
.disc.unknown {
|
||||
border: 1.5px dashed v-bind("theme.borderColor");
|
||||
background: v-bind("theme.actionColor");
|
||||
background: v-bind(offBg);
|
||||
color: v-bind("theme.textColor3");
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@ import { useRarityColor } from "shared/composables/rarity"
|
||||
import type { Near } from "../series"
|
||||
import Medal from "./Medal.vue"
|
||||
|
||||
/** 「快拿到了」:每个只说还差什么,进度条底下是现在几 / 要几、本班几人有 */
|
||||
defineProps<{ items: Near[]; compact?: boolean }>()
|
||||
/**
|
||||
* 「快拿到了」:每个只说还差什么,进度条底下是现在几 / 要几、本班几人有。
|
||||
* `wide`:旁边没有「本班」(没有班级的号)时三个横着排,占满整宽
|
||||
*/
|
||||
defineProps<{ items: Near[]; compact?: boolean; wide?: boolean }>()
|
||||
|
||||
const theme = useThemeVars()
|
||||
const rarityText = useRarityColor()
|
||||
@@ -22,38 +25,40 @@ const percent = (item: Near) => Math.round((item.series.value / item.achievement
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="card" :class="{ compact }">
|
||||
<section class="card" :class="{ compact, wide }">
|
||||
<h3>快拿到了</h3>
|
||||
<div v-for="item in items" :key="item.achievement.id" class="item">
|
||||
<Medal
|
||||
:icon="item.achievement.icon"
|
||||
:rarity="item.achievement.rarity"
|
||||
:size="compact ? 44 : 48"
|
||||
state="off"
|
||||
:ring="item.series.value / item.achievement.threshold!"
|
||||
/>
|
||||
<div class="body">
|
||||
<div class="head">
|
||||
<b>{{ item.achievement.name }}</b>
|
||||
<span class="tag" :style="{ color: rarityText[item.achievement.rarity] }">
|
||||
{{ RARITY_LABEL[item.achievement.rarity] }}
|
||||
</span>
|
||||
<span class="remain">{{ item.remain }}</span>
|
||||
</div>
|
||||
<n-progress
|
||||
type="line"
|
||||
:percentage="percent(item)"
|
||||
:height="6"
|
||||
:show-indicator="false"
|
||||
:color="theme.primaryColor"
|
||||
:border-radius="3"
|
||||
:fill-border-radius="3"
|
||||
<div class="list">
|
||||
<div v-for="item in items" :key="item.achievement.id" class="item">
|
||||
<Medal
|
||||
:icon="item.achievement.icon"
|
||||
:rarity="item.achievement.rarity"
|
||||
:size="compact ? 44 : 48"
|
||||
state="off"
|
||||
:ring="item.series.value / item.achievement.threshold!"
|
||||
/>
|
||||
<div class="foot">
|
||||
<span>{{ now(item) }}</span>
|
||||
<span v-if="item.achievement.classHolders !== null">
|
||||
本班 {{ item.achievement.classHolders }} 人有
|
||||
</span>
|
||||
<div class="body">
|
||||
<div class="head">
|
||||
<b>{{ item.achievement.name }}</b>
|
||||
<span class="tag" :style="{ color: rarityText[item.achievement.rarity] }">
|
||||
{{ RARITY_LABEL[item.achievement.rarity] }}
|
||||
</span>
|
||||
<span class="remain">{{ item.remain }}</span>
|
||||
</div>
|
||||
<n-progress
|
||||
type="line"
|
||||
:percentage="percent(item)"
|
||||
:height="6"
|
||||
:show-indicator="false"
|
||||
:color="theme.primaryColor"
|
||||
:border-radius="3"
|
||||
:fill-border-radius="3"
|
||||
/>
|
||||
<div class="foot">
|
||||
<span>{{ now(item) }}</span>
|
||||
<span v-if="item.achievement.classHolders !== null">
|
||||
本班 {{ item.achievement.classHolders }} 人有
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -116,6 +121,20 @@ h3 {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.wide {
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
|
||||
.wide .list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.wide .item {
|
||||
border-top: 1px solid v-bind("theme.dividerColor");
|
||||
}
|
||||
|
||||
/* 手机:「还差什么」换到名字下面一行 */
|
||||
.compact {
|
||||
padding: 12px 14px 4px;
|
||||
|
||||
@@ -85,9 +85,14 @@ watch(name, load)
|
||||
<router-link v-if="other" to="/achievement" class="mine">看我的 ›</router-link>
|
||||
</div>
|
||||
|
||||
<!-- 只有一张(老师没有班级、或看别人)时也只占半边,别把进度条拉得一屏宽 -->
|
||||
<div v-if="near.length || data.classBoard" class="top">
|
||||
<NearCard v-if="near.length" :items="near" :compact="!isDesktop" />
|
||||
<!-- 没有班级(老师、自己注册的号)就没有「本班」,「快拿到了」三个横排占满整宽 -->
|
||||
<div v-if="near.length || data.classBoard" class="top" :class="{ alone: !data.classBoard }">
|
||||
<NearCard
|
||||
v-if="near.length"
|
||||
:items="near"
|
||||
:compact="!isDesktop"
|
||||
:wide="isDesktop && !data.classBoard"
|
||||
/>
|
||||
<ClassCard
|
||||
v-if="data.classBoard"
|
||||
:board="data.classBoard"
|
||||
@@ -177,6 +182,10 @@ h2 {
|
||||
margin-bottom: var(--oj-gap);
|
||||
}
|
||||
|
||||
.top.alone {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
||||
Reference in new issue
Block a user