Skip to content

Discover: vee-plugins built-in store by default, live store refresh, screenshot zoom, stable card heights - #149

Merged
navbytes merged 3 commits into
mainfrom
discover-store-defaults
Aug 30, 2026
Merged

Discover: vee-plugins built-in store by default, live store refresh, screenshot zoom, stable card heights#149
navbytes merged 3 commits into
mainfrom
discover-store-defaults

Conversation

@navbytes

Copy link
Copy Markdown
Owner

Four changes to the Discover/store system:

  • vee-plugins is now a built-in store (manifest-backed via vee-catalog.json, listed before xbar) and the xbar catalog ships disabled by default on fresh installs only — a one-shot seed (vee.didSeedDefaultStores) runs before first-run completes, so existing users' store settings are untouched. vee.disablePublicStore (MDM) now hides both built-ins.
  • Store changes refresh the open Discover tab liveStoresSettingsModel.onStoresChanged closure wired through AppController to PluginBrowserModel.reload(stores:); no more relaunch.
  • Click-to-enlarge plugin screenshots — the card image opens a sheet with the full-size screenshot (Esc closes).
  • Scroll jank fixed — every image phase now reserves the same fixed height, so cards no longer jump as screenshots load mid-scroll.

Gate: build clean, 1,273 tests / 0 failures across all 12 bundles, swiftlint --strict clean. New tests cover seeding (fresh-only, once-only, existing-install-untouched), built-in ordering/immutability, live reload, and fixed card heights.

…t on fresh installs

vee-plugins publishes a curated vee-catalog.json manifest, so it's added as a
manifest-backed .http built-in (not .github — that kind skips its manifest
probe for isBuiltIn stores, a fallback meant for xbar's zero-config git-tree
convention) and listed before xbar in Discover's default order.

xbar stays enabled for existing installs but ships disabled on a genuinely
fresh one, via a one-shot StoreRegistry.seedDefaultStoresIfNeeded() gated on
VeePreferences' hasCompletedFirstRun still being false — called from
AppController before first-run onboarding flips that flag. disabledIDs()
alone can't distinguish "never touched Stores" from "fresh install", hence
the separate vee.didSeedDefaultStores one-shot flag.

vee.disablePublicStore now hides both built-ins, and add/remove/update/dedup
guard against both built-in ids, not just xbar's.
PluginBrowserModel.stores/clients were private let, so an enable/disable/
add/remove in the Stores tab never reached an already-open Discover tab —
only reopening the window rebuilt it. StoresSettingsModel now takes an
onStoresChanged closure (fired by every mutator, not init — a fresh
StoresSettingsModel is built on every window open, and firing there too
would defeat the browser model's no-refetch-on-reopen caching).

AppController wires it to PluginBrowserModel.reload(stores:), a new async
method that swaps in the new store set and re-fetches in place on the same
retained instance the live view observes — no window close/reopen needed.
…load

PluginCard.preview only rendered its AsyncImage's .success phase, so a card
with a declared screenshot was 0pt tall while the image was loading/failed,
then jumped to its full height once .success landed mid-scroll. Factored the
phase rendering into PluginPreviewPhaseView, which reserves the same fixed
height across .empty (a loading placeholder)/.failure (reserved but blank)/
.success, so a card's height never changes after the image settles.

The loaded image is now a plain-style Button opening a sheet with a large
resizable AsyncImage and a close control (?/Esc) — the card itself stays
non-interactive outside its own Install/Update/View source controls.
@navbytes
navbytes enabled auto-merge (squash) August 30, 2026 01:27
@navbytes
navbytes merged commit a0f37ff into main Aug 30, 2026
7 checks passed
@navbytes
navbytes deleted the discover-store-defaults branch August 30, 2026 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant