@@ -247,17 +247,29 @@ watch(() => queueStore.proofread.size, () => {
247247const backend = useProofreadingBackendStore ();
248248let prevNotifCount = - 1 ;
249249
250+ /** Parse badge name and description from notification body like:
251+ * 'You earned the "Alpha Tester" award! — Only the elite are invited...' */
252+ function parseBadgeBody(body : string ): { name: string ; description: string } {
253+ const nameMatch = body .match (/ "([^ "] + )"/ );
254+ const name = nameMatch ? nameMatch [1 ] : ' New Achievement' ;
255+ // Description is after " — " or after "award!"
256+ const descMatch = body .match (/ (?:award!? \s * (?:—\s * )? )(. * )/ );
257+ const description = descMatch ?.[1 ]?.trim () || body ;
258+ return { name , description };
259+ }
260+
250261watch (() => backend .notifications .length , (newLen ) => {
251262 if (prevNotifCount < 0 ) { prevNotifCount = newLen ; return ; }
252263 if (newLen <= prevNotifCount ) { prevNotifCount = newLen ; return ; }
253264 // Check the newest notifications for achievement awards
254265 const newNotifs = backend .notifications .slice (0 , newLen - prevNotifCount );
255266 for (const notif of newNotifs ) {
256267 if (notif .title ?.includes (' New Achievement' )) {
268+ const { name, description } = parseBadgeBody (notif .body || ' ' );
257269 addToast ({
258270 type: ' badge' ,
259- title: ' ✨ New Achievement! ' ,
260- subtitle: notif . body || ' You earned a special award! ' ,
271+ title: name ,
272+ subtitle: description ,
261273 icon: notif .image_url || notif .thumbnail_url || ' 🏆' ,
262274 isImage: !! (notif .image_url || notif .thumbnail_url ),
263275 });
@@ -270,10 +282,11 @@ watch(() => backend.notifications.length, (newLen) => {
270282// ── Replay badge celebration when clicked from notification panel ─────────
271283watch (() => backend .pendingBadgeCelebration , (pending ) => {
272284 if (! pending ) return ;
285+ const { name, description } = parseBadgeBody (pending .body || ' ' );
273286 addToast ({
274287 type: ' badge' ,
275- title: ' ✨ New Achievement! ' ,
276- subtitle: pending . body || ' You earned a special award! ' ,
288+ title: name ,
289+ subtitle: description ,
277290 icon: pending .imageUrl || ' 🏆' ,
278291 isImage: !! pending .imageUrl ,
279292 });
@@ -504,9 +517,9 @@ watch(() => backend.pendingBadgeCelebration, (pending) => {
504517/* ── Holographic rings ── */
505518.nge-hero-rings {
506519 position : absolute ;
507- top : 20 px ;
508- width : 440 px ;
509- height : 440 px ;
520+ top : 10 px ;
521+ width : 320 px ;
522+ height : 320 px ;
510523 pointer-events : none ;
511524}
512525.nge-hero-ring {
@@ -543,9 +556,9 @@ watch(() => backend.pendingBadgeCelebration, (pending) => {
543556/* ── Orbital electron dots ── */
544557.nge-hero-orbits {
545558 position : absolute ;
546- top : 20 px ;
547- width : 440 px ;
548- height : 440 px ;
559+ top : 10 px ;
560+ width : 320 px ;
561+ height : 320 px ;
549562 pointer-events : none ;
550563}
551564.nge-hero-orbit-dot {
@@ -598,9 +611,9 @@ watch(() => backend.pendingBadgeCelebration, (pending) => {
598611/* ── Energy aura ── */
599612.nge-hero-aura {
600613 position : absolute ;
601- top : 50 px ;
602- width : 360 px ;
603- height : 360 px ;
614+ top : 20 px ;
615+ width : 280 px ;
616+ height : 280 px ;
604617 border-radius : 50% ;
605618 background : radial-gradient (circle , rgba (0 , 180 , 255 , 0.08 ) 0% , rgba (206 , 147 , 216 , 0.04 ) 40% , transparent 70% );
606619 animation : nge-hero-aura-pulse 2.5s ease-in-out infinite ;
@@ -613,8 +626,8 @@ watch(() => backend.pendingBadgeCelebration, (pending) => {
613626
614627/* ── Badge icon ── */
615628.nge-hero-icon {
616- width : 380 px ;
617- height : 380 px ;
629+ width : 280 px ;
630+ height : 280 px ;
618631 display : flex ;
619632 align-items : center ;
620633 justify-content : center ;
@@ -627,8 +640,8 @@ watch(() => backend.pendingBadgeCelebration, (pending) => {
627640 position : relative ;
628641}
629642.nge-hero-badge-img {
630- width : 360 px ;
631- height : 360 px ;
643+ width : 240 px ;
644+ height : 240 px ;
632645 object-fit : contain ;
633646 image-rendering : auto ;
634647 animation : nge-hero-badge-materialize 0.8s cubic-bezier (0.16 , 1 , 0.3 , 1 ) forwards ;
0 commit comments