From 1c18163a90fea204df46ee4f8b342fcb0c028c30 Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Thu, 30 Jul 2026 00:08:52 +0700 Subject: [PATCH] chore(sasquatch): remove joke book, clean up default suggested questions - Delete sasquatchJokes.ts and all joke usages (idle chat line, fallback taglines, Lab/Crew guide messages). - Tidy the default/generic suggested questions to a clean Nostr-focused set (Plan a trip, spots, events, crews, zaps, Nostr, Stash, free). Co-authored-by: shakespeare.diy --- src/components/SasquatchGuide.tsx | 23 ++------ src/hooks/useSasquatchGuide.ts | 15 ++--- src/lib/sasquatchJokes.ts | 93 ------------------------------- 3 files changed, 10 insertions(+), 121 deletions(-) delete mode 100644 src/lib/sasquatchJokes.ts diff --git a/src/components/SasquatchGuide.tsx b/src/components/SasquatchGuide.tsx index db83ff0..ef84a5f 100644 --- a/src/components/SasquatchGuide.tsx +++ b/src/components/SasquatchGuide.tsx @@ -22,7 +22,6 @@ import { useSasquatchActions, type SasquatchDraft } from '@/hooks/useSasquatchAc import { SasquatchActionCard } from '@/components/SasquatchActionCard'; import { callSasquatchAI } from '@/lib/sasquatchBrain'; import { answerFromGlossary } from '@/lib/glossary'; -import { ethosJoke } from '@/lib/sasquatchJokes'; import { TripItineraryCard } from '@/components/TripItineraryCard'; import { buildItinerary, type Itinerary, type PlannerSpot, type PlannerEvent, type PlannerCoach, type PlannerCrew, type WeatherLite } from '@/lib/tripPlanner'; import { cn } from '@/lib/utils'; @@ -387,7 +386,7 @@ function formatLocalResults(intent: LocalIntent, result: unknown): string { intent.tool === 'find_crews' ? 'crews' : 'gear listings'; if (!items.length) { - return `No ${label} listed there yet 🦧 β€” be the first to add some at [skate-spots.org](https://skate-spots.org). ${ethosJoke()}`; + return `No ${label} listed there yet 🦧 β€” be the first to add some at [skate-spots.org](https://skate-spots.org).`; } const lines = items.slice(0, 6).map((it) => { @@ -854,7 +853,7 @@ export function SasquatchGuide({ message, onDismiss }: SasquatchGuideProps) { if (itinerary.empty) { appendMessage({ role: 'sasquatch', - text: `Nothing on the map for **${destination}** yet 🦧 β€” be the first to drop spots at [skate-spots.org](https://skate-spots.org). Once locals add spots, crews & events, I'll build you a full trip. ${ethosJoke()}`, + text: `Nothing on the map for **${destination}** yet 🦧 β€” be the first to drop spots at [skate-spots.org](https://skate-spots.org). Once locals add spots, crews & events, I'll build you a full trip.`, timestamp: Date.now(), }); } else { @@ -1004,7 +1003,7 @@ Instructions: if (itinerary.empty) { appendMessage({ role: 'sasquatch', - text: `Nothing on the map for **${intent.destination}** yet 🦧 β€” be the first at [skate-spots.org](https://skate-spots.org). ${ethosJoke()}`, + text: `Nothing on the map for **${intent.destination}** yet 🦧 β€” be the first at [skate-spots.org](https://skate-spots.org).`, timestamp: Date.now(), }); } else { @@ -1069,7 +1068,7 @@ Instructions: const fallback = staticAnswer ?? answerFromGlossary(question) ?? - `My AI brain's catching some air right now 🦧 β€” but I've still got you:\n\nβ€’ πŸ—ΊοΈ [Map](/) β€” spots, shops, events near you\nβ€’ πŸ§ͺ [The Lab](/lab) β€” coaches, filmers, editors\nβ€’ πŸ“– [Glossary](/glossary) β€” 150+ tricks & terms\nβ€’ πŸ‘₯ [Crews](/crews) β€” find your people\n\nOr just tell me a **city** ("spots in Barcelona") or a **trick** ("what's a nollie") and I'll answer straight up. πŸ›Ή\n\n_${ethosJoke()}_`; + `My AI brain's catching some air right now 🦧 β€” but I've still got you:\n\nβ€’ πŸ—ΊοΈ [Map](/) β€” spots, shops, events near you\nβ€’ πŸ§ͺ [The Lab](/lab) β€” coaches, filmers, editors\nβ€’ πŸ“– [Glossary](/glossary) β€” 150+ tricks & terms\nβ€’ πŸ‘₯ [Crews](/crews) β€” find your people\n\nOr just tell me a **city** ("spots in Barcelona") or a **trick** ("what's a nollie") and I'll answer straight up. πŸ›Ή`; appendMessage({ role: 'sasquatch', text: fallback, timestamp: Date.now() }); } } catch (err) { @@ -1133,10 +1132,6 @@ Instructions: const inputDisabled = isThinking; - // A random "idle" joke so Sasquatch feels alive on the empty chat state. - // Recomputed only when the panel is (re)opened fresh, not on every render. - const idleJoke = useMemo(() => ethosJoke(), [showChat]); - // Build a fallback generic message for pages with no specific context const activeMessage = message ?? { id: 'generic', @@ -1149,8 +1144,9 @@ Instructions: 'Any upcoming events?', 'What are crews?', 'How do zaps work?', + 'What is Nostr?', 'What is My Stash?', - 'What is the Lab?', + 'Is this free?', ], enableChat: true, }; @@ -1311,13 +1307,6 @@ Instructions: ) : (
- {/* Idle joke β€” a little personality on the empty state */} - {chatMessages.length === 0 && ( -
- 🦧{idleJoke} -
- )} - {/* Suggested questions */} {chatMessages.length === 0 && activeMessage.suggestedQuestions && (
diff --git a/src/hooks/useSasquatchGuide.ts b/src/hooks/useSasquatchGuide.ts index 4b64f95..e88e6cd 100644 --- a/src/hooks/useSasquatchGuide.ts +++ b/src/hooks/useSasquatchGuide.ts @@ -2,11 +2,6 @@ import { useState, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import type { GuideMessage } from '@/components/SasquatchGuide'; -import { - LAB_JOKES, - CREW_JOKES, - randomJoke as getRandomJoke, -} from '@/lib/sasquatchJokes'; /** * Sasquatch Guide - Context-aware helper for onboarding and tips @@ -94,13 +89,12 @@ export function useSasquatchGuide() { }; } - // Show on The Lab page with random jokes + // Show on The Lab page else if (location.pathname === '/lab') { - const joke = getRandomJoke(LAB_JOKES); message = { id: 'lab-guide', title: 'Welcome to The Lab! πŸŽ“', - message: `This is where the magic happens! Find coaches who can teach you anything from kickflips to darkslides, or connect with filmers to capture your best sessions. Filter by skills, check their experience, and book a session. Remember - everyone started somewhere!\n\n${joke}`, + message: `This is where the magic happens! Find coaches who can teach you anything from kickflips to darkslides, or connect with filmers to capture your best sessions. Filter by skills, check their experience, and book a session. Remember - everyone started somewhere!`, context: 'lab', suggestedQuestions: [ 'Find coaches', @@ -126,11 +120,10 @@ export function useSasquatchGuide() { // Show on the Crews page else if (location.pathname === '/crews') { - const joke = getRandomJoke(CREW_JOKES); message = { id: 'crews-guide', title: 'Crews 🀘', - message: `Crews are your map-anchored skate family β€” the people you skate WITH, not who you hire. Every crew has home turf on the map, home spots, members and a manifesto. Members confirm from their own keys, so the roster's legit. Start your own or find your people!\n\n${joke}`, + message: `Crews are your map-anchored skate family β€” the people you skate WITH, not who you hire. Every crew has home turf on the map, home spots, members and a manifesto. Members confirm from their own keys, so the roster's legit. Start your own or find your people!`, context: undefined, suggestedQuestions: [ 'What are crews?', @@ -152,7 +145,7 @@ export function useSasquatchGuide() { } // /map: never auto-show β€” user opens Sasquatch by tapping the floating bubble - // The map guide context + jokes are still available in the generic fallback inside SasquatchGuide + // The map guide context is still available in the generic fallback inside SasquatchGuide else if (location.pathname === '/map') { message = undefined; } diff --git a/src/lib/sasquatchJokes.ts b/src/lib/sasquatchJokes.ts deleted file mode 100644 index 14da4ad..0000000 --- a/src/lib/sasquatchJokes.ts +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Sasquatch's joke book 🦧 - * ───────────────────────────────────────────────────────────────────────────── - * A shared, framework-agnostic library of skate jokes + gentle roasts of the - * "buy-my-course, KYC-your-sats" Bitcoin-influencer crowd. Used by the Sasquatch - * guide for idle personality and by the free-tier fallback so the bot always has - * something fun to say even when the AI brain is unreachable. - * - * Keep it playful, never mean-spirited. The running gag: SkateSpots is free, - * self-custodial and no-KYC β€” the opposite of the grifters. - */ - -// ─── Classic skate jokes ────────────────────────────────────────────────────── -export const SKATE_JOKES = [ - "Why did the skateboarder bring a ladder to the session? The kickflips were on another level. πŸ›Ή", - "What do you call a sasquatch who can tre flip? A myth. 🦧", - "Why did the skateboard go to therapy? Too many commitment issues... with grinds. πŸ˜…", - "I tried teaching a tree to skate. Went great till it got board. 🌲", - "Why did the ledge break up with the handrail? Too much grinding in the relationship. πŸ’”", - "How many skaters to change a lightbulb? None β€” they're too busy trying to ollie over it. πŸ’‘", - "What's a skater's favorite music? BOARD rock. ...I'll show myself out. 🎸", - "Why don't spots get lonely? Skaters always drop in. 😎", - "Rain check literally means 'go check the mini-ramp under the bridge.' β˜”πŸ›Ή", - "Bail hard, tuck early, credit the spot. That's the whole philosophy. πŸ€™", -]; - -// ─── Nostr / self-custody / no-KYC jokes ───────────────────────────────────── -// The heart of the request: mock the influencer-industrial complex that tells -// you to be your own bank... on their KYC exchange, with their referral link. -export const BITCOIN_KYC_JOKES = [ - "A Bitcoin influencer told me to 'be my own bank' β€” right after making me upload my passport to *his* exchange. 🀑", - "Guy sells a $999 'sovereignty' course, then asks for your ID, your selfie, and your firstborn's SSN. Real free, that. πŸͺͺ", - "Not your keys, not your coins. Not your face-scan either β€” but the KYC bro forgot that part. πŸ“ΈβŒ", - "Influencer: 'Bitcoin is freedom!' Also influencer: 'Sign up with my referral code and KYC in 3 easy steps.' πŸ™ƒ", - "Some dude on a podcast: 'I'm early, I'm a whale.' Bro your cold wallet is a Coinbase screenshot. πŸ‹πŸ’€", - "'DYOR,' says the guy whose research was a paid tweet thread. Here on SkateSpots you keep your own keys. πŸ”‘", - "KYC = Know Your Customer. Self-custody = Nobody's Business But Yours. Skate free. πŸ›Ή", - "They'll sell you a hardware wallet, a seed-phrase steel plate, AND a course on how to use them. Meanwhile you just... don't KYC. 😌", - "Orange-pill grifter voice: 'Have fun staying poor!' Says the man with 40 open exchange accounts. 🍊", - "A laser-eyes profile pic does not, in fact, secure your funds. Your keys do. And nobody scanned your face for those. πŸ‘€βš‘", - "The most decentralized thing that influencer owns is his three burner Twitter accounts. 🐦", - "Zap a skater directly, no middleman, no 'creator monetization program,' no KYC. That's the whole flex. βš‘πŸ€™", - "'Number go up' hits different when you didn't hand your ID to a hack-waiting-to-happen exchange. πŸ“ˆπŸ”’", - "The KYC bros want your data. The Sasquatch wants your best line. Only one of us respects your privacy. 🦧", - "Buy the dip, they said. Then leaked your dip AND your driver's license. Self-custody, kids. 🀦", -]; - -// ─── Location / map jokes ───────────────────────────────────────────────────── -export const MAP_JOKES = [ - "Why did the skate spot go to the doctor? Too many cracks. Report those conditions! 🩹", - "X marks the spot β€” and a sasquatch ALWAYS finds it. πŸ—ΊοΈ", - "Found a spot so perfect I thought I was dreaming. Turns out I was just board. πŸ’€", - "A map without your local spots is just... geography homework. Add yours. πŸ“", -]; - -// ─── The Lab jokes ──────────────────────────────────────────────────────────── -export const LAB_JOKES = [ - "Why did the skater bring a camera to The Lab? To capture the moment before they bail. πŸ“Έ", - "Coaches here can teach anything from kickflips to darkslides. No influencer upsell, promise. πŸŽ“", - "A good filmer makes your sketchy landing look like a Thrasher cover. πŸŽ₯", - "What's the difference between a bad skater and a pizza? A coach can fix one of them. πŸ•", -]; - -// ─── Crew jokes ─────────────────────────────────────────────────────────────── -export const CREW_JOKES = [ - "A board shared is a board doubled. Roll with a crew. 🀘", - "A crew is like grip tape β€” sticks together, keeps everyone from slipping. πŸ›Ή", - "Crews don't gatekeep spots β€” they open gates. πŸšͺ", - "What do you call a sasquatch's crew? The Bigfoot Brigade β€” big tracks, bigger sessions. 🦧", -]; - -/** All the jokes, for random idle personality across the app. */ -export const ALL_JOKES = [ - ...SKATE_JOKES, - ...BITCOIN_KYC_JOKES, - ...MAP_JOKES, - ...CREW_JOKES, -]; - -/** Pick a random joke from a category (or all). */ -export function randomJoke(pool: readonly string[] = ALL_JOKES): string { - return pool[Math.floor(Math.random() * pool.length)]; -} - -/** - * A joke pool that leans into the SkateSpots ethos β€” half skate humor, half - * gentle roasting of the KYC-your-audience Bitcoin-influencer crowd. Good for - * the free-tier "AI is napping" fallback where we want to stay charming. - */ -export function ethosJoke(): string { - const pool = Math.random() < 0.5 ? BITCOIN_KYC_JOKES : SKATE_JOKES; - return randomJoke(pool); -}