Skip to content

Commit b70e7f3

Browse files
committed
improvement(wrapped): 年度总结仅保留 Modern 主题
- 移除复古主题切换入口(控制面板/左上角按钮)与 Win98/CRT 相关 UI - 简化 useWrappedTheme:仅保留 off(Modern),历史主题值自动回退 - Modern 下也展示 LuckyBlock 占位图,并同步更新 README 说明
1 parent 1ad2c38 commit b70e7f3

5 files changed

Lines changed: 22 additions & 227 deletions

File tree

README.md

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,26 +65,18 @@
6565

6666
## 年度总结
6767

68-
年度总结现在支持 3 种不同风格(style1、style2、style3)。如果你对某个风格有更好的修改建议,或有新风格的点子,欢迎到 Issue 区反馈:https://github.com/LifeArchiveProject/WeChatDataAnalysis/issues
68+
年度总结目前只保留「现代(Modern)」风格。如果你对年度总结有更好的修改建议,欢迎到 Issue 区反馈:https://github.com/LifeArchiveProject/WeChatDataAnalysis/issues
6969

70-
> ⚠️ **提醒**:年度总结目前还不是最终版本,后续还会增加新总结或新风格
70+
> ⚠️ **提醒**:年度总结目前还不是最终版本,后续还会增加新总结或新内容
7171
7272
也欢迎加入下方 QQ 群一起讨论。
7373

7474
<table>
7575
<tr>
76-
<td align="center"><b>Style 1</b></td>
77-
<td align="center"><b>Style 2</b></td>
76+
<td align="center"><b>Modern</b></td>
7877
</tr>
7978
<tr>
80-
<td><img src="frontend/public/style1.png" alt="年度总结 Style 1" width="400"/></td>
81-
<td><img src="frontend/public/style2.png" alt="年度总结 Style 2" width="400"/></td>
82-
</tr>
83-
<tr>
84-
<td align="center" colspan="2"><b>Style 3</b></td>
85-
</tr>
86-
<tr>
87-
<td align="center" colspan="2"><img src="frontend/public/style3.png" alt="年度总结 Style 3" width="400"/></td>
79+
<td align="center"><img src="frontend/public/style1.png" alt="年度总结 Modern" width="400"/></td>
8880
</tr>
8981
</table>
9082

frontend/components/wrapped/cards/Card03ReplySpeed.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
@error="onShownAvatarError"
116116
/>
117117
<img
118-
v-else-if="isGameboy && phase === 'idle'"
118+
v-else-if="(isGameboy || isModern) && phase === 'idle'"
119119
src="/assets/images/LuckyBlock.png"
120120
class="w-full h-full object-contain"
121121
alt="Lucky Block"
@@ -258,6 +258,7 @@ const props = defineProps({
258258
259259
const { theme } = useWrappedTheme()
260260
const isGameboy = computed(() => theme.value === 'gameboy')
261+
const isModern = computed(() => theme.value === 'off')
261262
const isRetro = computed(() => isGameboy.value)
262263
263264
const nfInt = new Intl.NumberFormat('zh-CN', { maximumFractionDigits: 0 })

frontend/components/wrapped/shared/WrappedControls.vue

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
</div>
4040

4141
<div class="flex gap-2 items-end">
42-
<WrappedThemeSwitcher />
4342
<button
4443
class="inline-flex items-center justify-center px-4 py-2 rounded-lg bg-[#07C160] text-white text-sm wrapped-label hover:bg-[#06AD56] disabled:opacity-60 disabled:cursor-not-allowed transition controls-btn"
4544
:disabled="loading"
@@ -83,73 +82,3 @@ const yearOptions = computed(() => {
8382
return years
8483
})
8584
</script>
86-
87-
<style scoped>
88-
/* 复古模式 - 控制面板样式 */
89-
.wrapped-retro .controls-panel {
90-
background-color: var(--wrapped-card-bg);
91-
border-color: var(--wrapped-border);
92-
}
93-
94-
.wrapped-retro .controls-label {
95-
color: var(--wrapped-text-secondary);
96-
}
97-
98-
.wrapped-retro .controls-select {
99-
background-color: var(--wrapped-bg);
100-
border-color: var(--wrapped-border);
101-
color: var(--wrapped-text);
102-
}
103-
104-
.wrapped-retro .controls-select:focus {
105-
--tw-ring-color: var(--wrapped-accent);
106-
}
107-
108-
.wrapped-retro .controls-checkbox {
109-
border-color: var(--wrapped-border);
110-
color: var(--wrapped-accent);
111-
}
112-
113-
.wrapped-retro .controls-checkbox:focus {
114-
--tw-ring-color: var(--wrapped-accent);
115-
}
116-
117-
.wrapped-retro .controls-hint {
118-
color: var(--wrapped-text-secondary);
119-
}
120-
121-
.wrapped-retro .controls-warning {
122-
color: var(--wrapped-warning);
123-
}
124-
125-
.wrapped-retro .controls-btn {
126-
background-color: var(--wrapped-accent);
127-
color: var(--wrapped-bg);
128-
}
129-
130-
.wrapped-retro .controls-btn:hover:not(:disabled) {
131-
filter: brightness(1.1);
132-
}
133-
134-
/* Win98 特殊样式 */
135-
.wrapped-theme-win98 .controls-panel {
136-
border-radius: 0;
137-
border: 1px solid #808080;
138-
background: #c0c0c0;
139-
box-shadow:
140-
inset 1px 1px 0 #ffffff,
141-
inset -1px -1px 0 #000000;
142-
}
143-
144-
.wrapped-theme-win98 .controls-select {
145-
border-radius: 0;
146-
}
147-
148-
.wrapped-theme-win98 .controls-btn {
149-
border-radius: 0;
150-
}
151-
152-
.wrapped-theme-win98 .controls-warning {
153-
color: #800000;
154-
}
155-
</style>
Lines changed: 11 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,31 @@
11
/**
22
* 年度总结页面主题管理 composable
3-
* 支持三种主题:modern(现代)、gameboy(Game Boy)、win98(Windows 98)
3+
* 仅保留 modern(现代)主题
44
*/
55

6-
const STORAGE_KEY = 'wrapped-theme'
7-
const VALID_THEMES = ['off', 'gameboy', 'win98']
8-
const RETRO_THEMES = new Set(['gameboy'])
9-
106
// 全局响应式状态(跨组件共享)
11-
const theme = ref('off')
12-
let initialized = false
13-
let keyboardInitialized = false
7+
// Note: 历史上曾尝试过 gameboy / win98 等主题,但目前已移除,仅保留 Modern。
8+
const theme = ref('off') // off === Modern
149

1510
export function useWrappedTheme() {
16-
// 初始化:从 localStorage 读取(仅执行一次)
17-
const initTheme = () => {
18-
if (initialized || !import.meta.client) return
19-
const saved = localStorage.getItem(STORAGE_KEY)
20-
if (saved && VALID_THEMES.includes(saved)) {
21-
theme.value = saved
22-
}
23-
initialized = true
24-
}
25-
26-
// 设置主题
2711
const setTheme = (newTheme) => {
28-
if (!VALID_THEMES.includes(newTheme)) {
29-
console.warn(`Invalid theme: ${newTheme}`)
30-
return
12+
// Only keep Modern.
13+
if (newTheme !== 'off') {
14+
console.warn(`Wrapped theme '${newTheme}' has been removed; falling back to Modern.`)
3115
}
32-
theme.value = newTheme
33-
if (import.meta.client) {
34-
localStorage.setItem(STORAGE_KEY, newTheme)
35-
}
36-
}
37-
38-
// 切换到下一个主题(循环)
39-
const cycleTheme = () => {
40-
const currentIndex = VALID_THEMES.indexOf(theme.value)
41-
const nextIndex = (currentIndex + 1) % VALID_THEMES.length
42-
setTheme(VALID_THEMES[nextIndex])
16+
theme.value = 'off'
4317
}
4418

45-
// 计算属性:是否为复古模式(非 off)
46-
const isRetro = computed(() => theme.value !== 'off')
47-
48-
// 计算属性:当前主题的 CSS 类名
49-
const themeClass = computed(() => {
50-
if (theme.value === 'off') return ''
51-
// Note: not every non-modern theme is "retro pixel/CRT".
52-
// Keep wrapped-retro for themes that rely on pixel/CRT shared styles.
53-
const base = RETRO_THEMES.has(theme.value) ? 'wrapped-retro ' : ''
54-
return `${base}wrapped-theme-${theme.value}`
55-
})
56-
57-
// 计算属性:主题显示名称
58-
const themeName = computed(() => {
59-
const names = {
60-
off: 'Modern',
61-
gameboy: 'Game Boy',
62-
win98: 'Windows 98'
63-
}
64-
return names[theme.value] || 'Modern'
65-
})
66-
67-
// 全局 F1-F3 快捷键切换主题(仅初始化一次)
68-
const initKeyboardShortcuts = () => {
69-
if (keyboardInitialized || !import.meta.client) return
70-
keyboardInitialized = true
71-
72-
const handleKeydown = (e) => {
73-
// 检查是否在可编辑元素中
74-
const el = e.target
75-
if (el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.tagName === 'SELECT' || el.isContentEditable)) {
76-
return
77-
}
78-
79-
if (e.key === 'F1') {
80-
e.preventDefault()
81-
setTheme('off')
82-
} else if (e.key === 'F2') {
83-
e.preventDefault()
84-
setTheme('gameboy')
85-
} else if (e.key === 'F3') {
86-
e.preventDefault()
87-
setTheme('win98')
88-
}
89-
}
90-
91-
window.addEventListener('keydown', handleKeydown)
92-
}
19+
const cycleTheme = () => setTheme('off')
9320

94-
// 客户端挂载后再初始化:避免 SSR 与首帧 hydration 不一致
95-
onMounted(() => {
96-
initTheme()
97-
initKeyboardShortcuts()
98-
})
21+
const isRetro = computed(() => false)
22+
const themeClass = computed(() => '')
9923

10024
return {
10125
theme: readonly(theme),
10226
setTheme,
10327
cycleTheme,
10428
isRetro,
105-
themeClass,
106-
themeName,
107-
VALID_THEMES
29+
themeClass
10830
}
10931
}

frontend/pages/wrapped/index.vue

Lines changed: 5 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
>
88
<!-- PPT 风格:单张卡片占据全页面,鼠标滚轮切换 -->
99
<WrappedDeckBackground />
10-
<!-- CRT 叠加层仅用于“像素屏”类主题,Win98 等桌面 GUI 主题不应开启 -->
11-
<WrappedCRTOverlay v-if="theme === 'gameboy'" />
1210

13-
<!-- 左上角:刷新 + 复古模式开关 -->
11+
<!-- 左上角:返回 + 刷新 -->
1412
<div class="absolute top-6 left-6 z-20 select-none">
1513
<div class="flex items-center gap-3">
1614
<button
@@ -59,24 +57,6 @@
5957
</svg>
6058
</button>
6159

62-
<button
63-
type="button"
64-
class="pointer-events-auto inline-flex items-center justify-center w-9 h-9 rounded-full bg-transparent transition disabled:opacity-60 disabled:cursor-not-allowed focus:outline-none focus-visible:ring-2 focus-visible:ring-[#07C160]/30"
65-
:class="isRetro ? 'text-[#07C160] hover:bg-[#07C160]/10' : 'text-[#00000055] hover:bg-[#000000]/5'"
66-
:aria-pressed="isRetro ? 'true' : 'false'"
67-
:aria-label="`复古模式(当前:${theme === 'off' ? 'Modern' : theme.toUpperCase()})`"
68-
:title="`复古模式:${theme === 'off' ? 'Modern' : theme.toUpperCase()}(点击切换)`"
69-
@click="cycleTheme"
70-
>
71-
<img
72-
src="/assets/images/wechat-audio-dark.png"
73-
class="w-4 h-4 transition"
74-
:style="{ filter: isRetro ? 'none' : 'grayscale(1)', opacity: isRetro ? '1' : '0.55' }"
75-
alt=""
76-
aria-hidden="true"
77-
draggable="false"
78-
/>
79-
</button>
8060
</div>
8161

8262
<div v-if="error" class="mt-2 pointer-events-auto bg-white/90 backdrop-blur rounded-xl border border-red-200 px-3 py-2">
@@ -205,11 +185,6 @@
205185
</section>
206186
</div>
207187

208-
<!-- Win98:底部任务栏 -->
209-
<WrappedWin98Taskbar
210-
v-if="theme === 'win98'"
211-
:title="taskbarTitle"
212-
/>
213188
</div>
214189
</template>
215190

@@ -229,8 +204,8 @@ const year = ref(Number(route.query?.year) || new Date().getFullYear())
229204
// 分享视图不展示账号信息:默认让后端自动选择;需要指定时可用 query ?account=wxid_xxx
230205
const account = ref(typeof route.query?.account === 'string' ? route.query.account : '')
231206
232-
// 主题管理:modern / gameboy / win98
233-
const { theme, cycleTheme, isRetro, themeClass } = useWrappedTheme()
207+
// 主题:仅保留 Modern
208+
const { isRetro, themeClass } = useWrappedTheme()
234209
235210
const accounts = ref([])
236211
const accountsLoading = ref(true)
@@ -262,29 +237,14 @@ const wheelAcc = ref(0)
262237
let navUnlockTimer = null
263238
let deckResizeObserver = null
264239
265-
// 各主题的背景颜色
266-
const THEME_BG = {
267-
off: '#F3FFF8', // Modern: 浅绿
268-
gameboy: '#9bbc0f', // Game Boy: 亮绿
269-
win98: '#008080' // Win98: 经典桌面青色
270-
}
271-
272240
const slides = computed(() => {
273241
const cards = Array.isArray(report.value?.cards) ? report.value.cards : []
274242
const out = [{ key: 'cover' }]
275243
for (const c of cards) out.push({ key: `card-${c?.id ?? out.length}` })
276244
return out
277245
})
278246
279-
const taskbarTitle = computed(() => {
280-
if (theme.value !== 'win98') return ''
281-
if (activeIndex.value === 0) return `${year.value} WeChat Wrapped`
282-
const idx = activeIndex.value - 1
283-
const c = report.value?.cards?.[idx]
284-
return String(c?.title || 'WeChat Wrapped')
285-
})
286-
287-
const currentBg = computed(() => THEME_BG[theme.value] || THEME_BG.off)
247+
const currentBg = computed(() => '#F3FFF8')
288248
const deckTrackClass = computed(() => 'z-10')
289249
290250
const applyViewportBg = () => {
@@ -423,11 +383,8 @@ const onTouchEnd = (e) => {
423383
const updateViewport = () => {
424384
const h = Math.round(deckEl.value?.getBoundingClientRect?.().height || deckEl.value?.clientHeight || window.innerHeight || 0)
425385
if (!h) return
426-
// Reserve space for the Win98 taskbar at the bottom.
427-
const offset = theme.value === 'win98' ? 40 : 0
428-
const effective = Math.max(0, h - offset)
429386
// Avoid endless reflows from 1px rounding errors (especially in Electron).
430-
if (Math.abs(viewportHeight.value - effective) > 1) viewportHeight.value = effective
387+
if (Math.abs(viewportHeight.value - h) > 1) viewportHeight.value = h
431388
}
432389
433390
const loadAccounts = async () => {
@@ -592,12 +549,6 @@ onMounted(async () => {
592549
}
593550
})
594551
595-
// Theme switch may change reserved UI space (e.g., Win98 taskbar)
596-
watch(theme, () => {
597-
applyViewportBg()
598-
updateViewport()
599-
})
600-
601552
onBeforeUnmount(() => {
602553
if (import.meta.client) {
603554
document.documentElement.style.backgroundColor = ''

0 commit comments

Comments
 (0)