Commit Graph

24561 Commits

Author SHA1 Message Date
Tienson Qin
c5775df851 fix: large-title rehydrate
Root cause: large-title rehydrate was reusing the remote tx’s
original entity id. When that id was a string tempid,
Datascript had already resolved it during remote apply, so rehydrate
created a new invalid entity with only :block/title.
2026-05-08 11:31:50 +08:00
VictorVow
1423a38062 fix: restore :ref/default-open-blocks-level 0 behavior in DB graphs
Make `:ref/default-open-blocks-level 0` collapse references by default
in the DB version, matching the previous file-graph behavior. The
section fold is scoped to the page-bottom "Linked References" panel
only — the inline "Open block references" popup rendered next to
blocks always shows its references uncollapsed.

1. Collapse the "Linked References" section when the configured level
   is 0, gated on a new `:linked-refs-section?` config flag set only
   by the page-bottom call site in page.cljs. The inline popup at
   block.cljs:3366 passes `{}` and is unaffected.

2. Propagate `:block.temp/has-children?` on the top-level fetched
   block in `get-block-and-children`. The list-view loads linked-
   reference blocks with `:children? false`, so `(:block/_parent ...)`
   is always nil in the client DB and the collapse check in
   `block-default-collapsed?` could never fire. Use a lightweight
   `d/datoms :avet :block/parent` scan that stops at the first match,
   rather than the reverse-ref `(:block/_parent block)` which
   materializes the full child set. Includes a regression test.

3. Fall back to `:block.temp/has-children?` when computing `has-child?`
   in `block-container-inner-aux`. This renders the collapse arrow for
   blocks whose children exist in the worker DB but haven't been
   lazily loaded into the client DB yet (e.g. linked-reference blocks).
   Clicking the arrow calls `expand-block!` which loads them.

The `:ref/default-open-blocks-level 0 → (int? ...)` state.cljs fix
from PR #12228 is already present on this branch.
2026-05-08 11:18:51 +08:00
Tienson Qin
427dbe3f58 feat: export Logseq markdown syntax
Move the Logseq Markdown Mirror syntax/export work out of the two-way sync branch while leaving file-to-DB sync behavior behind.

Details:\n- add docs/logseq-markdown-syntax.md and update ADR 0016 with the one-way mirror syntax contract\n- export mirror files with page id markers, property list items, nested default property values, node page refs, task status markers, and datetime values with time\n- preserve block refs as uuid links where needed while keeping page/node refs readable\n- update focused export and markdown mirror tests

Validation:\n- bb dev:lint-and-test
2026-05-08 10:58:45 +08:00
scheinriese
8940bc9d8a feat: avatar fallback (letters | icon) + ghost-chip band polish
Adds a Fallback dimension to avatar icons (:letters | :icon) with
inheritance through `:logseq.property.class/default-icon`. When the
fallback is :icon, the avatar renders the chosen tabler icon instead
of initials, color-inheriting from the contrast-adjusted muted tint.

Highlights:
- normalize-icon enforces an invariant on both fast and slow paths:
  a :fallback-type :icon without a non-blank :fallback-icon degrades
  to :letters, so the renderer never has to guard.
- get-node-icon extends class-default select-keys to propagate
  :fallback-type and :fallback-icon alongside :shape.
- Both the text-only avatar branch and avatar-image-cp dispatch on
  :fallback-type. Tabler icons render at ~55% of avatar size with
  the fallback's contrast-adjusted color.
- New Fallback row in the customize band with a ghost-chip dropdown.
  Selecting "Letters" commits inline; selecting "Icon…" opens a
  constrained sub-picker (only the Icons tab) anchored on the click.
- Generic addition: icon-search now accepts an :allowed-tabs prop
  that filters the tab strip and seeds *tab to the first allowed
  entry. Useful beyond fallback (any caller wanting a scoped picker).
- Reset link now clears Shape AND Fallback together, dropping any
  dormant :fallback-icon. Disabled when state matches default.

Polish:
- Avatar font-size scales up past 32px (16px @ 40px tile, 22px @ 56px
  tile, ~40% of size for larger). Page-icon and band preview now
  read as proper avatars instead of small text in big circles.
- Customize band labels match Settings panel style (text-sm
  font-medium leading-5 opacity-70).
- preview-meta gets min-height: 56px + justify-content: center so
  the resting "Title / subtitle" sits centered against the avatar.
- Ghost-chip aesthetic: dropdown chips drop background and border at
  rest (1px transparent border keeps geometry stable), revealing
  fill on hover and Radix's data-state="open". Label and value share
  the same 14px text-sm so each row reads as one "Shape: Circle"
  line — Linear/Notion settings panel register.
- Tighter row geometry: 26px chip × 2 + 4px gap = 56px exact match
  against the avatar tile. No more overflow tail under the avatar.

Tests: 16 new assertions across 6 deftest groups (legacy default,
round-trip, :icon→:letters degradation, blank-icon edge case,
top-level legacy keys, full multi-field coexistence). 26 total
icon test assertions, all passing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 01:12:19 +02:00
scheinriese
c85e8e5588 feat: avatar shape + customize band in asset-picker
Adds a Shape dimension to avatar icons (circle | rounded-rect) with
inheritance through `:logseq.property.class/default-icon`. Surfaced via
a tap-the-preview customize band in the asset-picker (avatar mode) with
a Shape dropdown and a keymap-style Reset/Done rail. Animates open/close.

Highlights:
- normalize-icon defaults `:shape :circle` for legacy data on both the
  slow path and the already-shaped fast path.
- get-node-icon extends class-default `select-keys` to propagate :shape.
- avatar.tsx accepts `data-shape`; CSS in icon.css drives the radius via
  `[data-shape="rounded-rect"]` selectors (avoiding Tailwind JIT issues
  with conditional arbitrary-value classes).
- Customize band: preview tile + Shape dropdown + Reset/Done rail. All
  blocks always rendered so CSS transitions can interpolate height,
  gradient, and the cue badge crossfade. Layout matches Paper artboard
  99K-1 / 97A-1 (344px inner content inside 380px band, inset rail
  separator, gradient flush against topbar).
- Fixes `keep-popup?` plumbing at three forwarding wrappers (asset-
  picker, icon-search, icon-picker) and the topmost on-chosen handler
  in property/value.cljs. Single click now produces a single write
  instead of the prior triple-write race.
- icon-row (property/value.cljs) and icon-search (icon.cljs) both made
  reactive via model/sub-block — so in-popup commits update the picker
  preview/chip live, not just the page-header avatar.
- Lazy `*text-measure-ctx` so the namespace loads in the Node test
  runner (was previously blocking all icon tests).
- New `.lx-toolbar-action` / `.lx-toolbar-reset-link` utility CSS
  mirrors Settings → Keymap shortcut popover footer styling.
- 10 new test assertions for shape default, preservation, fast-path
  handling, and field independence.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 00:26:49 +02:00
scheinriese
502e91fef1 feat: row icons in tables + batch Set icon button
Adds an icon prefix to the Name cell of class-instance tables and a
batch Set icon button to the row-selection action bar. Avatar/text
initials are derived per row, so batch-applying an avatar to multiple
rows yields each row's own initials while preserving picker colors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 16:57:53 +02:00
scheinriese
d19310bd64 feat: legible avatar fallbacks + class default-icon row
Avatar fallback rendering: replace the prior 31.4%-alpha background
treatment, which silently rendered dark picks (#1a3d60 etc.) at ~1.1:1
contrast on dark surfaces. The new pipeline computes a hue-preserving
muted tint for the bg via OKLCh L bisection (~1.5:1 vs page surface)
and runs the picked color through adjust-for-contrast (3.0 target) for
the initials. Picked color passes through as text whenever it reads;
only genuinely-illegible picks get lifted, and the lift stays close
to the picked hue. Works for both custom hex picks and Radix theme
tokens (var(--rx-...)) via a new colors/->hex CSS-color resolver.

The 3.0 target — instead of WCAG 4.5 body-text — treats avatar initials
as decorative identifiers (matches Slack/Linear/GitHub practice) and
lets vivid hues like tomato and red pass through without desaturating.

Class default-icon row: new property row that uses the unified icon
picker in default-icon mode, where Text/Image tiles commit immediately
rather than drilling into sub-pickers (per-instance inheritance derives
the actual face from each instance's title). Setting a class's page
icon now auto-syncs into default-icon when default-icon is empty so
instances inherit it; clearing the page icon only clears default-icon
if the two were synced.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 16:43:10 +02:00
Tienson Qin
f7ff5301fa fix: should never retract asset remote-metadata 2026-05-07 21:47:34 +08:00
charlie
7018f62bf7 fix(ux): incorrect keyboard navigation for installed themes 2026-05-07 21:24:22 +08:00
scheinriese
b2bf734976 feat: replace asset-picker action bar with footer hint
The floating URL+Upload buttons are the last UI in the picker still
pushing users toward an explicit URL-name dialog; paste and Web Image
flows already auto-derive names. Replace them with a thin static
footer ("Tip: Drop an image, paste a link, or browse · ⌘V"), delete
the url-asset-pane popover entirely, and fix URL-paste naming to use
extract-filename-from-url instead of clipboard-{timestamp}. Phones
get a parallel hint where each verb is a real control (iOS Safari
won't deliver paste events to non-input popover roots).

Also: title+caption styling for the Wikipedia tooltip to match the
color-picker contrast tooltip, and remove the 56px grid bottom
padding that previously cleared the floating bar.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 14:23:05 +02:00
charlie
7306cc8916 feat(ui): add open folder action for repository context menu 2026-05-07 20:14:07 +08:00
scheinriese
e1dd2bec90 feat: color picker in asset-picker topbar (Avatar mode)
The icon-picker's color swatch only lived at level 1 — to recolor an
avatar from inside the asset-picker the user had to click Back, recolor,
then drill into Custom > Avatar again. Surface the same trigger in the
asset-picker topbar so the round trip collapses to one click.

- Trigger renders only when mode = :avatar; image assets aren't tinted
  so showing it in Image mode would be misleading. Toggling segment to
  Image dismisses an open color popover by id (:asset-picker-color) so
  it doesn't orphan over an unrelated topbar.
- The color-picker component itself is unchanged besides accepting an
  optional :popup-id opt and threading it into shui/popup-show!. The
  asset-picker observes the same `*color` rum atom the icon-picker
  topbar uses, so backing out reflects the new color in the parent
  immediately — no state duplication.
- Hover-preview wired through preview-target-db-id, same as the parent.
- Layout: bundles color + trash inside `.asset-picker-topbar-actions`
  in the topbar's right grid cell. Class is intentionally distinct from
  `.asset-picker-actions` (the floating bottom bar with "Add image via
  URL" / "Upload image"); reusing the latter would inherit its
  `position: absolute; bottom: 0` and yank the topbar group off-screen.

Forward-declares `color-picker` near the asset-picker so the
top-to-bottom CLJS compile resolves the call site at line 3375 even
though the definition lives at line 5042. Without the declare, CLJS
emits a direct property reference that's undefined at runtime, the
`(color-picker …)` call throws, and the entire `.asset-picker-topbar-
actions` subtree fails to mount (which manifested as both the color
trigger AND the trash going missing).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 13:39:14 +02:00
scheinriese
749a032d04 feat: persist asset attribution metadata
Adds four asset-scoped properties so Logseq can keep the provenance of an
image alongside the file:

- :logseq.property.asset/source-url — Wikimedia descriptionurl, Wikipedia
  page, or any user-supplied source link. Queryable; this is the join
  key the asset-picker uses to dedup web-image hits against the local
  library.
- :logseq.property.asset/source-name — short label ("Wikimedia Commons",
  "Wikipedia", etc.). Queryable.
- :logseq.property.asset/license — license slug (CC-BY-SA-3.0 etc.).
  Queryable.
- :logseq.property.asset/attribution — full credit string for embed/
  export contexts. Not queryable.

Schema bumped 65.26 → 65.29 with three migrations:

- 65.27: register the four new properties.
- 65.28: an in-development DB hit a build that registered source-url
  with :type :url (a ref-typed schema), which made datascript treat
  plain URL strings as tempid lookups and blocked every asset save with
  "Tempids used only as value in transaction". Coerces the entity's
  :logseq.property/type back to :string.
- 65.29: 65.28 corrected the type but left :db/valueType :db.type/ref on
  the same entity. In Logseq's datascript fork the :db/valueType on a
  :db/ident-keyed entity IS the live schema, so the attribute stayed
  ref-typed and string URLs continued to fail. Retracts :db/valueType
  to release the lock; mirrors logseq.outliner.property's existing
  ref→non-ref pattern.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 13:38:54 +02:00
Tienson Qin
a256c65cbc fix: handle mirror file errors 2026-05-07 18:24:43 +08:00
Tienson Qin
0a4b59f0e0 fix: markdown mirror path collisions 2026-05-07 17:09:27 +08:00
Tienson Qin
98baff725b fix: e2e tests 2026-05-07 16:09:12 +08:00
Tienson Qin
1524621936 Merge pull request #12589 from logseq/feat/markdown-mirror
feat: add markdown mirror
2026-05-07 15:34:53 +08:00
Tienson Qin
2bda15bf56 Merge branch 'master' into feat/markdown-mirror 2026-05-07 15:32:13 +08:00
Charlie
3c2359a79e enhance(plugins): libs improvements (#12588)
* enhance(libs): add Commands proxy and unified command APIs

* enhance(plugin): improve unregistering of simple and palette commands

* enhance(plugin): add unregister functionality for plugin commands

* chore(libs): add logseq.Commands API guide and implementation

* enhance(libs): introduce LSPluginNet for HTTP client functionality

* fix(ipc): ensure proper handling of IPC messages and improve plugin call structure

* enhance(libs): add HTTP methods (GET, HEAD, POST, PUT, PATCH, DELETE) and error handling

* enhance(api): support additional identifier types for opening blocks in sidebar

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-07 15:21:48 +08:00
Tienson Qin
cb0c961998 fix: isolate editor async test state
Keep editor async tests pinned to their test graph and restore frontend state so full cljs:run-test order does not leak into persist-db tests.

Issue: https://github.com/logseq/db-test/issues/821
2026-05-07 14:59:03 +08:00
Tienson Qin
fae97c8003 Merge branch 'master' into feat/markdown-mirror 2026-05-07 14:07:23 +08:00
Tienson Qin
7e7d9dd81f fix: flaky tests 2026-05-07 14:06:58 +08:00
charlie
66b1140fc9 feat(markdown): enhance markdown block formatting and handling for quotes, code, and headings 2026-05-07 13:54:51 +08:00
Tienson Qin
46227b05eb fix: queue tab for pending new block
Fixes rapid Enter then Tab applying indentation to the previous editing block while the newly inserted block is still pending.

fixes https://github.com/logseq/db-test/issues/821
2026-05-07 13:23:21 +08:00
rcmerci
6ddf90732d enhance(skill): add logseq-review-workflow 2026-05-07 12:43:58 +08:00
rcmerci
58cf05dc39 enhance(skill): update logseq-repl 2026-05-07 11:13:00 +08:00
rcmerci
a772e6582b fix: render mhchem reaction arrows correctly 2026-05-07 10:48:43 +08:00
rcmerci
5301d39f07 fix(db-worker): compare repo-name failed sometimes because of db-version-prefix 2026-05-06 23:03:11 +08:00
Tienson Qin
575ddecced fix: ci 2026-05-06 22:05:20 +08:00
Tienson Qin
a973c4fb85 fix: speed up large graph search 2026-05-06 21:38:04 +08:00
Tienson Qin
5bc8fafb1b fix: debounce search results 2026-05-06 21:38:04 +08:00
Tienson Qin
e47539398b fix: speed up worker search 2026-05-06 21:38:04 +08:00
rcmerci
028ac07348 enhance(skill): update logseq-repl 2026-05-06 21:14:22 +08:00
rcmerci
a610925bca fix(export): ignore legacy-property 2026-05-06 21:03:23 +08:00
Tienson Qin
8bc8c435ba Merge branch 'master' into feat/markdown-mirror 2026-05-06 20:47:32 +08:00
rcmerci
c6d21e2006 fix(db-worker): protect db-worker server-list writes 2026-05-06 20:37:38 +08:00
Tienson Qin
56494fdb05 add js hints 2026-05-06 19:10:54 +08:00
Tienson Qin
971ccf21f1 update AGENTS.md 2026-05-06 19:04:08 +08:00
Tienson Qin
7c339462d0 fix: keep latest title sync conflict
Store only the latest non-empty server :block/title conflict for a block, clearing previous title conflict candidates before inserting the new one.

Add a regression test covering previous title candidates, empty server titles, and the latest non-empty title.
2026-05-06 19:02:39 +08:00
Tienson Qin
1ed14885cd doc: move old adr to archive 2026-05-06 17:57:40 +08:00
Tienson Qin
aeacf2ad8e fix: shouldn't use catch for promise 2026-05-06 17:42:49 +08:00
Tienson Qin
0980e63711 fix: improve rtc asset sync status
Normalize browser asset paths through the same memory URL flow used by renderer asset IO so graph names with spaces resolve correctly during RTC upload.

Handle async asset read failures in upload as read-asset failures, and surface queued asset uploads plus active asset upload/download counts in the RTC indicator.

Tests cover browser asset path normalization and RTC asset transfer summaries.
2026-05-06 17:40:49 +08:00
Tienson Qin
a111602d7b chore: add debug log for pending txs not push when ws reconnect 2026-05-06 17:00:42 +08:00
Tienson Qin
5b929b1f79 fix: sync markdown mirror graph setting 2026-05-06 16:06:37 +08:00
Tienson Qin
4bde9e0111 fix: enable markdown mirror per graph 2026-05-06 16:06:37 +08:00
copilot-swe-agent[bot]
94f2cbc5f6 fix: delete old mirror path on rename when new path content is unchanged
Agent-Logs-Url: https://github.com/logseq/logseq/sessions/9db79397-9189-4b9b-a75c-ec333a6ca7b5

Co-authored-by: tiensonqin <479169+tiensonqin@users.noreply.github.com>
2026-05-06 16:06:37 +08:00
Tienson Qin
9189755b3a fix: update markdown mirror 2026-05-06 16:06:37 +08:00
Tienson Qin
06dbef8715 feat: add markdown mirror
Add markdown mirror generation for DB graphs, including page and journal paths, regeneration, debounced write handling, and settings UI.

Serialize page and block property values into mirrored Markdown by resolving property-value entities to their display content.

Persist mirror files through the node worker platform and make browser worker mirror storage fail fast as unsupported.

Fix Electron userAppCfgs writes to avoid returning unserializable Electron state over IPC.

Add ADR and targeted tests for mirror generation, worker wiring, platform storage, and graph path handling.
2026-05-06 16:06:37 +08:00
rcmerci
7a731c6044 enhance(cli): render block/link in show 2026-05-06 15:29:01 +08:00
PlunderStruck
3b7bc2e5d8 dev: remove developer command cycle 2026-05-06 08:15:04 +08:00