Skip to content

Commit a47b491

Browse files
committed
improvement(wrapped-ui): 年度总结新增隐私模式开关(昵称/头像/消息/词云可模糊)
- Wrapped 页面右上角新增隐私模式开关,并在 deck 根节点挂载 wrapped-privacy - Tailwind 新增 wrapped-privacy-* 细粒度模糊样式:仅模糊昵称/消息/关键词/头像,hover 可临时显示 - Wrapped 各卡片/可视化统一接入新 class,逐步替换原 privacy-blur 用法(词云/聊天回放/气泡等)
1 parent 3e0c304 commit a47b491

12 files changed

Lines changed: 166 additions & 86 deletions

frontend/assets/css/tailwind.css

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,46 @@
9090
.privacy-blur:hover {
9191
filter: none;
9292
}
93+
94+
/* Wrapped 隐私模式:仅模糊“用户名文本”,头像不模糊(避免把头像也 blur 掉) */
95+
.wrapped-privacy .wrapped-privacy-name {
96+
filter: blur(9px);
97+
transition: filter 0.2s ease;
98+
}
99+
100+
.wrapped-privacy .wrapped-privacy-name:hover {
101+
filter: none;
102+
}
103+
104+
/* Wrapped 隐私模式:模糊“消息内容文本”(仅在被标记为 message 的节点上生效) */
105+
.wrapped-privacy .wrapped-privacy-message {
106+
filter: blur(9px);
107+
transition: filter 0.2s ease;
108+
}
109+
110+
.wrapped-privacy .wrapped-privacy-message:hover {
111+
filter: none;
112+
}
113+
114+
/* Wrapped 隐私模式:模糊“词云关键词” */
115+
.wrapped-privacy .wrapped-privacy-keyword {
116+
filter: blur(9px);
117+
transition: filter 0.2s ease;
118+
}
119+
120+
.wrapped-privacy .wrapped-privacy-keyword:hover {
121+
filter: none;
122+
}
123+
124+
/* Wrapped 隐私模式:模糊头像(含 fallback 字符) */
125+
.wrapped-privacy .wrapped-privacy-avatar {
126+
filter: blur(9px);
127+
transition: filter 0.2s ease;
128+
}
129+
130+
.wrapped-privacy .wrapped-privacy-avatar:hover {
131+
filter: none;
132+
}
93133
/* 按钮样式 */
94134
.btn {
95135
@apply px-6 py-3 rounded-full font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 transform active:scale-95;

frontend/components/wrapped/cards/Card00GlobalOverview.vue

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,8 @@
3636
<template v-if="topContact || topGroup">
3737
<template v-if="topContact">
3838
你发消息最多的人是
39-
「<span
40-
class="privacy-blur inline-flex items-center gap-2 align-bottom max-w-[12rem]"
41-
:title="topContact.displayName"
42-
>
43-
<span class="w-6 h-6 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0">
39+
「<span class="inline-flex items-center gap-2 align-bottom max-w-[12rem]" :title="topContact.displayName">
40+
<span class="w-6 h-6 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0 wrapped-privacy-avatar">
4441
<img
4542
v-if="topContactAvatarUrl && avatarOk.topContact"
4643
:src="topContactAvatarUrl"
@@ -52,18 +49,15 @@
5249
{{ avatarFallback(topContact.displayName) }}
5350
</span>
5451
</span>
55-
<span class="inline-block max-w-[10rem] truncate align-bottom">{{ topContact.displayName }}</span>
52+
<span class="wrapped-privacy-name inline-block max-w-[10rem] truncate align-bottom">{{ topContact.displayName }}</span>
5653
</span>」
5754
(<span class="wrapped-number text-[#07C160] font-semibold">{{ formatInt(topContact.messages) }}</span> 条)
5855
</template>
5956
<template v-if="topContact && topGroup">,</template>
6057
<template v-if="topGroup">
6158
你最常发言的群是
62-
「<span
63-
class="privacy-blur inline-flex items-center gap-2 align-bottom max-w-[12rem]"
64-
:title="topGroup.displayName"
65-
>
66-
<span class="w-6 h-6 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0">
59+
「<span class="inline-flex items-center gap-2 align-bottom max-w-[12rem]" :title="topGroup.displayName">
60+
<span class="w-6 h-6 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0 wrapped-privacy-avatar">
6761
<img
6862
v-if="topGroupAvatarUrl && avatarOk.topGroup"
6963
:src="topGroupAvatarUrl"
@@ -75,7 +69,7 @@
7569
{{ avatarFallback(topGroup.displayName) }}
7670
</span>
7771
</span>
78-
<span class="inline-block max-w-[10rem] truncate align-bottom">{{ topGroup.displayName }}</span>
72+
<span class="wrapped-privacy-name inline-block max-w-[10rem] truncate align-bottom">{{ topGroup.displayName }}</span>
7973
</span>」
8074
(<span class="wrapped-number text-[#07C160] font-semibold">{{ formatInt(topGroup.messages) }}</span> 条)
8175
</template>
@@ -87,10 +81,7 @@
8781
</template>
8882

8983
<template v-if="topPhrase && topPhrase.phrase && topPhrase.count > 0">
90-
你说得最多的一句话是「<span
91-
class="privacy-blur inline-block max-w-[12rem] truncate align-bottom"
92-
:title="topPhrase.phrase"
93-
>{{ topPhrase.phrase }}</span>」(<span class="wrapped-number text-[#07C160] font-semibold">{{ formatInt(topPhrase.count) }}</span> 次)。
84+
你说得最多的一句话是「<span class="inline-block max-w-[12rem] truncate align-bottom" :title="topPhrase.phrase">{{ topPhrase.phrase }}</span>」(<span class="wrapped-number text-[#07C160] font-semibold">{{ formatInt(topPhrase.count) }}</span> 次)。
9485
</template>
9586

9687
<span class="hidden sm:inline text-[#00000055]">愿你的每一句分享,都有人回应。</span>

frontend/components/wrapped/cards/Card01CyberSchedule.vue

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,39 +66,39 @@
6666
<!-- 最早最晚消息描述(按一天中的时刻) -->
6767
<template v-if="earliestSent && latestSent && totalMessages > 0">
6868
<template v-if="sameMomentTarget">
69-
最先想起的是「<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>」,
70-
最后放不下的也还是「<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>」。
69+
最先想起的是「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>」,
70+
最后放不下的也还是「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>」。
7171
</template>
7272
<template v-else>
7373
<template v-if="sameMomentDate">
74-
在 {{ earliestDateLabel }},最早的一条发给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>」,
75-
最晚的一条发给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ latestSent.displayName }}</span>」。
74+
在 {{ earliestDateLabel }},最早的一条发给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>」,
75+
最晚的一条发给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ latestSent.displayName }}</span>」。
7676
</template>
7777
<template v-else-if="!hasMomentDates">
7878
最早的一条发给了
79-
<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>,
79+
<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>,
8080
最晚的一条发给了
81-
<span class="wrapped-number text-[#07C160] font-semibold">{{ latestSent.displayName }}</span>。
81+
<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ latestSent.displayName }}</span>。
8282
</template>
8383
<template v-else-if="momentVariant === 0">
84-
最早的一条({{ earliestDateLabel }})发给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>」,
85-
最晚的一条({{ latestDateLabel }})发给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ latestSent.displayName }}</span>」。
84+
最早的一条({{ earliestDateLabel }})发给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>」,
85+
最晚的一条({{ latestDateLabel }})发给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ latestSent.displayName }}</span>」。
8686
</template>
8787
<template v-else-if="momentVariant === 1">
88-
最早的收件人是「<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>」({{ earliestDateLabel }}),
89-
最晚的收件人是「<span class="wrapped-number text-[#07C160] font-semibold">{{ latestSent.displayName }}</span>」({{ latestDateLabel }})。
88+
最早的收件人是「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>」({{ earliestDateLabel }}),
89+
最晚的收件人是「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ latestSent.displayName }}</span>」({{ latestDateLabel }})。
9090
</template>
9191
<template v-else-if="momentVariant === 2">
92-
在 {{ earliestDateLabel }},你把消息发给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>」;
93-
在 {{ latestDateLabel }},你又发给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ latestSent.displayName }}</span>」。
92+
在 {{ earliestDateLabel }},你把消息发给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>」;
93+
在 {{ latestDateLabel }},你又发给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ latestSent.displayName }}</span>」。
9494
</template>
9595
<template v-else-if="momentVariant === 3">
96-
最早与最晚,分别写给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>」({{ earliestDateLabel }})
97-
和「<span class="wrapped-number text-[#07C160] font-semibold">{{ latestSent.displayName }}</span>」({{ latestDateLabel }})。
96+
最早与最晚,分别写给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>」({{ earliestDateLabel }})
97+
和「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ latestSent.displayName }}</span>」({{ latestDateLabel }})。
9898
</template>
9999
<template v-else>
100-
最早的一条落在 {{ earliestDateLabel }},发给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ earliestSent.displayName }}</span>」;
101-
最晚的一条落在 {{ latestDateLabel }},发给了「<span class="wrapped-number text-[#07C160] font-semibold">{{ latestSent.displayName }}</span>」。
100+
最早的一条落在 {{ earliestDateLabel }},发给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ earliestSent.displayName }}</span>」;
101+
最晚的一条落在 {{ latestDateLabel }},发给了「<span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ latestSent.displayName }}</span>」。
102102
</template>
103103
</template>
104104
</template>
@@ -111,15 +111,15 @@
111111
v-if="yearFirstSent.avatarUrl"
112112
:src="yearFirstSent.avatarUrl"
113113
:alt="yearFirstSent.displayName"
114-
class="inline-block w-5 h-5 rounded align-middle mx-0.5"
115-
/><span class="wrapped-number text-[#07C160] font-semibold">{{ yearFirstSent.displayName }}</span>:「{{ yearFirstSent.content || '...' }}」<template v-if="yearLastSent">;
114+
class="inline-block w-5 h-5 rounded align-middle mx-0.5 wrapped-privacy-avatar"
115+
/><span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ yearFirstSent.displayName }}</span>:「<span class="wrapped-privacy-message">{{ yearFirstSent.content || '...' }}</span>」<template v-if="yearLastSent">;
116116
最后一条消息(<span class="wrapped-number text-[#07C160] font-semibold">{{ yearLastDateLabel }} {{ yearLastSent.time }}</span>)发给了
117117
<img
118118
v-if="yearLastSent.avatarUrl"
119119
:src="yearLastSent.avatarUrl"
120120
:alt="yearLastSent.displayName"
121-
class="inline-block w-5 h-5 rounded align-middle mx-0.5"
122-
/><span class="wrapped-number text-[#07C160] font-semibold">{{ yearLastSent.displayName }}</span>:「{{ yearLastSent.content || '...' }}」</template>。
121+
class="inline-block w-5 h-5 rounded align-middle mx-0.5 wrapped-privacy-avatar"
122+
/><span class="wrapped-number text-[#07C160] font-semibold wrapped-privacy-name">{{ yearLastSent.displayName }}</span>:「<span class="wrapped-privacy-message">{{ yearLastSent.content || '...' }}</span>」</template>。
123123
<template v-if="sameYearTarget">
124124
<span class="text-[#7F7F7F]">——从年初到年末,始终如一。</span>
125125
</template>

frontend/components/wrapped/cards/Card03ReplySpeed.vue

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
class="inline-flex items-center gap-2 align-bottom px-1.5 py-0.5 rounded-lg bg-[#00000008]"
1212
:title="bestBuddy?.displayName || ''"
1313
>
14-
<span class="w-5 h-5 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0">
14+
<span class="w-5 h-5 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0 wrapped-privacy-avatar">
1515
<img
1616
v-if="bestBuddyAvatarUrl && avatarOk.best"
1717
:src="bestBuddyAvatarUrl"
@@ -23,7 +23,7 @@
2323
{{ avatarFallback(bestBuddy?.displayName) }}
2424
</span>
2525
</span>
26-
<span class="wrapped-body text-sm text-[#000000e6] max-w-[12rem] truncate">
26+
<span class="wrapped-body text-sm text-[#000000e6] max-w-[12rem] truncate wrapped-privacy-name">
2727
{{ bestBuddy?.displayName || '' }}
2828
</span>
2929
</span>
@@ -35,7 +35,7 @@
3535
class="inline-flex items-center gap-1.5 align-bottom px-1.5 py-0.5 rounded-lg bg-[#00000008]"
3636
:title="seg.contact?.displayName || ''"
3737
>
38-
<span class="w-4 h-4 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0">
38+
<span class="w-4 h-4 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0 wrapped-privacy-avatar">
3939
<img
4040
v-if="resolveMediaUrl(seg.contact?.avatarUrl) && avatarOk[seg.contact?.username] !== false"
4141
:src="resolveMediaUrl(seg.contact?.avatarUrl)"
@@ -47,7 +47,7 @@
4747
{{ avatarFallback(seg.contact?.displayName) }}
4848
</span>
4949
</span>
50-
<span class="wrapped-body text-sm text-[#000000e6] max-w-[8rem] truncate">
50+
<span class="wrapped-body text-sm text-[#000000e6] max-w-[8rem] truncate wrapped-privacy-name">
5151
{{ seg.contact?.displayName || '' }}
5252
</span>
5353
</span>
@@ -95,7 +95,7 @@
9595

9696
<!-- 主内容:抽奖揭晓 + 右侧年度 Top10 总消息 bar race -->
9797
<div v-else class="w-full">
98-
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 items-center">
98+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 items-start">
9999
<!-- Left: 抽奖区 -->
100100
<div
101101
class="reply-buddy-rail flex flex-col items-center justify-center transition-transform duration-500 will-change-transform"
@@ -109,7 +109,7 @@
109109
<img
110110
v-if="shownAvatarUrl && shownAvatarOk"
111111
:src="shownAvatarUrl"
112-
class="w-full h-full object-cover"
112+
class="w-full h-full object-cover wrapped-privacy-avatar"
113113
alt="avatar"
114114
@error="onShownAvatarError"
115115
/>
@@ -121,15 +121,15 @@
121121
/>
122122
<div
123123
v-else
124-
class="w-full h-full flex items-center justify-center"
124+
class="w-full h-full flex items-center justify-center wrapped-privacy-avatar"
125125
>
126126
<span class="wrapped-number text-3xl text-[#00000066]">
127127
{{ shownAvatarFallback }}
128128
</span>
129129
</div>
130130
</div>
131131

132-
<div class="mt-4 min-h-[1.75rem] wrapped-body text-base text-[#000000e6] max-w-[18rem] truncate" :title="shownDisplayName">
132+
<div class="mt-4 min-h-[1.75rem] wrapped-body text-base text-[#000000e6] max-w-[18rem] truncate wrapped-privacy-name" :title="shownDisplayName">
133133
{{ shownDisplayName }}
134134
</div>
135135

@@ -210,7 +210,7 @@
210210
</div>
211211

212212
<div
213-
class="w-7 h-7 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0"
213+
class="w-7 h-7 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0 wrapped-privacy-avatar"
214214
>
215215
<img
216216
v-if="item.avatarUrl && avatarOk[item.username] !== false"
@@ -227,7 +227,7 @@
227227
<div class="min-w-0 flex-1">
228228
<div class="flex items-center justify-between gap-3">
229229
<div class="min-w-0">
230-
<div class="wrapped-body text-[#000000e6] text-sm truncate" :title="item.displayName">
230+
<div class="wrapped-body text-[#000000e6] text-sm truncate wrapped-privacy-name" :title="item.displayName">
231231
{{ item.displayName }}
232232
</div>
233233
</div>

frontend/components/wrapped/cards/Card04EmojiUniverse.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
class="mt-0.5 inline-flex items-center gap-1.5 rounded-md bg-[#00000008] px-1.5 py-1 max-w-full"
5959
:title="heroStickerOwnerName ? `常发送给 ${heroStickerOwnerName}` : '常发送给:未知'"
6060
>
61-
<span class="w-4 h-4 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0">
61+
<span class="w-4 h-4 rounded-md overflow-hidden bg-[#0000000d] flex items-center justify-center flex-shrink-0 wrapped-privacy-avatar">
6262
<img
6363
v-if="heroStickerOwnerAvatarUrl && avatarOk.topStickerOwner"
6464
:src="heroStickerOwnerAvatarUrl"
@@ -71,7 +71,7 @@
7171
</span>
7272
</span>
7373
<span class="wrapped-body text-[11px] text-[#00000080] truncate">
74-
常发送给 <span class="text-[#07C160] font-semibold">{{ heroStickerOwnerName || '未知' }}</span>
74+
常发送给 <span class="text-[#07C160] font-semibold wrapped-privacy-name">{{ heroStickerOwnerName || '未知' }}</span>
7575
</span>
7676
</div>
7777

frontend/components/wrapped/cards/Card04MonthlyBestFriendsWall.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<template v-if="item.winner">
3131
<div class="flex items-start gap-1.5 pt-0.5 px-0.5">
3232
<!-- 头像 -->
33-
<div class="polaroid-photo flex-shrink-0">
33+
<div class="polaroid-photo flex-shrink-0 wrapped-privacy-avatar">
3434
<img
3535
v-if="winnerAvatar(item) && avatarOk[item.winner.username] !== false"
3636
:src="winnerAvatar(item)"
@@ -46,7 +46,7 @@
4646
<div class="flex-1 min-w-0 pt-0.5 flex flex-col justify-between" style="height:70px">
4747
<div>
4848
<div class="flex items-center justify-between gap-1 min-w-0">
49-
<div class="wrapped-body text-[10px] text-[#000000cc] truncate flex-1 leading-tight" :title="item.winner.displayName">
49+
<div class="wrapped-body text-[10px] text-[#000000cc] truncate flex-1 leading-tight wrapped-privacy-name" :title="item.winner.displayName">
5050
{{ item.winner.displayName }}
5151
</div>
5252
<!-- 月份徽章 -->

0 commit comments

Comments
 (0)