diff --git a/src/pages/NewsletterPage.tsx b/src/pages/NewsletterPage.tsx index 43cf135..7f95e7a 100644 --- a/src/pages/NewsletterPage.tsx +++ b/src/pages/NewsletterPage.tsx @@ -103,57 +103,124 @@ export const NEWSLETTER_ISSUES: NewsletterIssue[] = [ { number: 3, date: '2026-07-25', - vibe: "A 'weekly' newsletter that shows up whenever the f*** we want. This drop: we spent an unholy amount of time teaching one Android phone where it is on planet Earth — and won. Plus spots can now tell you when they've been knobbed into oblivion.", + vibe: "It's a WEEKLY newsletter and we ship whenever the f*** we want — cope. This drop we went to war with a single Android phone across a dozen builds until it finally admitted where it was standing on Earth. We won. Then we gave you a pin, taught the map to snitch on dead spots, fixed the camera, unstuck your keys, and let you bury your own bad crews. It's a fat one. Strap in.", updates: [ + // ── The Great Geolocation War ────────────────────────────────────────── { icon: 'fix', - title: "The 'Near Me' button no longer nukes the app", + title: "The 'Near Me' button stopped assassinating the app", tag: 'Android', - body: "Tapping Near Me used to grant location permission, think about it for a second, and then yeet you straight back to the app store as the whole app died. Turns out the native geolocation plugin was compiled against a newer Kotlin than our build spoke — a NoClassDefFoundError blowing up on the main thread, which no amount of JavaScript try/catch can catch. Aligned the Android build to Kotlin 2.1, and the crash is dead. RIP little bug, you will not be missed.", + body: "Tap Near Me → grant location → the ENTIRE app instantly dies and yeets you back to the app store. Adorable. The native geolocation plugin was compiled against a newer Kotlin than our build could read — a NoClassDefFoundError detonating on Android's main thread, the exact kind of crash no JavaScript try/catch on this green Earth can catch. We hauled the whole Android build up to Kotlin 2.1 — plugin classpath, forced stdlib, coroutines, all of it — and put a bullet in it. Dead. Not coming back.", }, { icon: 'feature', - title: 'GPS that actually finds you (even on GrapheneOS)', + title: "GPS that actually finds you — zero Google required", tag: 'Map', - body: "Once it stopped crashing, it just... timed out forever. The old code politely asked GPS for one perfect satellite fix and gave up after a few seconds — useless indoors, and extra useless on de-Googled phones with no fused-location shortcut. Rewrote it to run high- and low-accuracy location watches in parallel, grab the FIRST real fix that comes back, and wait a proper 60 seconds for a cold GPS lock instead of rage-quitting. Google Maps energy, no Google required.", + body: "Once it stopped crashing it did something almost ruder: nothing. It'd beg the sky for one flawless satellite fix, wait a few seconds, then quietly give up. Useless indoors, extra useless on de-Googled phones (hi GrapheneOS) with no fused-location cheat code. So we rebuilt it from scratch: run high- AND low-accuracy location watches in PARALLEL, grab the very first real fix that comes back, and give a cold GPS chip a proper 60 seconds to lock instead of rage-quitting after five. That's the trick that makes Google Maps feel instant — and we do it with no Google in the building.", }, { icon: 'ux', - title: "'Locating you…' instead of a frozen spinner of despair", + title: "'Locating you…' — because a dead spinner is psychological warfare", tag: 'Map', - body: "Because a cold GPS lock can genuinely take up to a minute, the app now tells you it's working — a 'Locating you…' banner while it hunts, then a 'Found you' when it locks. No more staring at a spinner wondering if the app died again. (It didn't. Probably.)", + body: "A cold GPS lock can genuinely take up to a minute. So instead of a silent spinner that has you wondering if the app died AGAIN, you now get a 'Locating you…' banner while it hunts and a clean 'Found you' when it snaps in. Telling the user what's happening: groundbreaking, apparently.", }, { icon: 'feature', - title: 'You now have a pin — and it\'s a whole personality', + title: "You finally have a pin — with main-character energy", tag: 'Map', - body: "Near Me used to just slide the map over and leave you guessing which blob was you. Now you get a proper 'you are here' marker: the SkateSpots logo in a circular badge with a pulsing halo, sitting exactly where you're standing, riding on top of every other pin. Google's boring blue dot could never.", + body: "Near Me used to just slide the map over and leave you squinting at a pile of markers going 'wait, which blob is me?'. Now there's a proper 'you are here': the SkateSpots logo in a circular badge with a pulsing halo, planted exactly where you're standing, floating on top of every other pin. Google's sad little blue dot could never.", + }, + { + icon: 'fix', + title: "Native geolocation is now crash-proof, permanently", + tag: 'Android', + body: "We didn't just defuse the Kotlin bomb — we bricked up the whole hallway. The app now checks the geolocation plugin is GENUINELY registered before it dares touch it, falls back gracefully instead of self-destructing, ignores garbage 0°/0° 'null island' readings, and prints the real underlying error straight to your screen when something's off — so we never debug blind again. Belt, suspenders, and a second belt bolted over the first.", + }, + { + icon: 'perf', + title: "'No location provider' now says so, like an adult", + tag: 'Android', + body: "Privacy-hardened phone with no network-location provider? Instead of a vague 'it timed out lol', the app now correctly detects the actual problem and tells you exactly what to do — flip on Network Location, or get GPS a look at the sky. Honest errors beat mystery errors every single time.", + }, + + // ── Community: Spot Status Reports ────────────────────────────────────── + { + icon: 'community', + title: "Spot Status Reports — rat out the knobbed ones", + tag: 'Community', + body: "Spots die. Ledges get knobbed, plazas get bulldozed, mellow spots go full bust overnight — and the person who mapped it is basically NEVER the one who finds out. So now ANYONE can slap a status on any spot: 🟢 Active, 🟡 Bust, 🟠 Skate-stopped, ⚪ Closed, or 🔴 Gone — with an optional note like 'new knobs on the ledge' or 'guard boots you after 6pm'. Brand new event kind, fully documented, 100% Nostr-native.", }, { icon: 'community', - title: 'Spot Status Reports — snitch on knobbed spots', - tag: 'Community', - body: "Spots change. Ledges get knobbed, plazas get demolished, chill spots go full bust overnight — and the person who mapped it is rarely the one who finds out. So now ANYONE can report a spot's current state: 🟢 Active, 🟡 Bust, 🟠 Skate-stopped, ⚪ Closed, or 🔴 Gone. The app blends recent reports — weighted by how fresh they are and how trusted the reporter is — into one consensus badge on the spot. No ballot-stuffing, no single grumpy local nuking a good spot.", + title: "Consensus that can't be gamed", + tag: 'Trust', + body: "One salty local can't nuke a good spot out of spite. Reports blend into a single verdict weighted by how FRESH they are (30-day half-life, so a rebuilt spot heals itself over time) and how TRUSTED the reporter is (your web-of-trust score). Only your latest report counts — no ballot-stuffing — and anything older than six months is ignored. It's democracy, but for curbs.", }, { icon: 'ux', - title: "Demolished spots quietly leave the party", + title: "Status badges everywhere you look", tag: 'Map', - body: "When the community agrees a spot is 🔴 Gone, it disappears from the map markers so you're not skating 20 minutes to a parking lot. It still shows up (dimmed, with the Gone badge) in the list, because Nostr never forgets and neither should the history books. Pour one out.", + body: "The verdict shows up as a color-coded badge on the spot page AND on every spot card, with a tooltip telling you how many skaters chimed in and how recently. Tap 'Report Status' on any spot, pick a state, drop a note, done. The pulse of the streets, live on the map.", + }, + { + icon: 'ux', + title: "Demolished spots ghost the map", + tag: 'Map', + body: "When the crowd agrees a spot is 🔴 Gone, it vanishes from the map markers so you're not bombing 20 minutes across town to skate a fresh parking lot. It stays (dimmed, wearing its Gone badge) in the list — because Nostr never forgets and neither should the history books. Pour one out for the fallen.", + }, + + // ── Camera / Quick Snap ───────────────────────────────────────────────── + { + icon: 'feature', + title: "Quick Snap goes camera-first", + tag: 'Camera', + body: "Quick Snap kept fumbling open your gallery on native when you clearly wanted to, you know, take a damn photo. Now it fires the actual camera through the native plugin on the app, and a clean file picker on web. Snap a spot in the wild without spelunking through menus.", + }, + { + icon: 'ux', + title: "Snap → straight to Add Spot", + tag: 'Camera', + body: "Take the shot and you land instantly on the Add Spot form — the photo uploads in the background while you fill in the details. No awkward 'now wait for the upload' purgatory staring at your screen in a parking lot.", + }, + + // ── Signing / Keys ────────────────────────────────────────────────────── + { + icon: 'security', + title: "Amber signing no longer hangs into the void", + tag: 'Keys', + body: "Signing through Amber (the external key-holder app) could just… hang. Silently. Forever. With zero feedback. We added a timeout and a one-time package handshake so a stuck signer surfaces as an actual error you can see and retry — instead of a frozen screen and a quiet prayer. Your keys stay in Amber; your sanity stays with you.", }, { icon: 'fix', - title: 'Native geolocation can no longer crash us, ever', + title: "'Capacitor Amber plugin not available' — exorcised", + tag: 'Keys', + body: "Uploads and signing on the native app would sometimes whine 'Amber plugin not available' and bail. Fixed the plugin wiring so the signer is reliably present when you upload or publish. Fewer gremlins standing between you and posting a clip.", + }, + + // ── Crews & The Lab (deletion — the NEW bit) ──────────────────────────── + { + icon: 'community', + title: "You can finally bury your own crews & Lab profiles", + tag: 'Community', + body: "Made a crew you regret at 2am? Set up a Lab profile you no longer vibe with? You can now properly dissolve a crew or delete a Lab profile (builder, photographer, filmer, editor, coach) via NIP-09 — instead of it haunting the map until the heat death of the universe. Clean up your own mess. The delete button is yours.", + }, + + // ── Build / infra ─────────────────────────────────────────────────────── + { + icon: 'fix', + title: "Android builds that don't fight us", tag: 'Android', - body: "Beyond the Kotlin fix, we hardened the whole path: the app now verifies the geolocation plugin is genuinely registered before touching it, falls back gracefully instead of exploding, and surfaces the real underlying error on-screen when something goes wrong — so we never have to debug blind again. Belt, suspenders, and a second belt.", + body: "A mountain of unglamorous but load-bearing native-build plumbing: externalized the plugins that kept blowing up the compile, sorted the JSR package registry, and tamed the Capacitor sync so the APK ships to ZapStore clean. The boring stuff that's the only reason the fun stuff ever reaches your phone.", }, ], spotOfTheWeek: undefined, communityNote: - "Shipped straight to ZapStore this week (several times, because versioning is a contact sport). If Near Me still can't find you on a de-Googled phone, flip on Network Location in your OS settings or step toward a window — GPS needs a peek at the sky. Everything syncs through wss://goskatespots.nostr1.com as always.", + "This hit ZapStore roughly a dozen times this week, because apparently 'just bump the version number' is an extreme sport. If Near Me still can't pin you on a de-Googled phone: flip on Network Location in your OS settings, or give GPS a peek at the sky — satellites get shy indoors. Everything syncs through wss://goskatespots.nostr1.com. Keep mapping, keep reporting, keep skating.", nostrText: `🛹 SkateSpots Drop #003 -Our "weekly" newsletter, arriving precisely whenever we feel like it. This drop: we beat a native crash, taught the app to actually find you on a de-Googled phone (60s cold GPS lock, first-fix-wins), gave you a pulsing "you are here" pin, and shipped Spot Status Reports so anyone can flag a spot as bust, skate-stopped or straight-up gone. Demolished spots now quietly vanish from the map. +It's a WEEKLY newsletter and we ship whenever the f*** we want. + +We beat a native crash that was killing the app on Near Me, then taught the map to actually find you on a de-Googled phone — 60s cold GPS lock, first-fix-wins, no Google. You get a pulsing "you are here" pin now. Plus Spot Status Reports: anyone can flag a spot as bust, skate-stopped or straight-up GONE, and demolished spots quietly vanish from the map. Camera, Amber signing and crew/Lab deletes all got fixed too. https://skate-spots.org/#/newsletter