feat: add gallery pagination, dynamic progress colors, and UX fixes
- Replace infinite scroll with page-based navigation in gallery - Add dynamic progress color (blue→amber→red) in encyclopedia - Fix timeline not returning to realtime when closing in archive mode - Simplify image detail modal close button styling - Add web-design-reviewer skill
This commit is contained in:
@@ -20,9 +20,25 @@ const rarityMeta = {
|
||||
rare: { label: '罕见', chip: 'bg-rose-100 text-rose-700 border-rose-200', glow: 'from-rose-100 to-white' },
|
||||
} satisfies Record<CloudType['rarity'], { label: string; chip: string; glow: string }>
|
||||
|
||||
function lerpHex(a: string, b: string, t: number) {
|
||||
const ah = parseInt(a.slice(1), 16)
|
||||
const bh = parseInt(b.slice(1), 16)
|
||||
const r = Math.round(((ah >> 16) & 0xff) + (((bh >> 16) & 0xff) - ((ah >> 16) & 0xff)) * t)
|
||||
const g = Math.round(((ah >> 8) & 0xff) + (((bh >> 8) & 0xff) - ((ah >> 8) & 0xff)) * t)
|
||||
const bv = Math.round((ah & 0xff) + ((bh & 0xff) - (ah & 0xff)) * t)
|
||||
return `#${((r << 16) | (g << 8) | bv).toString(16).padStart(6, '0')}`
|
||||
}
|
||||
|
||||
function progressColor(percent: number) {
|
||||
const t = Math.min(1, Math.max(0, percent / 100))
|
||||
if (t <= 0.5) return lerpHex('#0ea5e9', '#f59e0b', t * 2)
|
||||
return lerpHex('#f59e0b', '#ef4444', (t - 0.5) * 2)
|
||||
}
|
||||
|
||||
const totalTypes = computed(() => encyclopediaStore.cloudTypes.length || 10)
|
||||
const unlockedCount = computed(() => (authStore.isLoggedIn ? encyclopediaStore.unlockedCount : 0))
|
||||
const progressText = computed(() => `${unlockedCount.value}/${totalTypes.value}`)
|
||||
const currentProgressColor = computed(() => progressColor(authStore.isLoggedIn ? encyclopediaStore.unlockPercent : 0))
|
||||
|
||||
function isUnlocked(cloudTypeId: number) {
|
||||
return authStore.isLoggedIn && encyclopediaStore.isUnlocked(cloudTypeId)
|
||||
@@ -80,9 +96,12 @@ onMounted(async () => {
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-slate-500">当前进度</p>
|
||||
<p class="mt-1 text-3xl font-bold text-slate-900">{{ progressText }}</p>
|
||||
<p class="mt-1 text-3xl font-bold" :style="{ color: currentProgressColor }">{{ progressText }}</p>
|
||||
</div>
|
||||
<div class="flex h-16 w-16 items-center justify-center border border-slate-900 bg-slate-900 text-xl font-semibold text-white">
|
||||
<div
|
||||
class="flex h-16 w-16 items-center justify-center border text-xl font-semibold text-white transition-colors duration-500"
|
||||
:style="{ backgroundColor: currentProgressColor, borderColor: currentProgressColor }"
|
||||
>
|
||||
{{ authStore.isLoggedIn ? encyclopediaStore.unlockPercent : 0 }}%
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,8 +111,9 @@ onMounted(async () => {
|
||||
type="line"
|
||||
:show-indicator="false"
|
||||
:percentage="authStore.isLoggedIn ? encyclopediaStore.unlockPercent : 0"
|
||||
color="{stops:['#0ea5e9','#f59e0b']}"
|
||||
:color="{ stops: ['#0ea5e9', currentProgressColor] }"
|
||||
:height="12"
|
||||
rail-color="#e2e8f0"
|
||||
/>
|
||||
|
||||
<p class="mt-4 text-sm text-slate-500">
|
||||
|
||||
Reference in New Issue
Block a user