frontend: the shell names the active lens (task 1913)
CI & Build / Python lint (push) Successful in 4s
CI & Build / TypeScript typecheck (push) Successful in 8s
CI & Build / Python tests (push) Successful in 15s
CI & Build / Build & push image (push) Successful in 44s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m51s
Android (Tauri) / Android APK (debug) (push) Successful in 3m37s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 4m57s
Desktop (Tauri) / Update manifest (push) Successful in 5s
CI & Build / Python lint (push) Successful in 4s
CI & Build / TypeScript typecheck (push) Successful in 8s
CI & Build / Python tests (push) Successful in 15s
CI & Build / Build & push image (push) Successful in 44s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m51s
Android (Tauri) / Android APK (debug) (push) Successful in 3m37s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 4m57s
Desktop (Tauri) / Update manifest (push) Successful in 5s
Which lens you're looking at is a property of the space, not of a page you navigated to — so the name now sits in the bar that never moves, beside the app name, and stays put while everything beneath it re-filters. It replaces three per-view <h1>s that each sat in a different place with slightly different markup (timeline, reminders, graph) and, more to the point, were absent entirely on the board and in search — the two lenses people spend the most time in had no name at all. A label lens is named by the label itself, because "Groceries" is what the user came looking for and "Label" tells them nothing. Shown at every width rather than hidden on small screens, which was my first cut and would have been a regression: deleting the per-view titles while hiding the shell one leaves a phone with no lens name anywhere, and Android is a peer surface now. Below `sm` the app name is already hidden, so the lens name simply takes the space it vacates — you know which app you're in; what you need is which lens. The h1s on Settings, Sync, Account, Login and Register are untouched: those routes render outside the shell entirely, so they have no chrome to be named by. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -202,6 +202,39 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* What to call the lens currently in view.
|
||||
*
|
||||
* Keyed off the route name rather than each view declaring its own title, so the
|
||||
* label sits in one place and can't go missing (the board and search never had one)
|
||||
* or drift in styling (timeline, reminders and graph each had their own h1).
|
||||
*
|
||||
* A label lens is named by the label itself — "Groceries" is what the user came
|
||||
* looking for; "Label" would tell them nothing they didn't already know.
|
||||
*/
|
||||
const lensName = computed<string>(() => {
|
||||
switch (route.name) {
|
||||
case "archive":
|
||||
return "Archive";
|
||||
case "trash":
|
||||
return "Trash";
|
||||
case "search":
|
||||
return "Search";
|
||||
case "timeline":
|
||||
return "Timeline";
|
||||
case "reminders":
|
||||
return "Reminders";
|
||||
case "graph":
|
||||
return "Graph";
|
||||
case "label":
|
||||
// The store may not have loaded yet on a deep link; fall back rather than
|
||||
// flashing an empty slot.
|
||||
return labels.items.find((l) => l.id === String(route.params.id))?.name ?? "Label";
|
||||
default:
|
||||
return "Notes";
|
||||
}
|
||||
});
|
||||
|
||||
async function signOut() {
|
||||
await session.logout();
|
||||
await router.replace("/login");
|
||||
@@ -248,6 +281,20 @@ async function signOut() {
|
||||
<span class="hidden font-semibold sm:inline">{{ config.siteName }}</span>
|
||||
</RouterLink>
|
||||
|
||||
<!-- The active lens, named in the persistent chrome rather than inside each
|
||||
view. Which lens you're looking at is a property of the SPACE, not of a
|
||||
page you navigated to — so it sits in the bar that never moves, beside
|
||||
the app name, and stays in one place while everything beneath it
|
||||
re-filters. Replaces the per-view <h1>s, which sat in a different spot
|
||||
in each view and were absent entirely on the board and in search. -->
|
||||
<span aria-live="polite" class="flex min-w-0 shrink items-center gap-2 text-sm text-neutral-400">
|
||||
<!-- The separator only makes sense next to the app name, which is itself
|
||||
hidden on narrow screens. There, the lens name simply takes the space
|
||||
the app name vacated — you already know which app you're in. -->
|
||||
<span aria-hidden="true" class="hidden sm:inline">/</span>
|
||||
<span class="truncate font-medium text-neutral-600 dark:text-neutral-300">{{ lensName }}</span>
|
||||
</span>
|
||||
|
||||
<div class="flex flex-1 justify-center">
|
||||
<input
|
||||
ref="searchInput"
|
||||
|
||||
@@ -304,8 +304,8 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<div class="flex h-full flex-col p-4">
|
||||
<div class="mb-3 flex flex-wrap items-center justify-between gap-3">
|
||||
<h1 class="text-lg font-semibold">Graph</h1>
|
||||
<!-- Titled by the shell's persistent lens name (task 1913). -->
|
||||
<div class="mb-3 flex flex-wrap items-center justify-end gap-3">
|
||||
<div class="flex items-center gap-3 text-sm">
|
||||
<label class="flex cursor-pointer items-center gap-1.5 text-neutral-600 dark:text-neutral-300">
|
||||
<input type="checkbox" class="accent-brand" :checked="showLabels" @change="toggleLabels" />
|
||||
|
||||
@@ -33,8 +33,8 @@ onMounted(load);
|
||||
|
||||
<template>
|
||||
<div class="mx-auto w-full max-w-2xl px-4 py-6">
|
||||
<div class="mb-2 flex items-center justify-between gap-3">
|
||||
<h1 class="text-lg font-semibold">Reminders</h1>
|
||||
<!-- Titled by the shell's persistent lens name (task 1913). -->
|
||||
<div class="mb-2 flex items-center justify-end gap-3">
|
||||
<button
|
||||
v-if="reminders.osSupported && !reminders.osEnabled"
|
||||
type="button"
|
||||
|
||||
@@ -102,8 +102,10 @@ onMounted(load);
|
||||
|
||||
<template>
|
||||
<div class="mx-auto w-full max-w-6xl px-4 py-6">
|
||||
<div class="mb-1 flex flex-wrap items-center justify-between gap-3">
|
||||
<h1 class="text-lg font-semibold">Timeline</h1>
|
||||
<!-- No <h1> here: the shell's persistent bar names the active lens (task 1913),
|
||||
so a per-view title would say the same thing twice, in a place that scrolls
|
||||
away. -->
|
||||
<div class="mb-1 flex flex-wrap items-center justify-end gap-3">
|
||||
<div class="flex flex-wrap items-center gap-2 text-sm">
|
||||
<label class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">
|
||||
<span>From</span>
|
||||
|
||||
Reference in New Issue
Block a user