Commit graph

83 commits

Author SHA1 Message Date
SkateSpots
4009dd3a72 release: 1.7.3 2026-10-27 16:40:54 +07:00
SkateSpots
ac5ac85004 release: 1.7.2 2026-10-27 16:36:29 +07:00
SkateSpots
118b91188e release: 1.7.1 2026-10-27 09:13:09 +07:00
SkateSpots
67f21bf1ac release: 1.7.0 (authoritative map, pass-the-app, clearer sign-in, security)
Bump 1.6.8 -> 1.7.0. Notes: canonical map + restored spot; Android share-app
card; 3-card sign-in with per-session desktop welcome; zod 4 + nostrify 0.50 +
react-router 7 + vitest 5 (audit 35 -> 8). APK built + published + verified.
2026-10-26 12:45:10 +07:00
SkateSpots
f8ec7e35c0 release: 1.6.8 (3-card sign-in, curated deps, AGPL on Zapstore)
- 3-card sign-in chooser + desktop welcome modal (from 2164dd6's LoginDialog
  restyle) ships.
- Curated dependency fixes (vite 6.4.5 / vitest 3.2.7 / unhead 2.1.17 /
  yaml 2.9.1, TS pinned 5.8.3) — OSV 107 -> 59.
- zapstore.yaml license: custom -> AGPL-3.0-only (the listing now shows the real
  licence; verified on the 32267 tag).
Bump 1.6.7 -> 1.6.8, APK built + published + verified.
2026-10-26 11:27:04 +07:00
SkateSpots
4d9389fa48 release: 1.6.7 (Amber result-compression fix)
Bump 1.6.6 -> 1.6.7. Native Amber intents now send compressionType=none and the JS
signer decodes Signer1 gzip results, so long encrypted payloads no longer fail.
APK built + published to Zapstore (verified on relay.zapstore.dev).
2026-10-14 06:31:06 +07:00
SkateSpots
704714583f release: 1.6.6 (crew chat simplification, decrypt cache, i18n, invite)
Bump 1.6.5 -> 1.6.6, notes for the always-NIP-17 crew chat, instant sends +
persisted decrypt cache, the 20-locale i18n backfill, and the private-chat invite.
APK built + published to Zapstore (verified on relay.zapstore.dev).
2026-10-13 20:57:15 +07:00
SkateSpots
c7be44dfb3 release: 1.6.5 (crew chat fixes)
Messages now appear on send; shared DM decrypt cache stops per-view re-decrypts;
double-send guarded. Bump 1.6.4 -> 1.6.5, APK built + published to Zapstore
(verified on relay.zapstore.dev).
2026-10-13 00:31:07 +07:00
SkateSpots
07d4df037d release: 1.6.4 (crew chat sends with Amber no longer fail)
Fix: sending to a crew sequential-ised its per-recipient signer intents, so Amber
approvals land instead of timing out. Bump 1.6.3 -> 1.6.4, APK built + published
to Zapstore (verified on relay.zapstore.dev).
2026-10-13 00:10:12 +07:00
SkateSpots
6c10d880c6 release: 1.6.3 (Amber pop-ups, Crews in Messages, crew-chat UX)
Bump 1.6.2 -> 1.6.3, notes for the Amber navigation fix, the Messages Crews
section, and the crew encrypted-chat card rewrite. APK built + published to
Zapstore (verified on relay.zapstore.dev).
2026-10-12 23:48:08 +07:00
SkateSpots
f73190ab81 release: 1.6.2 (onboarding pop-up fixes)
Bump 1.6.1 -> 1.6.2, release notes for the first-run checklist + backup-reminder
fixes. APK built and published to Zapstore (verified on relay.zapstore.dev).
2026-10-12 23:15:11 +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
0f01eb1bc6 chore: bump to 1.6.0 (10 new languages) 2026-10-08 17:21:57 +07:00
SkateSpots
cc50eaad18 chore(release): bump to 1.5.13 + release notes 2026-10-05 21:52:18 +07:00
SkateSpots
0c4d4f6b29 fix(supporters): drop dead BTC address; fix Zapstore version duplication in release notes 2026-10-05 17:42:09 +07:00
SkateSpots
ef5a30eb5f chore(release): v1.5.12 2026-10-03 22:50:48 +07:00
SkateSpots
bc6c1e0c70 feat(lab): tidier "Offer a service" menu
The dropdown was a wall of full-colour buttons that also ran off-screen. Now:
- one clean list with a small colour icon chip per role (the role's colour is
  kept as identity, not the whole row), neutral hover highlight;
- a "Offer a service" caption and a scrollable list capped at min(60vh,440px);
- "Get Rider Card" separated below a divider so it stays pinned and reachable.
2026-10-03 22:16:08 +07:00
SkateSpots
1f8f06affd fix(ui): stop overflow/overlap on narrow screens (stash + listing form)
- Stash mobile header: the title row now wraps — the title + "Encrypted /
  Syncs everywhere" badges take a full line and the Select / view-toggle / Add
  actions drop to their own right-aligned line (they were overlapping).
- Stash list row: the stars + price line wraps, and the price can shrink, so
  the sats/fiat no longer runs under the action buttons.
- Create-listing: the Condition and Fulfilment option buttons are
  `whitespace-normal` (they inherited `whitespace-nowrap` from Button, so the
  descriptions overflowed into the neighbouring cell).
2026-10-03 21:11:42 +07:00
SkateSpots
89ec54cb23 chore(release): v1.5.11 2026-10-03 19:36:24 +07:00
SkateSpots
c84f0bdeb9 release: v1.5.10 (versionCode 10510) — directions rework, mint info, offers/barter, Trades tab
Rebuilds the APK with everything shipped since 1.5.9 (all previously web-only):
destination search + bigger follow map, MintRadar ratings/reliability in a mint
detail sheet, counter-offers + barter with notifications and a Trades bell tab,
the crews type control, one-close spot sheet, and the floating map toolbar.
2026-09-29 18:53:14 +07:00
SkateSpots
1c7bd2aa6e release: v1.5.9 (versionCode 10509) — voice navigation + floating map controls
Rebuilt the APK so the phone gets:
- voice turn prompts (device TTS) + arrival, wake lock, bigger follow map
- floating map controls (map fills the screen)
Web was already deployed; this only bumps the Android version.
2026-09-29 17:20:15 +07:00
SkateSpots
c14b19aee1 release: v1.5.8 (versionCode 10508) — coordinator settings, discovery, crew bridge
Rebuilt the release APK so the phone gets what shipped this session:
- Settings -> Coordinator (pick/add/health, run-your-own hand-off)
- crew form accepts a phone-run coordinator (nprofile/cordn link) + 'Use my coordinator'
- profile discovery: publish your coordinator, one-tap add on profiles
- Edit Profile preview + 'finish your profile' checklist

Web was already deployed; this only bumps the Android version.
2026-09-29 16:27:30 +07:00
SkateSpots
d966bca148 feat(notify): scheduled event reminders (Phase 1b) + v1.5.7
An OS alarm an hour before each upcoming event the user RSVP'd going or
interested to. Because the OS holds the alarm it fires with the app fully
closed — the only closed-app notification achievable without a server.

- src/lib/reminders.ts: schedule/cancel via @capacitor/local-notifications,
  tracking handed-out ids in localStorage so withdrawn RSVPs and passed events
  are cancelled without disturbing one-off notifications. Web is a no-op.
- src/hooks/useLocalReminders.ts: reuses the existing upcoming-events and
  my-RSVPs queries; no new relay destination, no signing.
- Bridge mounts the hook only on native and only when the new 'reminders'
  pref is on; unmount cancels everything (opt-out/logout).
- Skipped the Pro-expiry reminder on purpose: it would drag the heavy
  useSasquatchPro query into a nudge.

Bumps to v1.5.7 (versionCode 10507); APK rebuilt.
2026-09-29 14:12:55 +07:00
SkateSpots
a4b79adadd release: v1.5.6 (versionCode 10506) — notifications, faster map pins, badges
Rebuilt the release APK so the phone gets everything currently on main:
opt-in on-device notifications (incl. the @capacitor/local-notifications
native plugin), the batched/smoother map markers, profile badges, the
'closest spot to me' Sasquatch intent, and the 'Keep the map free' support
element. Bumps only package.json (version sync script derives versionCode).
2026-09-29 13:08:16 +07:00
SkateSpots
9846b3756a release: v1.5.5 (versionCode 10505)
Bump 1.5.4 -> 1.5.5 and give today's ships their own release block: offline map
tiles, photo mirror fallback, the DM 'No messages yet' fix, and free
name@skate-spots.org handles. 1.5.4's notes are restored below.

APK rebuilt: versionName 1.5.5 / versionCode 10505, and its bundle carries the
ai.skate-spots.org base.
2026-09-28 14:35:42 +07:00
SkateSpots
53cb4a2d95 docs(release): add today's ships to the v1.5.4 notes
Offline map tiles, photo mirror fallback, the DM 'No messages yet' fix, and
free name@skate-spots.org handles. APK rebuilt (1.5.4 / 10504) and verified to
carry the ai.skate-spots.org base.

release-notes.txt isn't in dist, so the deploy guard skips the Netlify deploy
(no credits).
2026-09-28 14:33:15 +07:00
SkateSpots
3c0a91a379 feat(moderation): report inbox, bulk undo, crews + Lab in the queue
- Report INBOX: /review now defaults to a Reports tab. useRecentReports fetches
  recent NIP-56 (1984) and resolves the referenced event by id (one extra ids:
  query), so ANY report is actionable — content that isn't flagged, comments,
  profiles, anything. reportTargetMeta maps kind -> label + route for the link.
  Actions: Hide / Dismiss report (verify) / Undo / Look at it.
- Bulk undo: when a tab holds >1 verdict, a toolbar offers 'Undo all N' with an
  AlertDialog that warns each undo is its own label publish (one Amber approval
  each). Built for the 13 old hidden labels from Sep 3.
- Crews + Lab tabs: added includeHidden to useCrews/useLabProfiles. Hiding these
  removes a community / a person's listing, so their Hide goes through a
  confirmation (confirmHide/confirmHideNote on QueueList).

Verified in the browser: 8 tabs render; the inbox shows and resolves a real
report (target + reason); the Spots tab shows the bulk-undo toolbar.
tsc/eslint clean, 101 tests, smoke PASS.
2026-09-28 10:20:54 +07:00
SkateSpots
f1ddf5fdf1 feat(quality): review queue for every kind, soft photo gate, empty-map nudge
(a) Review queue covers spots/shops/events/tours/gear: added { includeHidden }
    (admin-tooling only) to useSkateShops/useSkateEvents/useTours/
    useMarketplaceItems; generalised the flags to contentFlags() in spotQuality.ts
    (trust/status/photo signals stay spot-only); one component per kind so only the
    OPEN tab queries. Reports + trust are kind-agnostic; the label mechanism never
    cared about kind.
(b) Photo gate softened: removed the hard block (it punished an honest mapper with
    no photo). Publish without a photo is allowed; the spot stays Unverified, the
    success toast says so, and the queue's 'no photo' flag lets a human look.
(c) Empty-map nudge: MapPage now distinguishes a FILTER empty ('No spots match')
    from a genuinely EMPTY map ('No spots mapped yet — be the first to map your
    park', with Add-spot + Near-me). Note: must key off allLocations, not mapSpots
    (which derives from filteredSpots).

Verified in the browser: the empty-map nudge renders with its CTAs when no spots
load; the review queue renders 15 spot rows and the tabs switch (Gear shows its
own empty state). tsc/eslint clean, 101 tests, smoke PASS.
2026-09-28 09:59:09 +07:00
SkateSpots
e549aeee3a feat(spots): reports reach the admin, duplicates are caught, contributors are told
1) Reports were a VOID: ReportDialog publishes NIP-56 (1984) but the only reader
   in the app was a count on marketplace cards, so an admin never saw one. Now
   useSpotReports batch-reads kind 1984 by '#e' (one query for every spot) and
   the review queue ranks reported spots ABOVE the heuristics with a red
   'REPORTED: ...' chip. useNotASpotReport publishes to getWriteRelays()
   (community relay + the reporter's), not the default pool — the admin reads
   from the community relay, so reports written only to personal relays would
   never arrive. Verified end-to-end: published a report from Node, saw it
   surface in the queue.

2) Duplicate guard in CreateSpotPage: on submit, existing spots within 60 m are
   listed with distances + links, with 'It's a different spot — publish anyway'.
   Targets the clone-spam failure mode (five near-identical pins).

3) Contributor feedback: useSkateSpot no longer nulls a hidden spot for its
   AUTHOR (it used to silently 404 for the person who made it), and
   SpotDetailPage shows an author-only banner for hidden/verified.

tsc/eslint clean, 101 tests, smoke PASS.
2026-09-28 09:45:36 +07:00
SkateSpots
e44f8b81a7 feat(moderation): reversible verdicts (undo) + community photos as a signal
Undo (latest verdict wins):
- MODERATION_LABEL_CLEARED = 'cleared' — the neutral undo verdict.
- useAdminModeration no longer UNIONS labels (which made a hide permanent in the
  UI); it keeps the NEWEST verdict per target (created_at, with device-local
  verdicts overlaid by timestamp), so 'cleared' supersedes an earlier
  'hidden'/'verified'. useAdminClear() publishes it.
- Local mirror is now a verdict map (skatespots_local_admin_verdicts_v1: key ->
  {verdict, at}) with migration from the legacy hidden/confirmed arrays.
- useSkateSpots(limit, { includeHidden: true }) — ADMIN TOOLING ONLY: without it
  a hidden spot leaves the list, so a verdict could never be undone. The review
  queue uses it, keeps actioned rows (Hidden/Confirmed badge + Undo), and sorts
  un-actioned first.

Community photos as a signal:
- useBatchSpotPhotos: ONE #a query for every spot (the single-spot hook already
  queried by #a, so batching is free), counting only photos from people OTHER
  than the mapper. Folded into the 'no community signals' flag.

Verified by seeding local verdicts: none -> flags + Confirm/Hide; hidden ->
Undo; verified -> Undo; cleared -> back to neutral. tsc/eslint clean, 101 tests,
smoke PASS.
2026-09-28 01:06:04 +07:00
SkateSpots
0419c18810 feat(moderation): positive 'verified' verdict + trust/community signals in the review queue
- MODERATION_LABEL_VERIFIED: the positive counterpart to 'hidden'. Both labels
  are fetched in ONE query; useAdminModeration now exposes verifiedCoords/
  verifiedIds/isVerified() with a local mirror (addLocalConfirmed/
  getLocalConfirmed). useAdminVerify() publishes it (shares the publish path
  with useAdminHide).
- Review queue: a human review can now CONFIRM a spot, not just hide it. A
  confirmed spot clears from the queue and gets a 'Verified by SkateSpots' badge
  on the spot page (staff verdict, shown separately from the community badge).
- Two more signals: mapper trust (useBatchTrustScores) and whether any skater has
  filed a status report (useBatchSpotStatus reporterCount) -> 'mapper not in your
  web of trust' / 'no community signals'. The latter only fires alongside another
  flag so a brand-new real spot isn't punished for being new.
- Flag logic moved to src/lib/spotQuality.ts so the page and AdminReviewCard share it.

Verified: the queue lists the airport entry with suspicious name + no photo + no
community signals, shows mapper trust, and offers Confirm/Hide/Not a skate
spot/Look at it.
2026-09-28 00:25:12 +07:00
SkateSpots
a43ff47b28 feat(spots): honest quality signals, photo required, off-topic reports, admin review queue
The 'test of secret island airport' problem: a junk pin wearing an app-endorsed
'Skateability 95/100'.

- Rename the weather score to 'Conditions · weather only' (SpotDetailPage +
  the SpotMap popup). It was never a verdict on the place.
- New Community verified / Unverified badge from signals only OTHER skaters can
  produce: community photos + useSpotStatus reporterCount (kind 2259).
- CreateSpotPage now REQUIRES at least one photo (guard + disabled submit +
  a required hint on the label).
- useNotASpotReport: one-tap NIP-56 (1984) report tagged 'not-a-skate-spot'
  (NIP-56 'other' + our L/l/t taxonomy), wired into the spot's More menu and
  added to the shared ReportDialog reasons.
- useAdminHide: the MISSING WRITE SIDE for admin moderation. useAdminModeration
  always read NIP-32 kind-1985 'hidden' labels but nothing published one, so the
  only working hide was device-local. Now publishes the label (+ optimistic
  local hide). Soft and reversible — the event stays on relays.
- /review (AdminReviewPage, admin-only → 404 otherwise): review queue over
  useSkateSpots with cheap flags (suspicious title, name <=3 chars, no photo, no
  description, no geohash), sorted by flag count, one-tap Hide or Not a skate
  spot. Entry via the admin-only AdminReviewCard in Settings → Advanced.
- /review added to the smoke-test route list.

Verified: the airport spot shows UNVERIFIED with 'Conditions · weather only' and
no 'Skateability'; the review queue lists it with flags + Hide/report actions;
create-spot blocks without a photo.
2026-09-27 23:41:49 +07:00
SkateSpots
0adfbcbd29 feat(app-shop): remove the subscribe band and the honesty note
Per request, the page is now: hero -> in the works -> free to print -> how
buying works. Nothing else changed.

Honesty is still carried by the remaining copy: the COMING SOON badge, the
'IN THE WORKS / not for sale yet' label on the teasers, and the hero's 'sold
locally, on request'. No prices, no buy buttons, no stock list.

Also drops the now-unused NewsletterSubscribeButton/ArrowRight imports, and
updates release-notes + AGENTS.md (they described the removed copy).
2026-09-27 23:23:14 +07:00
SkateSpots
4341653abe feat(app-shop): add free printable sticker + poster (vector, real QR)
- public/images/print/skatespots-sticker.svg (55 x 86 mm) and
  skatespots-poster.svg (A3) — the free artwork to print and stick up. Physical
  size is baked into the SVG (mm units), so 'Actual size' printing is exact.
- Self-contained: Outfit/Barlow fonts + the logo embedded as data URIs, and a
  real vector QR. VERIFIED both QRs decode to https://skate-spots.org (decoded
  with jsQR from a rendered PNG; logo centre, error-correction H).
- New 'Free to print' section in the App Shop: previews, FREE badge, sizes,
  cutting tip, 'Open & print' + 'Save file' buttons, and a 100%/Actual-size note.
- scripts/make-print-art.mjs regenerates the artwork (committed output).
- AGENTS.md documents the assets + the re-verify-the-QR rule.
2026-09-27 22:16:43 +07:00
SkateSpots
8dcc97fd81 feat(app-shop): add the App Shop section (empty on purpose)
New /app-shop page for SkateSpots merch, to be paid in sats only (Lightning or
Cashu) — no cards, no accounts, no middleman.

Design: gradient/glow hero ('Wear the scene' + Coming soon badge), an honest
stock strip (0 items / None pre-orders / Nothing for sale today), an 'In the
works' teaser grid (tees, decks, stickers, tools — dashed + 'soon', no prices),
a three-step 'How it'll work' (pick -> pay in sats -> ships), a newsletter
notify band (the drop lands there first) and a plain-English honesty footer.

Deliberately contains no items: no stock, no prices, no pre-orders, no buy
buttons. AGENTS.md documents that rule so nobody invents a catalogue later.

Wiring: registered in NAV_CATALOG as id 'app-shop' (appears in the desktop
'More' menu AND the mobile burger menu automatically), lazy route in AppRouter,
and added to the smoke-test route list so a broken page aborts deploys.

Verified: page renders desktop + mobile (all sections), listed in both navs,
smoke PASS with /app-shop.
2026-09-27 21:40:41 +07:00
SkateSpots
9aa5a9ca4e release: v1.5.4
1.5.3 shipped at 19:22, before the DM fix, the directions UI rework and the
newsletter reader fix. Bump to 1.5.4 so those can actually reach people.

- package.json 1.5.4 (-> versionName 1.5.4 / versionCode 10504).
- release-notes.txt: new v1.5.4 section (DM persistence + parallel send/read,
  bigger-map/app-like directions, underscore italics in the issue reader);
  trimmed v1.5.3 back to what was actually published.
2026-09-27 20:43:16 +07:00
SkateSpots
1ef35c14b8 fix(dms): DM inbox relays were wiped on every load, so DMs went nowhere
Root cause: AppProvider validates the persisted config with
AppConfigSchema.partial().parse(), and RelayMetadataSchema only declared
'relays' + 'updatedAt'. Zod drops unknown keys by default, so dmRelays (and
localRelays + blockedRelays) were SILENTLY STRIPPED on every page load. The DM
inbox relays (kind 10050) are usually not in a user's NIP-65 list, so DM reads
and writes fell back to NIP-65 relays - where the other side isn't listening -
and messages looked like they never went through.

- Declare localRelays/blockedRelays/dmRelays in RelayMetadataSchema.
- Send: publish gift wraps in PARALLEL with per-relay timeouts and resolve on
  the first relay that accepts (a dead relay or auth.nostr1.com no longer
  stalls the send); deliver to the recipient's NIP-65 WRITE relays when they
  have no discoverable 10050 (the old fallback was dead code because our own DM
  relays are always non-empty); discovery of 10050/10002 now runs in parallel.
- Read: query all DM relays in parallel with per-relay timeouts. Previously one
  slow/dead relay burned the shared 15s budget and then the fired abort made
  every remaining relay fail instantly.

Verified with an nsec login + a hostile relay list (dead + auth-required):
before, the wrap reached only write relays and the recipient found 0; after, it
lands on the configured inbox relays and both the recipient and our own copy are
found. Send worst case 20s -> 4.5s.
2026-09-27 19:58:54 +07:00
SkateSpots
4474cc26e9 feat(directions): bigger map + app-like layout and richer route details
- Map is now the hero: h-[38vh] mobile / 400px desktop (was 256), with a metric
  Leaflet scale control.
- New layout: flex column with header/modes/From/map pinned, the details as the
  ONLY scroll region, and Start/Stop pinned at the bottom so it's always
  reachable. Previously the dialog was a single overflow-hidden box, so once the
  map grew everything below the fold (Start, steps) was unreachable.
- Summary rebuilt as stat tiles (distance / time / arrive) plus a detail line:
  step count, honest 'uses driving roads'/'driving estimate' notes, and the
  average speed the engine assumed ('21 km/h avg'; foot keeps the skate cruise
  estimate). Steps header shows the count; step list scrolls taller (max-h-72).
- Wider dialog on desktop (sm:max-w-xl).

Verified in-app: tiles + 9/8/5/5 steps per mode, follow banner still tracks
movement, offline chip still appears, map 371px -> 321px with the new layout.
2026-09-27 19:42:06 +07:00
SkateSpots
dff3ccc6f8 release: v1.5.3
1.5.2 is already published to Zapstore (verified: org.skatespots.app@1.5.2 on
relay.zapstore.dev), so the post-publish work needs a new version.

- package.json 1.5.3 (-> versionName 1.5.3 / versionCode 10503).
- release-notes.txt: new v1.5.3 section (real per-mode routing + steps + follow
  mode + choose-your-start + offline saved routes + Amber scoping); trimmed the
  v1.5.2 section back to what was actually published.
2026-09-27 19:16:53 +07:00
SkateSpots
5a819d5a31 feat(directions): follow mode, choose-your-start, offline route cache
Follow mode (explicit Start; off by default — a watcher drains battery):
watchPosition in geolocation.ts, live dot, 'NEXT · step N' banner with
distance-to-turn + distance-to-go, current step highlighted, map follows.
A transient watch error (timeout/unavailable) no longer kills it — only a
permission denial does; the watcher recovers on its own.

Choose your start: 'From → My location / Choose on map' — tapping the map sets
the origin, and the route recomputes from there.

Offline: src/lib/routeCache.ts keeps the last route per destination+mode with
the line downsampled to <=250 points. If a fetch fails (no signal / routing
server down) the dialog falls back to it with an 'Offline · saved route {age}'
badge instead of a dead error.

Also tidied the map overlays (offline badge bottom-left, Whole route
bottom-right) so nothing covers Leaflet's zoom control.

Verified with CDP: controls present; follow banner tracks movement (step 1 ->
step 7, distances update); blocking routing shows the cached route + badge;
picking a start on the map changed the route (968 m -> 922 m). Still no voice
guidance or re-routing if you leave the route (documented).
2026-09-27 19:11:14 +07:00
SkateSpots
59e5829b2a feat(directions): make the route dialog usable as guidance, not just a preview
Answering 'are we giving the best navigation experience?': no, it was a preview
with dead ends. Fixes the concrete gaps:

- ETA: 'arrive ~08:10 PM' alongside the duration.
- Mode memory: the last travel mode is remembered (skatespots:route-mode), so
  cyclists/drivers aren't reset to Skate/Walk every trip.
- Tappable steps: each step pans the map and highlights; added a 'Whole route'
  re-fit button to zoom back out.
- Taller route map on desktop (h-64 sm:h-80).
- min-h-0 on step rows: the app-wide 44px mobile touch-target rule was making
  every step a 44px slab (rows now 29px).

Still out of scope (documented, not faked): live turn-by-turn following, voice
guidance and offline routing.
2026-09-27 18:47:29 +07:00
SkateSpots
e69bace784 fix(amber,routing): scope Amber prompts to real actions; real per-mode routes + steps
AMBER — 'pops on every screen':
staleTime: Infinity only stops REFETCHING, never the FIRST decrypt. So the
encrypted useSyncedAppData blobs (read-state, preferences) each ran a queryFn on
mount (racing consumers multiplied it) and relay responses landing during
navigation made it look per-page. useSyncedAppData now has interactiveNetwork
(default false): for an interactive signer the blob is LOCAL-ONLY — query not
even enabled, patch() a no-op — no decrypt on mount, no publish on a nav-tab
change. Verified with a mocked x-amber login: network-on => Amber op at startup,
with the fix => 0. (useCrewDismissals/useStash were already gated.)

ROUTING — 'same time for every transport option':
router.project-osrm.org hosts ONE car dataset and ignores the profile in the URL,
so foot/bike/car returned identical numbers. Switched to the FOSSGIS per-profile
servers (routing.openstreetmap.de/routed-{foot,bike,car}); the demo server is now
only a last-resort fallback and its result is flagged approximate ('driving
estimate'). Request steps=true and surface turn-by-turn steps for orientation,
plus a '~X min on a board' skate estimate next to the walking time. Verified:
same trip => walk 13 min / bike 5 / moto+car 2, with 5-9 steps each.
2026-09-27 18:35:17 +07:00
SkateSpots
e2d367efab release: v1.5.2
Bump package.json (single source of truth → versionName 1.5.2 / versionCode
10502 via scripts/sync-android-version.mjs) and add the v1.5.2 release notes:
marketplace deck ratings + seller dashboard, working in-app directions, nav
fixes (desktop More / mobile Marketplace), the native mints fix, and the
newsletter CPU + relay fixes.
2026-09-27 17:46:00 +07:00
SkateSpots
4ed4e6f6fb release: v1.5.1
Patch bump over the unreleased 1.5.0, folding in today's mobile fixes: Mints in
the phone nav, instant Directions, and no stray signer prompt for the AI balance.
2026-09-27 16:04:53 +07:00
SkateSpots
7969e8e9de release: v1.5.0
Sasquatch Pro (AI), in-app directions (transit/bike/moto/car), Barbers &
Hairstylists in The Lab, and a smoother app shell (no remounts, no stray
signer pop-ups).
2026-09-27 15:42:52 +07:00
SkateSpots
645993cd64 chore: bump to 1.4.5 2026-09-26 16:07:01 +07:00
SkateSpots
0ac57d4250 chore: ignore generated android/ project; add v1.4.4 release notes 2026-09-26 15:52:14 +07:00
shakespeare.diy
cd3a353c8b Release notes for 1.3.3 (Citrine local relay + 1.2.34–1.3.3 fixes)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-08 19:40:13 +07:00
shakespeare.diy
be05a603be security: verify invoice amounts + require provider-issued zap receipts (1.2.14)
Fixes the audit findings:

HIGH-1 (NWC/WebLN auto-pay of unverified invoices): add assertInvoiceAmount and
call it before every programmatic payment in useZaps, useCrewZap, and
SpamFeePayment. A malicious LNURL/Lightning-address server can no longer return
an inflated invoice and drain the wallet — amount is decoded from bolt11 and must
match the intended sats (±1 sat), amountless invoices are rejected.

HIGH-2 (forgeable trust signals):
- useSasquatchPro: Pro is granted ONLY by a zap receipt AUTHORED by the
  platform's Lightning provider, embedding a user-signed zap request that tags
  the platform, with a real paid amount >= smallest tier. The self-signed
  kind:32671 receipt is now advisory only and never grants access (closed the
  "self-grant permanent Pro" hole).
- useFeaturedVerification: a listing is 'verified' only when the matching 9735 is
  authored by the provider pubkey (not any self-published receipt).
- useCrewGoal: tally only invoice-backed (bolt11) zaps; the forgeable amount tag
  is no longer summed, so goal progress can't be inflated with fake receipts.

Bump to 1.2.14.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-07 11:45:21 +07:00
shakespeare.diy
88685262ce fix(android): remove custom MainActivity that broke app startup (black screen)
The injected MainActivity overrode Capacitor's WebViewClient, wiping out the
client Capacitor needs to load the web layer — causing a black-screen crash on
launch. Remove the MainActivity template, its injection script, and the build
wiring. The real signing fix (setPackageName before signEvent) is unaffected and
remains in place. Bump to 1.2.10.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-04 22:02:23 +07:00