- prefer memory-backed copied blocks before async clipboard read fallback in paste flow
- normalize clipboard write payload construction for web ClipboardItem
- render exported property keys with property titles instead of db ident suffixes
- render datetime property integer values as journal titles using export date formatter
- add regression tests for paste and export property rendering
`sync status` can fail with error to use nonexistent
--e2ee-password option. `status` is a read only operation and isn't in
authenticated-sync-actions so just remove e2ee check for it
Web-image dedup turned into an annotation. Tiles whose source-url already
matches a local asset stay in the row but swap their globe overlay for a
deep-forest-green disc with a white check. Click on a saved tile routes
through the existing asset (no re-download, no orphan duplicate). Keeps
the row at full width even when 3 of 5 hits are already saved, and avoids
the "broken search" feel of the previous filter.
Disc color is a fixed#137333 rather than a Radix token because the
green scale's step 9 is intentionally similar across themes — pairing it
with a flipping icon color leaves white washed out in dark mode and
near-black on green in light mode. Hardcoded deep green is the simplest
single-token answer that gives white the contrast it needs in both modes.
Broken-image state (image-icon-cp's :error? branch) reworked from a heavy
filled bg-gray-04 block to a bordered placeholder-style tile matching the
"pick an image" affordance — solid border (vs dashed for "awaiting
input"), translucent fill, muted photo-off glyph at 0.45x size. Same
chrome family, distinct enough to read as "broken/persistent" rather
than "empty/inviting".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- icon dispatch + renderable-icon? trust the asset-uuid string instead of
probing the renderer-side entity, so a fresh navigation to a page whose
icon points at an asset renders via the filesystem loader instead of
silently rendering nothing while DataScript catches up.
- <load-asset-url! widens the retry window when the error is db-worker
not-yet-initialized (15x500ms) vs real failures (3x1s unchanged).
- asset-picker hides web-image suggestions whose source-url already
matches a saved asset, so the same image no longer shows up in both
Web images and Available assets. Pull queries extended to surface
:logseq.property.asset/source-url, and the keyboard-nav flat list
filters in lockstep with the visible UI.
- Custom-tab Text/Avatar/Image preview thumbnails get aria-hidden so
screen readers and find-by-text read just the label rather than
"STAvatar"/"STText".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: configurable publish server URL
Mirror the Custom Sync Server URL pattern (#12459) for the single-page
publish service. Settings -> Advanced -> Publish server URL opens a
dialog that writes the URL to localStorage; frontend.config/publish-api-base
reads it on each call so URL changes take effect without a restart.
Unlike sync, publish does not need a push-config-to-worker step because
the handler is purely HTTP request-response with no long-lived connection.
* fix(i18n): resolve en.edn merge after master sync
---------
Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
The page-icon now previews any tile the user is hovering or keyboard-
navigating in the picker — mirroring the existing color preview but
extended to icon, emoji, text, avatar, and image-placeholder types. The
preview state is keyed by `:db-id` and reads through the existing
`:ui/icon-hover-preview` slot.
Custom-tab tiles route to the asset-picker on the right tab and commit
a placeholder synchronously: Avatar commits the initials avatar and
opens the Avatar tab; Image commits an `:image-placeholder` (rendered
as a plus inside a dashed rounded square — the same affordance Logseq
uses for "no icon yet, click to add") and opens the Image tab. The
asset-picker accepts an `:initial-mode` prop that overrides its
heuristic seed.
Mouse-clicking a tab now also focuses the search input so ArrowDown
flows into the grid (the previous code only updated `*focus-region`,
leaving DOM focus on the tab button so the keydown listener never
fired).
A `pending-icon` `rum/use-state` in `icon-picker` holds the just-
committed icon-value during the ~15ms SharedWorker round-trip between
the DB write and the entity update propagating back through the
reactive read chain. Without this, every commit visibly flashed the
old icon for one render cycle. The state auto-clears via `use-effect`
on `[icon-value]` deps (Logseq's `hooks/use-effect!` uses Clojure
value equality, so map content changes fire correctly).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The page-title icon container used `.flex.self-start` and relied on each
icon type's own intrinsic baseline (font glyph for emoji, SVG bottom
anchor for tabler, etc.), with `margin-top: 8px` and `pb-[1.5px]`
band-aids compensating for one type at a time. Replaced with a single
flex-center 38×38 button rule, scoped to `.ls-page-title .ls-page-icon`,
so every type centers on the same visual axis. Drops the per-type pixel
overrides, the mobile-specific `:size 28` (mobile font is unchanged from
desktop, so the override was a band-aid), and the inline `1lh` style.
Bumps the icon-to-title gap from `gap-2` to `gap-3` (12px) for breathing
room.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The color-picker's :after-close! callback was gated on @*highlighted-index,
so opening the color picker without first navigating to an icon left focus
nowhere when the popover closed. The capture-phase keydown listener only
fires for keys whose target is inside the icon-picker container, so the
picker would appear open but reject every keystroke until the user clicked
the search input. Fall back to focusing the search input (and resetting
:focus-region to :search) when there's no highlighted tile to return to.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tab/Shift+Tab cycles three lanes (swatches → hex input → recents) and
arrow keys cross between them: hex input ↑ jumps to the active swatch,
↓ jumps to the first recent; the swatches grid's bottom row hops into
the hex input when the pane is open. The recents lane gets roving
tabindex with 2D nav across its two flex-wrapped rows, and react-
colorful's pad/hue sliders are stripped from the Tab order (mouse/
touch only) so keyboard users never land on the pad. The collapsed
pane is marked `inert` to keep its hidden controls out of focus.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>