@@ -169,30 +169,34 @@ const { pathPageLabels } = usePagePathRealtimeTitles({
169169 cryptoError ,
170170});
171171
172- // Fallback: decrypt current page title from bootstrap data when realtime
173- // WS hasn't provided it yet.
174- watch (
175- [pageId , pageKeyring , pageEncRelTitleB64 ],
176- () => {
177- const id = pageId .value ;
178- const pk = pageKeyring .value ;
179- const b64 = pageEncRelTitleB64 .value ;
180- if (! id || ! pk || ! b64 ) return ;
181- try {
182- const title = decryptPageRelativeTitle ({
183- pageKeyring: pk ,
184- pageId: id ,
185- ciphertext: base64ToBytes (b64 ),
186- });
187- if (title && title .length > 0 ) {
188- pathPageLabels .value = { ... pathPageLabels .value , [id ]: title };
189- }
190- } catch {
191- // ignore decrypt failures
172+ // Merge realtime labels with the current page's bootstrap-encrypted title.
173+ // usePagePathRealtimeTitles clears and refills pathPageLabels asynchronously,
174+ // so a simple watcher would be overwritten. A computed always re-evaluates.
175+ const pageLabels = computed <Record <string , string >>(() => {
176+ const labels = { ... pathPageLabels .value };
177+ const id = pageId .value ;
178+ if (labels [id ] && labels [id ].length > 0 ) {
179+ return labels ;
180+ }
181+ const pk = pageKeyring .value ;
182+ const b64 = pageEncRelTitleB64 .value ;
183+ if (! id || ! pk || ! b64 ) {
184+ return labels ;
185+ }
186+ try {
187+ const title = decryptPageRelativeTitle ({
188+ pageKeyring: pk ,
189+ pageId: id ,
190+ ciphertext: base64ToBytes (b64 ),
191+ });
192+ if (title && title .length > 0 ) {
193+ labels [id ] = title ;
192194 }
193- },
194- { immediate: true },
195- );
195+ } catch {
196+ // ignore decrypt failures
197+ }
198+ return labels ;
199+ });
196200
197201const snapshotsApi = usePageSnapshots ({
198202 pageId ,
@@ -300,10 +304,10 @@ onMounted(() => {
300304 class="text-primary hover:underline "
301305 :to =" ` /pages/${pid } ` "
302306 >
303- {{ pagePathLabel(pid, pathPageLabels ) }}
307+ {{ pagePathLabel(pid, pageLabels ) }}
304308 </RouterLink >
305309 <span v-else class =" text-foreground font-medium" >
306- {{ pagePathLabel(pid, pathPageLabels ) }}
310+ {{ pagePathLabel(pid, pageLabels ) }}
307311 </span >
308312 </template >
309313 </nav >
@@ -334,10 +338,10 @@ onMounted(() => {
334338 class="text-primary hover:underline "
335339 :to =" ` /pages/${pid } ` "
336340 >
337- {{ pagePathLabel(pid, pathPageLabels ) }}
341+ {{ pagePathLabel(pid, pageLabels ) }}
338342 </RouterLink >
339343 <span v-else class =" text-foreground font-medium" >
340- {{ pagePathLabel(pid, pathPageLabels ) }}
344+ {{ pagePathLabel(pid, pageLabels ) }}
341345 </span >
342346 </template >
343347 </nav >
@@ -374,23 +378,23 @@ onMounted(() => {
374378 <RecentPagesCard
375379 :recent-page-ids =" recentPageIds "
376380 :current-page-id =" pageId "
377- :page-labels =" pathPageLabels "
381+ :page-labels =" pageLabels "
378382 @clear =" void clearRecent ()"
379383 />
380384
381385 <!-- Favorite pages -->
382386 <FavoritePagesCard
383387 :favorite-page-ids =" favoritePageIds "
384388 :current-page-id =" pageId "
385- :page-labels =" pathPageLabels "
389+ :page-labels =" pageLabels "
386390 @clear =" void clearFavorites ()"
387391 />
388392
389393 <!-- Selected pages -->
390394 <SelectedPagesCard
391395 :selected-page-ids =" selectedPageIds "
392396 :current-page-id =" pageId "
393- :page-labels =" pathPageLabels "
397+ :page-labels =" pageLabels "
394398 @clear =" selectedPageIds = []"
395399 />
396400
@@ -415,8 +419,8 @@ onMounted(() => {
415419 <PagePropertiesCard
416420 v-if =" ! selectedNoteId && ! selectedArrowId "
417421 :page-id =" pageId "
418- :relative-title =" pathPageLabels [pageId ]"
419- :absolute-title =" pathPageLabels [pageId ]"
422+ :relative-title =" pageLabels [pageId ]"
423+ :absolute-title =" pageLabels [pageId ]"
420424 :is-favorite =" isFavorite "
421425 :read-only =" cryptoError !== null "
422426 @update :relative-title =" () => {} "
0 commit comments