Commit graph

572 commits

Author SHA1 Message Date
SkateSpots
4392df3202 feat(market): add low-friction new-seller safety note 2026-10-31 10:37:23 +07:00
SkateSpots
42d25818b4 fix: deterministic relay merge and privacy hardening 2026-10-31 09:54:36 +07:00
SkateSpots
2c8bd594a4 fix: harden badge links and polish small flows 2026-10-31 09:24:32 +07:00
SkateSpots
0ae4c59630 feat(ux): cordn status line, payment readiness and image compression 2026-10-30 22:00:31 +07:00
SkateSpots
f71f5eeef8 feat(ops): signed read-only relay status dashboard + HSTS/CAA hardening 2026-10-30 18:40:32 +07:00
SkateSpots
f2787d79cf ui(support): compact tabbed support page with friendlier /support alias 2026-10-30 17:13:25 +07:00
SkateSpots
b39c2ec386 fix(payments): round out profile CLINK and Lightning methods 2026-10-30 13:35:18 +07:00
SkateSpots
f95adeecf1 perf: faster shell, lazy wallet stack, serialized Amber and navigation polish 2026-10-30 13:12:06 +07:00
SkateSpots
262eb32e7c chore: audit fixes, designer stats and form FAB handling 2026-10-29 23:14:12 +07:00
SkateSpots
6746353670 feat: add Transport Lab craft with self-attested fleet profiles 2026-10-29 22:34:28 +07:00
SkateSpots
4a4f398df0 fix: fit follower stats and add grantmaker transparency 2026-10-29 21:25:08 +07:00
SkateSpots
3f35a6f3a4 feat: sponsorship opt-in and Bitcoin grantmaker inquiry 2026-10-29 20:57:43 +07:00
SkateSpots
bc1987f78c feat: sponsor-ready profiles with follow, events and audience stats 2026-10-29 20:20:49 +07:00
SkateSpots
a2ab5750ff feat: Cordn inbox, outbox, room controls and animated splash 2026-10-29 19:18:48 +07:00
SkateSpots
89e6438ee1 fix: make community joins self-healing and keep /c in the app 2026-10-29 13:27:12 +07:00
SkateSpots
65d90da26f fix: a11y labels and clearer crew-chat bell aggregation 2026-10-29 12:52:30 +07:00
SkateSpots
673bb983b8 feat: per-thread DM mute, event pass, a11y header, undo mute 2026-10-29 12:37:10 +07:00
SkateSpots
c09f1ff23d feat: event timezone clarity and marketplace retry 2026-10-29 10:37:00 +07:00
SkateSpots
8b895a4858 feat: marketplace saved searches, quick offers, safety 2026-10-29 10:27:02 +07:00
SkateSpots
7a797c0fc6 feat: frictionless first-run tip and inline mute actions 2026-10-29 10:09:50 +07:00
SkateSpots
eb7ea50702 feat: remember map view and add community first-run step 2026-10-28 22:55:27 +07:00
SkateSpots
4ae6b1d5ea feat: envelope-only DM unread in the bell 2026-10-28 22:43:52 +07:00
SkateSpots
7f0524978c feat: track unread NIP-17 group conversations 2026-10-28 18:31:45 +07:00
SkateSpots
534e939f9e feat: global command palette and scroll/layer context 2026-10-28 18:08:45 +07:00
SkateSpots
f86b7a74cf feat: show Amber prompt budget; cache service worker headers 2026-10-28 16:51:41 +07:00
SkateSpots
e94c16a479 perf: batch profiles, gate map layers, warm public cache 2026-10-28 12:42:39 +07:00
SkateSpots
66fc47cc28 feat: restore map footer, inline crew roles, Cordn reactions/push
- Keep the map footer links permanently visible; remove the hide toggle.
- Publish inline founder promote/demote from the member row.
- Add encrypted MLS reaction/delete/read control messages and UI.
- Add the minute Cordn join watcher: NIP-17 DMs + encrypted bell notices.
- Add the browser translation-matrix runner and a low-end performance finding.
2026-10-28 11:02:47 +07:00
SkateSpots
f029b5a516 feat(newsletter): weekly generated drafts, covers, and admin preview
- Add a browser-safe editorial generator with rotating satire and shipped highlights.
- Generate a fresh 1200x630 cover from the Drop #006 foundation and upload it to Blossom.
- Publish weekly drafts as NIP-78; add the admin Load draft/Preview composer flow and banner.
- Add the Monday user timer (draft by default) and a manual newsletter:weekly script.
- Remove static/live issue duplicates; translate the new admin strings to all 24 locales.
2026-10-28 09:42:44 +07:00
SkateSpots
7da67cc2c0 feat(cordn): unread and join-request badges; persist pending joins 2026-10-28 08:39:01 +07:00
SkateSpots
2ec861befd feat(community): add the app-wide Cordn room and always-on bot 2026-10-27 17:37:09 +07:00
SkateSpots
74249e304e fix(menus): move language into its own mobile view; fit crew tabs 2026-10-27 17:00:19 +07:00
SkateSpots
690c9c93bd feat(cordn): polish private chat onboarding, polling and invites 2026-10-27 16:22:25 +07:00
SkateSpots
d2a24679f0 feat(chat): on-device translation pilot (English ↔ Spanish)
- @xenova/transformers 2.17.2 in a Web Worker; Opus-MT en↔es ONNX q8 packs
  self-hosted on the relay VPS (/models + CORS); ONNX Runtime 1.14 WASM
  self-hosted in public/ort/ (37MB) loaded from ../ort/.
- Hard network guard: only model GET/HEAD (no query) and /ort/ assets allowed.
  Message text travels only via postMessage; 9 tests prove fetch is never called
  with the text and every other request is blocked.
- TranslateMessage in DMs + crew chat; Settings auto-translate off by default;
  memory-only translations; per-model download progress; 12 UI strings in all
  24 locales.
- Both model directions verified from the hosted files; tsc, 138 tests, build
  and smoke green.
2026-10-27 10:49:54 +07:00
SkateSpots
87f58cd84e feat(android): pass-the-app card (QR + share sheet + NFC tag)
About page renders ShareAppCard on Android only: a QR of the Zapstore listing,
a share-sheet button for the install link, and NfcWriteButton to write it to a
tag. Single-sourced APP_INSTALL_URL in lib/platform.ts (also used by the About
download button). No peer-to-peer APK transfer (needs native Wi-Fi Direct/BLE +
PackageInstaller + device QA); Zapstore handles install/update.
2026-10-26 11:41:51 +07:00
SkateSpots
707dcaf644 refactor(crew-chat): Chat tab is always NIP-17; widen group read window
Per the crew-chat audit recommendations:
- The crew Chat tab no longer silently switches transport on a coordinator tag.
  It is always NIP-17; coordinator routing lives only in the Private chat (MLS).
  useCordnChat / useCrewChatUnread / lib/cordn client+crypto are kept but unwired
  (headers marked). Drops the tab's Cordn-only unread dot.
- Group reads (Groups list + crew thread) widened 200 -> 500 wraps; the shared
  decrypt cache makes the extra reads affordable. 1:1 list stays 200.
2026-10-13 18:35:03 +07:00
SkateSpots
fa0fc1cc15 ux(cordn): reconcile the crew chat card with the MLS tab (+ audit)
The sidebar card badged 'Private chat - On' while the MLS tab said 'not created
yet', and led with external apps. Rewrote CrewCoordinatorCard to show two
explicit rows (Chat = NIP-17 always on; Private chat = MLS with real status) and
make the in-app chat the primary CTA (?tab=mls); demoted Cordn web / Staircase
under 'Open in another app'. Panel now gives join feedback + an admin invite
hint. Adds CORDN_UX_AUDIT.md (findings, terminology model, deferred items).
2026-10-12 23:41:29 +07:00
SkateSpots
4bdb949f06 feat(messages): Crews section in the Messages hub -> each crew's private chat
- DirectMessagesPage gains a 'Crews' block listing the viewer's crews with an
  Open/Set-up badge (from one local IndexedDB read via useCordnGroupGids),
  linking into /crew/<pk>/<id>?tab=mls.
- Crew page tabs are now URL-addressable (?tab=events|chat|mls); an explicit
  param wins over the auto-default. useUserCrews + cordnGroupGids added.
2026-10-12 23:35:35 +07:00
SkateSpots
3ae05a0c38 fix(amber): stop DM/read hooks re-decrypting on every navigation
For an interactive signer (Amber) each nip44 decrypt opens the app. The DM/NIP-17
read hooks decrypt 2x per gift wrap and DirectMessagesPage mounts two of them, so
navigating to Messages stormed Amber. Strengthened amberSafeQueryOptions for
interactive signers (staleTime/gcTime Infinity, refetchOnMount/refetchOnReconnect
false) so decryption happens once per session, mirroring useStash; same guard on
usePrivateContacts + useCordnChat. Added a manual Refresh to the Messages header
(Amber gets no polling). Gated useSyncPendingPosts' legacy re-sign loop for
interactive signers.
2026-10-12 23:28:03 +07:00
SkateSpots
bcc3eceeee Cordn native: default crew tab to the private chat + founder nudge; release 1.6.1
- Crew page defaults to the Private-chat (MLS) tab when this device already has
  the group (useCordnGroupExists reads the IndexedDB snapshot — local only, no
  signer prompt); a manual tab click always wins.
- Founder/admin banner ('Set up') points at the tab when the crew has no group.
- Bump 1.6.0 -> 1.6.1 and add release notes for everything since 1.6.0 (private
  crew chat/MLS, self-hosted relay + media, marketplace close-the-deal, trust
  controls, map/weather, Clothing Designer, UI fixes).
2026-10-12 22:52:33 +07:00
SkateSpots
383fb07127 Cordn native UI: crew MLS chat tab, IndexedDB store, membership flow
Milestone 2 for the native Cordn client.

- Session now runs on the viewer's own signer (NIP-07/Amber/nsec) instead of a
  raw key, so the Cordn identity is the user's pubkey. Added idbStore.ts
  (Dexie 'SkateSpotsCordnDB', one snapshot per account) so MLS state survives a
  reload, plus membership delivery: requestJoin / fetchJoinRequests /
  fetchWelcomes / acceptWelcome / addMemberByIdentifier, and addMember now also
  stores the Welcome on the coordinator for the target.
- useCordnNative owns the session lifecycle and lazy-imports the native module,
  keeping @contextvm/sdk + ts-mls in a separate ~678 kB async chunk (entry
  bundle unchanged at 1.9 MB).
- CordnNativePanel: a third 'Private chat' tab on the crew page — founder/admin
  create the group and approve join requests; members ask to join and check for
  an invite; live message list + composer (polling only for silent signers).
- Strings in i18n/legacy/cordnUi.ts (en/es).

Verified live against our coordinator with a new scenario
(join-request -> approve -> welcome) plus the existing two; npm test + smoke
pass. Not yet exercised in a real browser (browser tooling was offline this
session) — the dynamic-import failure path degrades to an inline error.
2026-10-12 22:30:15 +07:00
SkateSpots
b0c4684b4a feat(onboarding): first-run checklist with dynamic crew step
A one-shot 'Get started' nudge on the map for freshly signed-up users: Add a spot / crew / wallet. The crew CTA adapts to whether any crew exists yet — 'Join a crew' (/crews) when there are some, 'Start your crew' (/create-crew) when there are none. Dismissal persists; logged-out visitors see the welcome banner instead.
2026-10-12 15:15:35 +07:00
SkateSpots
54882285b6 feat(weather): 6-day forecast
FORECAST_DAYS=6 in lib/weather.ts is the single source for the fetch length and the UI labels (spot card + map popup). New count-interpolated labels spotUi.forecastDays / mapUi.forecastDays (en/es; other locales fall back to English). Legend colours moved to lib/skateabilityLevels.ts to keep the react-refresh lint at zero.
2026-10-12 13:51:29 +07:00
SkateSpots
e47c4b9d81 feat(weather): legend, refresh/error states, sunrise/sunset, reason chips
- WeatherLegend overlay on the map (only while the weather layer is on), colours mirroring calculateSkateability
- Spot weather card: freshness line + manual refresh, and an error/retry state when Open-Meteo is unreachable
- Sunrise/sunset row (weather.ts now fetches Open-Meteo daily sunrise,sunset)
- Score reasons render as chips, not a bullet-joined run-on
- Map popup muted text gray-500 -> gray-300 for contrast
Units stay Celsius/km/h (deliberate).
2026-10-12 13:44:19 +07:00
SkateSpots
6407310213 feat(relay): cut over community relay to self-hosted Newlay
Point SKATE_RELAY, the default relay pools, the DM/CVM/zap relay arrays, the cvm-server + push-service defaults, and the archive default at wss://relay.skate-spots.org, keeping the legacy hosted relay as a fallback during the client-update window. Restored 115/115 archived events; the relay runs behind Caddy with TLS. Docs + AGENTS.md updated.
2026-10-12 12:38:13 +07:00
SkateSpots
0b645d6d67 feat(lab): add Clothing Designer craft (kind 35015)
New data-driven Lab craft, mirroring the artist role: three skill
sections (What You Make [required] / How You Make It / Materials) plus
minimum order, turnaround, size range, samples and customisation extras,
inheriting the shared Lab extras (rate, payment, gallery, reel,
languages, availability, booking).

Wired through types.ts (kind, label/description maps, parse, collective-
capable), labelKeys, useLabProfiles (kind list + dispatch), becomeRoles
(role card), craftFields, LabPage (tab, filters, offer button, empty
state, counts, deep links), LabCrewsStrip, NIP.md, and en/es i18n
(labOptions, becomeRolesUi, labUi). /become/clothing added to the smoke
route list. tsc, eslint, check-i18n, vitest 101/101, build and smoke all
pass.
2026-10-10 19:30:47 +07:00
SkateSpots
057ef0a8f3 fix(marketplace): localize trade state and pending status
Trade-record state (revoked/verifying) and the listing pending status were
printed raw. New marketUi.trades.stateRevoked/stateVerifying and
marketUi.statusPending (en/es). Also reclassify the request tag as cosmetic
(never read in the client) in the audit.
2026-10-10 10:09:41 +07:00
SkateSpots
7a60099bab fix(marketplace): show an outage instead of an empty trade/reputation state
TradesPage, SellerDashboard, TradeReputationPanel, TradeReputationCard and
ShippingStatusCard now surface a relay outage explicitly instead of
rendering nothing-waiting / no-trades / hidden reputation. Shared
marketUi.loadFailed (en/es).
2026-10-10 09:32:52 +07:00
SkateSpots
5f8975d631 fix(ux): URL-addressable marketplace tabs, offers error state, nav reset
Next P1 slice from UX_AUDIT_2026-10-09.md:
- Marketplace hub tabs now live in the URL (?tab=...) so refresh, share and
  back/forward keep the tab; unknown values fall back to Browse.
- ListingOffersPanel shows an error state on a relay outage instead of
  returning null (a failure no longer reads as no offers).
- Nav customizer Reset reseeds from DEFAULT_TAB_IDS (4) instead of a
  hardcoded 3, matching MIDDLE_SLOTS.
New marketUi.offers.loadFailed (en/es).
2026-10-09 21:04:52 +07:00
SkateSpots
0d15a7ce3d fix(marketplace): close the P0 audit gaps + borrow the guidelines page
P0 fixes from UX_AUDIT_2026-10-09.md:
- useMarketplaceItem now filters admin-hidden listings and skips
  showcase-only (not-for-sale) items, so a direct /listing/... URL cannot
  surface removed or non-sale content.
- Listing detail hides Make an offer for logged-out users and for
  fixed-price listings (Buy is the single primary CTA there).

Borrowed from the Plebeian market review: a /marketplace-guidelines page
(peer-to-peer, buyer-beware, no checkout, prohibited items, soft
moderation), linked from the marketplace hub; new marketTerms en/es keys.
Records the remaining borrowables in the audit doc.
2026-10-09 20:21:04 +07:00
SkateSpots
18a9e28f0b feat(trust): network alerts for reported accounts you follow
Fifth slice of TRUST_SCORE.md. useNetworkAlerts reads the viewer's NIP-85
assertions for the accounts they follow and surfaces those trusted people
reported or muted. New /alerts page lists them with Ignore / Unfollow /
Mute / Report (reusing useFollowActions, useMuteUser, ReportDialog) —
inform, never auto-act. Settings -> Trust links to it with a live count;
ignored accounts are device-local. /alerts added to the smoke list.
2026-10-09 18:32:47 +07:00