Files
Simon James b54a3139c7 Initial commit: Qortal Web Builder monorepo.
Includes QWB, Qortal Web, and Q-Shops Q-Apps with shared packages and build scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 12:17:29 +00:00

211 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QShops changelog
## 0.0.44 — 2026-05-01
- **Fix `paymentOverlay is not defined`:** Restored **`useState`** for **`paymentOverlay`** and **`invoiceInspect`** (they were dropped during an earlier edit). Payment overlay and invoices work again.
## 0.0.43 — 2026-05-01
- **Blank Hub / “only theme”:** When no shops or products are in memory yet (cold directory, slow QDN), the main column could be **completely empty**. A **Marketplace** panel now always shows **loading** or **how to proceed**, plus the live **status** line.
- **Crash visibility:** **`QshopsErrorBoundary`** wraps the app so a mount/render error shows a message instead of a blank screen.
- **First paint:** **`data-qshops-theme="dark"`** on `<html>` in `index.html` so CSS variables apply before React runs.
## 0.0.42 — 2026-05-01
- **Fix blank Hub view:** Persisted browse tab **`orders`** without a loaded wallet left **no catalog and no orders panel** (only the dark page background). **Cold start** no longer restores **`orders`** from `localStorage`; **`useLayoutEffect`** resets **`orders``products`** when the wallet disconnects; unauthenticated **My orders** shows a short sign-in hint instead of an empty column.
## 0.0.41 — 2026-05-01
- **Post-pay Q-Mail / `GET_ACCOUNT_DATA`:** `tracedQReq` now uses **`qReqLong`** (same bridge as checkout) with **180s** race default. Shop owner / buyer **public keys** load with **`GET /addresses/{addr}` first** (guide §5), then Hub `GET_ACCOUNT_DATA` only if needed — avoids **10s “no response”** right after approving **`SEND_COIN`** when the Hub is still busy.
- **Payment vs QMail:** If the **wallet transfer succeeds** but **DOCUMENT_PRIVATE + MAIL_PRIVATE publish fails**, the overlay explains **payment vs seller notification** (no longer looks like the payment itself failed). Invoices show **Paid — verify in Hub** when there is **no tx reference** instead of a bare “Confirmed”.
- **My orders:** **Full in-app page** — toolbar tab **My orders** (with count) replaces the old modal; list + hint live in the main column. Invoice detail stays a modal.
## 0.0.40 — 2026-05-01
- **Shops gallery:** Shop intro / description (`.qs-shop-card__intro`) is **center-aligned**, with a **theme-aware panel** behind it (opaque dark teal scrim in dark mode, soft white in light mode) so text stays readable over **hero** imagery and on plain cards.
## 0.0.39 — 2026-05-01
- **Hub bridge (critical):** Added **`hasQortalBridge()`** — treats **`qortalRequest`**, **`qortalRequestWithTimeout`**, and **`qortalRequestWithNoTimeout`** on `window` / `parent` / `top` as a valid bridge. **`getQortalRequest()` alone** missed timeout wrappers, so **`refreshUser` / save-shipping / pay** could think the API was **missing** while **`qReqLong`** would have worked — no approval UI, no account.
- **Checkout pay:** **`SEND_COIN` / asset transfer** runs **before** closing cart/checkout (no prepayment **rAF + 80ms** delay). Checkout closes **after** Hub returns success.
- **`SEND_COIN`:** After the numeric payload, tries **`amount` as an 8decimal string** (some Hub builds are strict).
- **CSS:** Fixed **orphaned rules** under `.qs-catalog--list .qs-card__list-body` (list layout + text column).
## 0.0.38 — 2026-05-05
- **Qortal bridge (critical):** `qReq` / `qReqLong` now resolve **per window** (iframe → parent → top): on each context, **`WithTimeout``WithNoTimeout``qortalRequest`**. Previously we picked the **first** context that had **`WithTimeout`**, so if **only the iframe** exposed `qortalRequest` (Hub/stub) but **parent** had `WithTimeout`, calls went to the **wrong** bridge and **payments / QDN publish could fail silently** (see Q-Apps guide: always wire **`qortalRequest`** correctly).
- **Catalog list view:** Product image column **stretches full row height** (left strip **cover**-fills topbottom), fixed width **102px** (**80px** narrow).
## 0.0.37 — 2026-05-05
- **Qortal bridge (payments):** `qReqLong` now tries **`qortalRequestWithTimeout` / `WithNoTimeout` on parent/top before** requiring `qortalRequest` on the iframe — matches QWB and fixes cases where **`SEND_COIN` / `GET_NAME_DATA` never ran** because only the long-path helper was installed.
- **Recipient lookup:** `resolveNameOwnerAddress` uses **`qReqLong`** (same as storefront) instead of short **`qReq` + 25s race**.
- **UX:** Removed **`pointer-events: none`** on the main shell during pay and on checkout while saving — those layers **froze the UI** and could block Hub interaction. User chip shows the **name on one line** (ellipsis + tooltip); masthead **Q-Shops · Changelog · theme** stay on **one row** to the right of the title.
- **Checkout:** Button label **Save shipping details**; copy explains **local cache vs QDN publish** (Fill works from browser cache without re-approving).
## 0.0.36 — 2026-05-05
- **Shops gallery:** Each shop window shows a **full-width logo** at the top, then the intro over up to **three product photos** (split hero + scrim) for a unique look per catalog. Identity row uses the **catalog shop name**, with **@{website}** and product count below (publisher avatar). Search includes **shop name**.
- **Catalog list view:** Product thumbnails are **square** (**88×88**, **76×76** on narrow screens) with **`object-fit: contain`** + small inset padding (same treatment as **grid** cards), sized smaller than typical grid cells.
## 0.0.35 — 2026-05-01
- **Masthead:** **Changelog** and **theme** sit on one row **after** the **QShops** title (with the logo); the title cluster is **centered on small screens** and **left-aligned** on wide layouts.
- **Identity:** User chip shows the **full Hub primary name** when available (no ellipsis); name can wrap inside a wider chip.
- **Hub approval (publish & pay):** While **saving shipping to QDN**, the checkout layer uses **`pointer-events: none`** so the Hub publish dialog can receive input (same idea as QWB — **no modal above the signer**). **Pay** closes **cart + checkout**, clears the **preSEND overlay**, and the **shell** yields pointers during **`payBusy`** so **`SEND_COIN` / asset transfer** prompts are not trapped under the QApp iframe UI.
## 0.0.34 — 2026-05-05
- **Hub payments:** Full-screen payment overlay used **z-index 200000** and **captured all clicks**, so the **`SEND_COIN` / asset-transfer** signer could sit **under** the dimmer inside the Q-App iframe. While waiting on the Hub, the overlay now uses **`pointer-events: none`** (`.qs-pay-overlay-back--yield-signer`) and a lower base **z-index (~12k)** so approval dialogs receive input — aligned with QWB relying on **`qortalRequestWithTimeout`**. Same yield during **Q-Mail** batch approval.
- **Save shipping to QDN:** `PUBLISH_MULTIPLE_QDN_RESOURCES` now uses **`qReqLong`** (like other Hub-approved publishes) so the bridge routes through the **long-timeout / Hub helper** path instead of a bare `qortalRequest` that can skip the signer UX on some builds.
- **Profile UX:** **`pickupNotes`** included in the encrypted document; **optimistic `localStorage` cache** before publish so **Fill my details** works immediately; **fetch-on-checkout** unchanged for cross-device JSON. Messages explain Hub approval vs local cache.
## 0.0.33 — 2026-05-05
- **Catalog sync:** Live SEARCH merges **replace** each publishers manifests (so listing **prices, stock, and SKUs** refresh) and **drop** shops returned with **no catalog products** — directory + live scans apply in **one** state update after each cold/widen merge.
- **Refresh cadence:** Live network scan every **~90s** (was 4m) plus a **throttled** SEARCH merge when you **return to the tab** (~45s gap).
- **List layout:** Product thumbnail column is **taller and full-bleed cover** (`object-fit: cover`) so the image **fills the box**; title and description stay in the **middle column** without overlap. **Prices** sit **centerright** in the rail; **shop avatar** sits **left of the shop name**.
- **Detail modal / options:** **Prefetch** gallery + all **variant option image** URLs when the modal opens, and **warm** neighbors around the selected gallery index; main image uses **`fetchPriority="high"`**; first gallery thumbs load **eager**.
- **Perf:** List/catalog product images use **`decoding="async"`** where shown.
## 0.0.32 — 2026-05-01
- **Checkout (QWB parity):** Delivery uses **coordinates vs street address** (street shows structured fields); **digital-only carts** keep an optional location block for the buyers records.
- **Buyer profile:** **Fill my details** (when a cached / QDN profile exists) + **Save shipping to QDN** (encrypted DOCUMENT, same identifier as QWB checkout profile).
- **Payments:** Payment overlay opens **before** closing checkout, then **two animation frames** (+ short delay) before **`SEND_COIN` / `TRANSFER_ASSET`** so Hub signer prompts are not lost to modal teardown; **`payInFlightRef`** blocks overlapping approvals.
- **Identity:** Memo field shows **read-only Qortal primary name** from the authenticated account.
- **Coupons:** Per-vendor discount field appears only when that shops manifest lists **`coupons`**.
- **Header:** Theme toggle sits **beside Changelog** in the title lockup; compact **tool row** spacing for Changelog + theme.
- **Copy:** Removed verbose checkout intros and the old multi-vendor “bundled SEND” disclaimer; **Pay all shops** wording simplified.
## 0.0.31 — 2026-05-01
- **Status line:** Scan / catalog status is centered under the toolbar (narrow column, readable in the middle of the page).
- **Checkout map:** Replaced OpenStreetMap iframe with the same **Natural Earth vector + Hub raster DEM tiles / Leaflet** stack as published QWB QShop blocks (`QsDeliveryMap`, bundled `geojson` + tile index shards under `public/`).
- **Payments:** Closing checkout waits **450ms**, then shows a **top-layer payment spinner** (“Waiting for Hub…”) during `SEND_COIN` / `TRANSFER_ASSET` — mirrors the storefront UX so modal stacking does not swallow the signer.
- **QMail receipts:** Successful Hub payments trigger **`sendQshopPaymentReceiptQmail`** (same DOCUMENT_PRIVATE + MAIL_PRIVATE batch as QWB/`qsOrderReceipt.ts`).
- **Digital goods:** `qortal://FILE/…` lines resolve per variant/product (`digitalManifest`) and download via ported **`triggerQShopFileDownload`** Hub/REST/mobile fallbacks (`qshopsFileDownload.ts`).
- **My orders:** Header **My orders**, persisted per wallet (`localStorage` `qshops-app-v026-myorders`): open invoice view (QWB-parity markup/CSS), payment ref, totals, **re-download digital files**.
- **`GET_USER_ACCOUNT.publicKey`** + **`writeGateNamesCacheForAddress`** after name lookup improves Q-Mail publish name resolution parity.
## 0.0.30 — 2026-05-01
- **Automatic directory curator tracking:** Every publisher whose merged index includes a **`qwb-qshops-catalog-v1`** manifest (QWB QShop block) is **`prependTrackedDirectoryCurator`**d in the background so the next `fetchRemoteDirectorySnapshots` pass **tries that registered names** `.__qwb__/qshops-directory-snapshot.json` **first** (alongside SEARCH). Applies to network scan merges, registered-name supplement loads, saved-name merge, and the cold-start **localStorage** snapshot once the Hub bridge is present.
- **Fetch order:** Successful snapshot DOCUMENT parses now **prepend** the curator name instead of only appending — frequent / important curators stay near the front of the bounded list.
- **UI removed:** The **“Other hubs show only their own shop?”** manual curator panel and **“Publish merged directory to QDN…”** flow (and the post-merge “new listings” publish modal). **Shared directory updated on QDN** refresh prompt, fingerprint polling, and **BroadcastChannel** hints from other tabs are unchanged.
- **Dead code:** Dropped unused directory helpers (`mergeTrackedDirectoryCuratorNames`, `persistTrackedDirectoryCuratorsFromRawInput`, `jsonToData64`) from `directorySnapshot.ts`.
## 0.0.29 — 2026-05-01
- **Publishing hubs vs SEARCH:** Hubs that publish QWB WEBSITE blocks often get QDN SEARCH results that emphasize **their own** DOCUMENT hints for quite a while, so the app never **saw another curators** merged `qshops-directory-snapshot-v1` DOCUMENT. Then the federated fingerprint never changed and **“Shared directory updated” could not appear** on those nodes until SEARCH widened.
- **Direct curator fetch:** `fetchRemoteDirectorySnapshots` now unions **SEARCH hits** with a **persisted list of curator registered names** and **FETCHes those DOCUMENTs by name** (prioritizing tracked names, cap 96 per pass). Every successful merged snapshot loaded from a curator **augments** that list (bounded). Publishing a merged directory under your chosen name **adds your name** to the tracked set automatically.
- **UI:** Collapsible panel under the status line — paste comma-separated curator name(s), **Save list & merge catalogs**; persists in `localStorage` (`qshops-app-v003-directory-curator-names`). Use the **registered Qortal name** of whoever published the shared directory DOCUMENT (often the hub that successfully merged everyone).
## 0.0.28 — 2026-05-01
- **Header:** Theme toggle stays on the **same row** as Authenticate / user chip / Cart (`qs-masthead__tools-row`, no wrap on account cluster).
- **Catalog cards:** Fixed grid shop strip so **avatar + shop name** stay **horizontal** (CSS order after base); list + grid show **display name only** (no `@publisher` line on cards).
- **Cart / detail:** **Add another** replaces the disabled “Added…” state (detail modal + quickadd). Cart line **thumbnails** ~34% larger; summary **spacing** and label **Estimated subtotal** (removed parenthetical); new **`.qs-cart-summary-*`** layout rules.
- **Checkout:** Vendor block uses **avatar only** (logo `<img>` removed); slightly larger avatar tile.
- **Directory UX:** After you **publish** a merged snapshot, the app **reseeds the remote fingerprint** so you are not immediately nagged to refresh; refresh action **closes the dialog first** and runs merge in the **background** (no long “Refreshing…” freeze). **Fingerprint poll** ~90s. **localStorage** snapshot **v022** — skips persisting a **single-shop** index in the **first 3 minutes** to avoid freezing a partial mesh view; **~2.75 min** one-shot **widening** merge if only one shop still shows. **QDN HTTP search** span for **DOCUMENT** scans increased to pull more mirror/directory hits on sparse publishing hubs.
## 0.0.27 — 2026-05-01
- **Readability:** Product and shop snippets that ship as HTML (**card excerpts**, **detail/shipping tabs**, shop intros) inherit **theme foreground** so merchant inline colors no longer disappear on dark mode; links stay **accent**.
- **Product modal:** Shop **logo** shows top-right beside **Close**; header line shows shop display name · `@publisher`.
- **Catalog chrome:** Removed per-card **shop logo** from grid/list; grid keeps **name avatar → shop name**. List layout is **title + excerpt | avatar + shop + prices** on one row; **View more** / Quick add sit on a **footer row** aligned bottom-right.
## 0.0.26 — 2026-05-01
- **Directory updates:** Prompt to **refresh the catalog** when remote **`qshops-directory-snapshot-v1`** curator DOCUMENTs change versus the last merged layer (polling QDN fingerprints ~2½ min + **`BroadcastChannel`** hint after **Publish merged directory** so **other tabs** in the same browser can react). **`Later`** snoozes that fingerprint until something newer appears.
- **Publishing hubs:** Extra **merged directory + SEARCH** passes at ~44s and ~118s to mitigate SEARCH returning only your shop first; bumped **`LS_DIRECTORY_SNAPSHOT`** to **`v021`** so older local aggregates do not dominate the initial index.
## 0.0.25 — 2026-05-05
- **Sub-page storefronts:** QWB ships one `index.html` but the **`sn-embed-config`** JSON always includes **`pages[].blocks`**. Aggregator ingestion now **merges** explicit catalog `<script>` tags with catalogs **reconstructed from that embed**, so shops that live only on a sub-page still appear if script-tag extraction misses them.
- **Taxonomy:** `QSHOP_MARKETPLACE_TAXONOMY_VERSION` exported alongside category slugs (must stay aligned with QWB manifests).
## 0.0.24 — 2026-05-05
- **Cold start latency:** Peer **`qshops-directory-snapshot-v1`** DOCUMENT layer **merges as soon as it returns** instead of waiting for the full WEBSITE crawl to finish (`Promise.all` merged both before any UI merge).
- **Throughput:** DOCUMENT mirror prefetch and curator snapshot fetches use **bounded parallel pools** (~14 mirrors, ~12 snapshot DOCUMENTs); WEBSITE HTML/`website.zip` fetches parallelize at **~8** with per-request Hub timeouts unchanged.
- **Refresh cadence:** The post-open catch-up scan runs at **~9.8s** and only **`scanNetworkForCatalogs`** (no duplicated heavy snapshot crawl).
- **QWB alignment:** Merchants publishing from QWB now ship **mirror + shared directory DOCUMENT** only (duplicate `qshops-catalog-feed.json` removed); QShops still probes the legacy feed path for older publishes.
## 0.0.23 — 2026-05-01
- **Cross-node directory:** Publishing the merged catalog uses **`qReqLong`** so Hub approval for `PUBLISH_QDN_RESOURCE` is less likely to time out.
- **QWB alignment:** Merchants who publish a WEBSITE with QShop blocks also ship a **`qshops-directory-snapshot-v1`** slice in the same batch (see Qortal Web Builder); QShops merges those DOCUMENTs with live scans.
- **UI:** Removed the expandable “About the global QShops directory” note; added an optional **Publish merged directory to QDN…** action when you are signed in and the index has products.
## 0.0.22 — 2026-05-01
- **Grid**: shop avatar left of shop **name block** (`shopName`/title + `@publisher`), logo pinned on the **right**.
- **List/grid images**: tighter list thumbnails (~⅓ narrower column); text column **shields** product title & prices; hover **zoom** (~1.05×) on product images (`contain` unchanged).
- **Product detail**: **Add to cart** leaves modal open → gold **Added to cart** state + **View cart**.
- **Cart**: compact **centered** lines with tiny thumbs.
- **Checkout**: removed standalone map launcher row; optional **WORLD map OSM** embed unchanged; **pershop discount code** wired to **`catalog.coupons`** (republish WEBSITE with updated QWB to embed coupons in manifest).
- **Pay this shop**: **closes checkout briefly** before `SEND_COIN` so the Hub signer is not stacked under the modal; **SEND_COIN** payload aligned with published QWB storefront.
- **Shipping**: pervendor options use the **union** of tiers declared on catalog lines from that merchant (still one selected tier for the payment memo).
## 0.0.21 — 2026-05-01
- **Federation UX:** clarified that indexing uses **network QDN SEARCH** (not “this node only”); expandable **About the shared directory** note under the status line explains snapshots vs live scan.
- **Cold start:** first load and the **26s retry** now run **`fetchRemoteDirectorySnapshots` in parallel with `scanNetworkForCatalogs`** and **union-merge** into one index update so peer-published `qshops-directory-snapshot-v1` files and raw SEARCH hits apply together.
- **Discovery throughput:** Hub SEARCH paging cap **`MAX_BRIDGE_PAGES` 8 → 12**; broader snapshot SEARCH when loading curator DOCUMENT aggregates.
- **Publish prompt copy:** stresses that DIRECTORY snapshots help **other people on other nodes** hydrate faster.
## 0.0.20 — 2026-05-01
- **Cart** modal: thumbnails, line QORT/asset hints, estimate subtotal summary.
- **Checkout** modal: contact + delivery fields, ship vs pickup (non-digital carts), coordinate textarea with **OpenStreetMap** preview (`QsCheckoutMap`), **World Map / catalog map** deep-link, per-vendor **avatar + logo**, shared **shipping-method** radios where applicable, pay buttons use **`payBusy`** plus **Pay all shops (sequential)** for multi-vendor.
- **Product detail**: add-to-cart closes the modal without opening checkout (same as quick-add flow).
- **Catalog CSS**: grid thumbnails **square · contain** full product image; **list cards** stay side-by-side on narrow viewports (**horizontal scroll** instead of stacking); **Added to cart** green state.
- WEBSITE links keep opening via **`qortal://`** in a new Hub window/tab (`openWebsiteInNewTab` / `openInNewHubWindow`).
## 0.0.19 — 2026-05-01
- Masthead ordering + conditional cart; local + remote directory snapshot hydrate; discovery publish modal; min/“From” pricing; digital category fallback; list layout tweaks; broader WEBSITE SEARCH.
## 0.0.18 — 2026-05-04
- **Catalog cards:** merchant logo under product image; **single published WEBSITE name** on the row.
- **List view:** **compressed layout** — uniform small square covers and tighter shop strip.
- **Discovery:** higher SEARCH paging caps + **registered-name ingest** when your own WEBSITE is missing from the index.
## 0.0.17 — 2026-05-04
- **Add to cart** plays a **vortex-style fly** of the product thumbnail into the **masthead cart** chip; **Cart** stays visible next to **Authenticate** / user name (including when the cart is empty).
- **Listing image** opens product details (**View more**) on click; **Quick add to cart** appears only when the product has **one or no** catalog option — multi-variant listings only show **View more**.
## 0.0.16 — 2026-05-01
- **Discovery** is driven by **network scan + saved names list** only — wallet / primary name no longer triggers an extra ingest pass (avoids “only my alt names” skew).
- **QWB manifest** carries optional **`shopIntroHtml`** (Q-Shop storefront **Intro** rich text). Shops cards and focused shop banner show that copy; **logos / avatars** use the same **QDN media resolution** as product images.
- **Product grid:** **5 columns** (responsive), **grid/list** toggle (persisted), **seller thumbnail** on each card, **hover zoom** on covers (respects reduced motion).
- **Detail modal:** clicking a **gallery thumbnail** selects the **matching variant** when the image matches a variant row.
## 0.0.2 — 2026-05-03
- Network scan always FETCHes **`index.html`** per publisher from QDN search results (plus SEARCH row identifiers); catalog manifests from current QWB are embedded in that static file.
- Minor discover/docs alignment with QWB WEBSITE zip publish.
## 0.0.1 — 2026-05-03
Initial standalone Q-App (separate from Qortal Web Builder) that aggregates **published QWB Q-Shop** catalogs from QDN.
### Features
- **Manual authenticate** in the masthead (`GET_USER_ACCOUNT` on demand). Browse and index without signing in; after login, primary name + QDN **THUMBNAIL** avatar appear in the header.
- **Index by publisher**: load `index.html` for each WEBSITE name listed in the textarea; parse embedded **QWB Q-Shops catalog manifests** (`qwb-qshops-catalog-v1`), including optional **`shippingFlatQort`** for simple QORT shipping totals.
- **Scan whole QDN**: searches WEBSITE resources referencing the manifest marker and fetches HTML candidates (`SEARCH_QDN_RESOURCES``FETCH_QDN_RESOURCE`).
- **Search & filters**: quick search on titles and metadata; **deep search** adds product description excerpts; taxonomy category, availability, featured / bestseller, tag chips, sort, QORT price min/max — aligned with common QWB Q-Shop filter surface.
- **Multi-vendor cart** persisted locally; **checkout grouped by merchant** (`publisher` + shop `blockId`) with Hub payments:
- **QORT**: `SEND_COIN` to `GET_NAME_DATA(publisher).owner`, memo includes buyer labels.
- **Store Q-Asset** (when the catalog declares `storeAltAssetId`): optional checkbox per merchant group tries `TRANSFER_ASSET` / `SEND_PAYMENT` (**shipping in asset mode is omitted** until catalog exposes asset shipping in the manifest).
- Listing cards link to **`qortal://WEBSITE/<publisher>`** with WEBSITE title + logo from `sn-embed-config` where present.
### Qortal Web Builder prerequisite
Rebuild and republish **WEBSITE** zips **after** pulling the matching QWB change that embeds the catalog `<script type="application/json" data-qwb-qshops-catalog="1" id="qwb-qshops-manifest-{blockId}">` so scanners and indexer fetches can find product JSON.