The user page at /u/:username now opens with a compact identity block
(40px
avatar, name, handle, clamped bio) instead of a hero header with a share
button, and the list beneath it follows the user's column setting like
Explore does. In grid mode the header spans every column via a new
ColumnGrid
header slot, exposed through PagedMemoList.renderHeader. Loading shows a
skeleton after the standard delay, not-found renders a body instead of a
toast fired from render, and visitors get an explicit empty message.
Saved views now apply on profile routes too. A single profile-route
matcher
in lib/memo-views replaces five separate spellings,
isMemoCollectionRoute
names the routes where views, calendar days and tags narrow the list in
place, and the sidebar shows the Views section on every such route for
signed-in users. The never-taken navigation-target branch in the
collection
sidebar is removed along with its props.
Compact cards previously had two truncation systems taped together: a
text-only clamp inside MemoContent (144px, no re-measure on image load,
fade tinted to the wrong surface) and a whole-tile cap in ColumnGrid
(hard clip mid-image, no affordance), later joined by a content-shape
rule choosing an owner per card — which could still stack two Show-more
buttons and silently broke footnote navigation in clamped cards.
Now there is exactly one mechanism: ClampedSection measures its content
and folds anything taller than 420px to a 360px preview with a fade and
a Show more/less toggle. MemoBody wraps the whole body in it (reactions
stay outside, never hidden); ColumnGrid is pure packing again and never
clips; MemoContent is a stateless renderer whose `compact` prop only
informs footnote-link behavior; MemoPreview uses a static CSS bound in
place of its previously inert toggle.
Deltas: text-only compact previews grow from ~6 rows to the same 360px
image cards get, and pinned memos clamp like any card (pinned means
ordering and a badge, not size).
Replace the single-column-only feed with a max-columns model: one
Columns setting (1 / 2 / 3 / ∞) where 1 is the reading list and
anything wider packs into a Google-Keep-style column grid. There is
deliberately no separate list/grid mode — the setting is a ceiling,
and widths that only fit one column fall back to the flow list.
- ColumnGrid: absolute-positioned packing that only translates cards,
so appends and reorders never remount them; sticky column assignment
keeps existing cards in place when new memos arrive; tiles are capped
at 360px with a fade; columns clamp to 420px and center.
- Column one is the action column: the composer and active filters
stack as its first tile, and a just-created memo is pinned directly
beneath them.
- Multi-column always renders compact cards (policy centralized in
PagedMemoList and threaded through renderer(memo, { compact })).
- Setting persists in ViewContext localStorage; the settings menu
derives its options from the context's canonical value list.