diff --git a/package-lock.json b/package-lock.json
index baf4ea6..b370b9c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2946,12 +2946,6 @@
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
"license": "BSD-3-Clause"
},
- "node_modules/@protobufjs/inquire": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.2.tgz",
- "integrity": "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==",
- "license": "BSD-3-Clause"
- },
"node_modules/@protobufjs/path": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
@@ -10926,9 +10920,9 @@
"license": "MIT"
},
"node_modules/protobufjs": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.3.tgz",
- "integrity": "sha512-+k0vdJKNdW+Vu+dYe8tZA/VvQb6XKNWexC6URwBFXxNnjLJz9nQJCemGyNgRAWD+B7+nGNc9qMPGwcD7s4nzUw==",
+ "version": "7.6.5",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz",
+ "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -10938,7 +10932,6 @@
"@protobufjs/eventemitter": "^1.1.1",
"@protobufjs/fetch": "^1.1.1",
"@protobufjs/float": "^1.0.2",
- "@protobufjs/inquire": "^1.1.2",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.1",
diff --git a/package.json b/package.json
index 8211d93..d218ece 100644
--- a/package.json
+++ b/package.json
@@ -184,7 +184,7 @@
},
"overrides": {
"@tanstack/query-core": "$@tanstack/react-query",
- "protobufjs": "7.6.3",
+ "protobufjs": "7.6.5",
"sharp": "0.35.5"
}
}
diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx
index 70d8ac7..f30a2cd 100644
--- a/src/components/Layout.tsx
+++ b/src/components/Layout.tsx
@@ -522,6 +522,8 @@ export function Layout({ children, noPadding }: LayoutProps) {
// The map is full-bleed (it manages its own height), so it gets no bottom
// padding even though it shares this one persistent layout with every route.
const isFullBleed = noPadding || location.pathname === '/' || location.pathname === '/map';
+ // The floating assistant must not cover form controls on long-form pages.
+ const hideSasquatch = /^\/(become|create|edit|supporters|onboarding)(\/|$)/.test(location.pathname);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [mobileLanguageView, setMobileLanguageView] = useState(false);
// One auth dialog for the header + burger menu. Owning it here (not inside
@@ -1262,12 +1264,14 @@ export function Layout({ children, noPadding }: LayoutProps) {
{/* Sasquatch Guide (all screens) — lazy; not needed at first paint */}
-
-
-
+ {!hideSasquatch && (
+
+
+
+ )}
{/* Set Status Dialog — lazy (on-demand modal) */}
diff --git a/src/hooks/useFollowing.ts b/src/hooks/useFollowing.ts
index 21e7741..02af689 100644
--- a/src/hooks/useFollowing.ts
+++ b/src/hooks/useFollowing.ts
@@ -56,7 +56,7 @@ export function useFollowers(pubkey?: string) {
// Query all kind 3 events that have a p tag with our pubkey
const events = await nostr.query(
- [{ kinds: [3], '#p': [targetPubkey], limit: 100 }],
+ [{ kinds: [3], '#p': [targetPubkey], limit: 500 }],
{ signal }
);
diff --git a/src/hooks/useGrowthStats.ts b/src/hooks/useGrowthStats.ts
index 1459898..07dd354 100644
--- a/src/hooks/useGrowthStats.ts
+++ b/src/hooks/useGrowthStats.ts
@@ -17,7 +17,7 @@ import {
SKATE_MUSICIAN_KIND,
SKATE_JUDGE_KIND,
SKATE_ORGANIZER_KIND,
- SKATE_BARBER_KIND, SKATE_TRANSPORT_KIND,
+ SKATE_BARBER_KIND, SKATE_TRANSPORT_KIND, SKATE_DESIGNER_KIND,
SKATE_TOUR_KIND,
SKATE_CREW_KIND,
MARKETPLACE_ITEM_KIND,
@@ -80,6 +80,7 @@ export interface GrowthStats {
totalOrganizers: number;
totalBarbers: number;
totalTransport: number;
+ totalDesigners: number;
totalTours: number;
totalCrews: number;
/** All unique pubkeys that have published any content */
@@ -232,6 +233,7 @@ export function useGrowthStats() { // Community stats read from the CANONICAL c
organizerEvents,
barberEvents,
transportEvents,
+ designerEvents,
listingEvents,
tradeEvents,
] = await Promise.all([
@@ -256,6 +258,7 @@ export function useGrowthStats() { // Community stats read from the CANONICAL c
querySkateContent([{ kinds: [SKATE_ORGANIZER_KIND], limit: 500 }], { signal }).catch(() => []),
querySkateContent([{ kinds: [SKATE_BARBER_KIND], limit: 500 }], { signal }).catch(() => []),
querySkateContent([{ kinds: [SKATE_TRANSPORT_KIND], limit: 500 }], { signal }).catch(() => []),
+ querySkateContent([{ kinds: [SKATE_DESIGNER_KIND], limit: 500 }], { signal }).catch(() => []),
// Marketplace: live listings + completed-trade attestations.
querySkateContent([{ kinds: [MARKETPLACE_ITEM_KIND], '#t': ['skateboarding'], limit: 2000 }], { signal }).catch(() => []),
querySkateContent([{ kinds: [TRADE_ATTESTATION_KIND], limit: 1000 }], { signal }).catch(() => []),
@@ -299,8 +302,9 @@ export function useGrowthStats() { // Community stats read from the CANONICAL c
const organizers = dedup(organizerEvents);
const barbers = dedup(barberEvents);
const transport = dedup(transportEvents);
+ const designers = dedup(designerEvents);
// Aggregate of the "other" crafts for active-mapper / total rollups.
- const otherLab = [...artists, ...graffiti, ...tattoo, ...trainers, ...musicians, ...judges, ...organizers, ...barbers, ...transport];
+ const otherLab = [...artists, ...graffiti, ...tattoo, ...trainers, ...musicians, ...judges, ...organizers, ...barbers, ...transport, ...designers];
// ── Marketplace ──────────────────────────────────────────────────────
// Showcase-only stash items are public but NOT for sale, so exclude them.
@@ -579,6 +583,7 @@ export function useGrowthStats() { // Community stats read from the CANONICAL c
totalOrganizers: organizers.length,
totalBarbers: barbers.length,
totalTransport: transport.length,
+ totalDesigners: designers.length,
totalTours: tours.length,
totalCrews: crews.length,
totalMappers: allPubkeys.size,
diff --git a/src/i18n/ca/batch6.ts b/src/i18n/ca/batch6.ts
index bbe3047..6efe2d1 100644
--- a/src/i18n/ca/batch6.ts
+++ b/src/i18n/ca/batch6.ts
@@ -714,6 +714,7 @@ const batch6 = {
judges: "Jutges",
organizers: "Organitzadors",
barbers: "Barbers",
+ designers: "Dissenyadors",
showFewer: "Mostra'n menys",
showAllCrafts: "Mostra els 15 oficis",
community: "Comunitat",
diff --git a/src/i18n/cs/batch4.ts b/src/i18n/cs/batch4.ts
index 7f649c8..dff69ac 100644
--- a/src/i18n/cs/batch4.ts
+++ b/src/i18n/cs/batch4.ts
@@ -688,6 +688,7 @@ export const csBatch4 = {
judges: "Rozhodčí",
organizers: "Organizátoři",
barbers: "Barbeři",
+ designers: "Designéři",
showFewer: "Zobrazit méně",
showAllCrafts: "Zobrazit všech 15 řemesel",
community: "Komunita",
diff --git a/src/i18n/de/batch4.ts b/src/i18n/de/batch4.ts
index ffd43ff..153842e 100644
--- a/src/i18n/de/batch4.ts
+++ b/src/i18n/de/batch4.ts
@@ -688,6 +688,7 @@ const deBatch4 = {
judges: "Juroren",
organizers: "Organisatoren",
barbers: "Barbiere",
+ designers: "Designer:innen",
showFewer: "Weniger anzeigen",
showAllCrafts: "Alle 15 Handwerke anzeigen",
community: "Community",
diff --git a/src/i18n/el/batch4.ts b/src/i18n/el/batch4.ts
index 6957859..7b0ea58 100644
--- a/src/i18n/el/batch4.ts
+++ b/src/i18n/el/batch4.ts
@@ -688,6 +688,7 @@ const elBatch4 = {
judges: "Κριτές",
organizers: "Διοργανωτές",
barbers: "Κουρείς",
+ designers: "Σχεδιαστές",
showFewer: "Εμφάνιση λιγότερων",
showAllCrafts: "Εμφάνιση και των 15 ειδικοτήτων",
community: "Κοινότητα",
diff --git a/src/i18n/en.ts b/src/i18n/en.ts
index f34195b..39bf508 100644
--- a/src/i18n/en.ts
+++ b/src/i18n/en.ts
@@ -6521,6 +6521,7 @@ walletUi: {
organizers: 'Organizers',
barbers: 'Barbers',
transport: 'Transport',
+ designers: 'Designers',
showFewer: 'Show fewer',
showAllCrafts: 'Show all 15 crafts',
community: 'Community',
diff --git a/src/i18n/es.ts b/src/i18n/es.ts
index bb932d6..b5ad3ca 100644
--- a/src/i18n/es.ts
+++ b/src/i18n/es.ts
@@ -6521,6 +6521,7 @@ walletUi: {
organizers: 'Organizadores',
barbers: 'Barberos',
transport: 'Transporte',
+ designers: 'Diseñadores',
showFewer: 'Mostrar menos',
showAllCrafts: 'Mostrar los 15 oficios',
community: 'Comunidad',
diff --git a/src/i18n/eu/batch6.ts b/src/i18n/eu/batch6.ts
index 07f6e29..b76e3d3 100644
--- a/src/i18n/eu/batch6.ts
+++ b/src/i18n/eu/batch6.ts
@@ -714,6 +714,7 @@ const batch6 = {
judges: "Epaileak",
organizers: "Antolatzaileak",
barbers: "Bizarginak",
+ designers: "Diseinatzaileak",
showFewer: "Erakutsi gutxiago",
showAllCrafts: "Erakutsi 15 lanbide guztiak",
community: "Komunitatea",
diff --git a/src/i18n/fr/batch4.ts b/src/i18n/fr/batch4.ts
index 75c10f0..e2cbd2b 100644
--- a/src/i18n/fr/batch4.ts
+++ b/src/i18n/fr/batch4.ts
@@ -688,6 +688,7 @@ const frBatch4 = {
judges: "Juges",
organizers: "Organisateurs",
barbers: "Coiffeurs",
+ designers: "Concepteurs",
showFewer: "Afficher moins",
showAllCrafts: "Afficher les 15 disciplines",
community: "Communauté",
diff --git a/src/i18n/gl/batch6.ts b/src/i18n/gl/batch6.ts
index 1f46e05..9411f08 100644
--- a/src/i18n/gl/batch6.ts
+++ b/src/i18n/gl/batch6.ts
@@ -714,6 +714,7 @@ const batch6 = {
"judges": "Xuíces",
"organizers": "Organizadores",
"barbers": "Barbeiros",
+ "designers": "Deseñadores",
"showFewer": "Amosar menos",
"showAllCrafts": "Amosar os 15 oficios",
"community": "Comunidade",
diff --git a/src/i18n/hi/batch6.ts b/src/i18n/hi/batch6.ts
index 153d224..1ab9c22 100644
--- a/src/i18n/hi/batch6.ts
+++ b/src/i18n/hi/batch6.ts
@@ -714,6 +714,7 @@ const batch6 = {
"judges": "जज",
"organizers": "आयोजक",
"barbers": "नाई",
+ "designers": "डिज़ाइनर",
"showFewer": "कम दिखाएँ",
"showAllCrafts": "सभी 15 क्राफ़्ट दिखाएँ",
"community": "समुदाय",
diff --git a/src/i18n/id/batch4.ts b/src/i18n/id/batch4.ts
index 55afc36..da52ffe 100644
--- a/src/i18n/id/batch4.ts
+++ b/src/i18n/id/batch4.ts
@@ -694,6 +694,7 @@ const idBatch4 = {
judges: 'Juri',
organizers: 'Penyelenggara',
barbers: 'Tukang Cukur',
+ designers: 'Desainer',
showFewer: 'Tampilkan lebih sedikit',
showAllCrafts: 'Tampilkan semua 15 keahlian',
community: 'Komunitas',
diff --git a/src/i18n/it/batch4.ts b/src/i18n/it/batch4.ts
index dab9640..9eb8caa 100644
--- a/src/i18n/it/batch4.ts
+++ b/src/i18n/it/batch4.ts
@@ -688,6 +688,7 @@ const itBatch4 = {
judges: "Giudici",
organizers: "Organizzatori",
barbers: "Barbieri",
+ designers: "Progettisti",
showFewer: "Mostra meno",
showAllCrafts: "Mostra tutti i 15 mestieri",
community: "Community",
diff --git a/src/i18n/ja/batch7.ts b/src/i18n/ja/batch7.ts
index 48cbc45..6d84617 100644
--- a/src/i18n/ja/batch7.ts
+++ b/src/i18n/ja/batch7.ts
@@ -697,6 +697,7 @@ const jaBatch7 = {
judges: 'ジャッジ',
organizers: 'オーガナイザー',
barbers: 'バーバー',
+ designers: 'デザイナー',
showFewer: '表示を減らす',
showAllCrafts: '15職種すべて表示',
community: 'コミュニティ',
diff --git a/src/i18n/ko/batch4.ts b/src/i18n/ko/batch4.ts
index 5b84bc8..ff75e3d 100644
--- a/src/i18n/ko/batch4.ts
+++ b/src/i18n/ko/batch4.ts
@@ -696,6 +696,7 @@ const koBatch4 = {
judges: '심판',
organizers: '주최자',
barbers: '바버',
+ designers: '디자이너',
showFewer: '접기',
showAllCrafts: '15개 분야 모두 보기',
community: '커뮤니티',
diff --git a/src/i18n/nl/batch4.ts b/src/i18n/nl/batch4.ts
index bb7570b..3aad435 100644
--- a/src/i18n/nl/batch4.ts
+++ b/src/i18n/nl/batch4.ts
@@ -696,6 +696,7 @@ const nlBatch4 = {
judges: 'Juryleden',
organizers: 'Organisatoren',
barbers: 'Barbers',
+ designers: 'Ontwerpers',
showFewer: 'Minder tonen',
showAllCrafts: 'Alle 15 ambachten tonen',
community: 'Community',
diff --git a/src/i18n/pl/batch4.ts b/src/i18n/pl/batch4.ts
index ca844a3..11ca5aa 100644
--- a/src/i18n/pl/batch4.ts
+++ b/src/i18n/pl/batch4.ts
@@ -688,6 +688,7 @@ const plBatch4 = {
judges: "Sędziowie",
organizers: "Organizatorzy",
barbers: "Barberzy",
+ designers: "Projektanci",
showFewer: "Pokaż mniej",
showAllCrafts: "Pokaż wszystkie 15 rzemiosł",
community: "Społeczność",
diff --git a/src/i18n/pt/batch4.ts b/src/i18n/pt/batch4.ts
index 07694dc..53ebac2 100644
--- a/src/i18n/pt/batch4.ts
+++ b/src/i18n/pt/batch4.ts
@@ -775,6 +775,7 @@ const ptBatch4 = {
judges: 'Jurados',
organizers: 'Organizadores',
barbers: 'Barbeiros',
+ designers: 'Projetistas',
showFewer: 'Mostrar menos',
showAllCrafts: 'Mostrar todos os 15 ofícios',
community: 'Comunidade',
diff --git a/src/i18n/ro/batch4.ts b/src/i18n/ro/batch4.ts
index d90d3ae..4eb0c26 100644
--- a/src/i18n/ro/batch4.ts
+++ b/src/i18n/ro/batch4.ts
@@ -688,6 +688,7 @@ const roBatch4 = {
judges: 'Juri',
organizers: 'Organizatori',
barbers: 'Frizeri',
+ designers: 'Designeri',
showFewer: 'Arată mai puține',
showAllCrafts: 'Arată toate cele 15 meserii',
community: 'Comunitate',
diff --git a/src/i18n/ru/batch4.ts b/src/i18n/ru/batch4.ts
index 00d5001..bd530b7 100644
--- a/src/i18n/ru/batch4.ts
+++ b/src/i18n/ru/batch4.ts
@@ -688,6 +688,7 @@ const ruBatch4 = {
judges: 'Судьи',
organizers: 'Организаторы',
barbers: 'Барберы',
+ designers: 'Дизайнеры',
showFewer: 'Показать меньше',
showAllCrafts: 'Показать все 15 ремёсел',
community: 'Сообщество',
diff --git a/src/i18n/sv/batch4.ts b/src/i18n/sv/batch4.ts
index 47d8ff5..b4a0570 100644
--- a/src/i18n/sv/batch4.ts
+++ b/src/i18n/sv/batch4.ts
@@ -688,6 +688,7 @@ const svBatch4 = {
judges: "Domare",
organizers: "Arrangörer",
barbers: "Barberare",
+ designers: "Formgivare",
showFewer: "Visa färre",
showAllCrafts: "Visa alla 15 hantverk",
community: "Community",
diff --git a/src/i18n/th/batch9.ts b/src/i18n/th/batch9.ts
index 0bbeed0..443bd5f 100644
--- a/src/i18n/th/batch9.ts
+++ b/src/i18n/th/batch9.ts
@@ -768,6 +768,7 @@ const thBatch9 = {
judges: 'กรรมการ',
organizers: 'ผู้จัด',
barbers: 'ช่างตัดผม',
+ designers: 'นักออกแบบ',
showFewer: 'แสดงน้อยลง',
showAllCrafts: 'แสดงทั้ง 15 อาชีพ',
community: 'ชุมชน',
diff --git a/src/i18n/tr/batch4.ts b/src/i18n/tr/batch4.ts
index b715b85..65506c0 100644
--- a/src/i18n/tr/batch4.ts
+++ b/src/i18n/tr/batch4.ts
@@ -688,6 +688,7 @@ const trBatch4 = {
judges: "Jüri üyeleri",
organizers: "Organizatörler",
barbers: "Berberler",
+ designers: "Tasarımcılar",
showFewer: "Daha az göster",
showAllCrafts: "15 zanaatın tümünü göster",
community: "Topluluk",
diff --git a/src/i18n/uk/batch4.ts b/src/i18n/uk/batch4.ts
index b887f99..bd6f344 100644
--- a/src/i18n/uk/batch4.ts
+++ b/src/i18n/uk/batch4.ts
@@ -688,6 +688,7 @@ const ukBatch4 = {
judges: "Судді",
organizers: "Організатори",
barbers: "Барбери",
+ designers: "Дизайнери",
showFewer: "Показати менше",
showAllCrafts: "Показати всі 15 напрямів",
community: "Спільнота",
diff --git a/src/i18n/vi/batch4.ts b/src/i18n/vi/batch4.ts
index d657395..dba91df 100644
--- a/src/i18n/vi/batch4.ts
+++ b/src/i18n/vi/batch4.ts
@@ -696,6 +696,7 @@ const viBatch4 = {
judges: 'Giám khảo',
organizers: 'Nhà tổ chức',
barbers: 'Thợ cắt tóc',
+ designers: 'Nhà thiết kế',
showFewer: 'Hiện ít hơn',
showAllCrafts: 'Hiện cả 15 nghề',
community: 'Cộng đồng',
diff --git a/src/i18n/zh-CN/batch4.ts b/src/i18n/zh-CN/batch4.ts
index 5579c4a..d1be0fe 100644
--- a/src/i18n/zh-CN/batch4.ts
+++ b/src/i18n/zh-CN/batch4.ts
@@ -693,6 +693,7 @@ const zhCNBatch4 = {
judges: "裁判",
organizers: "组织者",
barbers: "理发师",
+ designers: "设计师",
showFewer: "收起",
showAllCrafts: "显示全部 15 种手艺",
community: "社区",
diff --git a/src/i18n/zh-TW/batch4.ts b/src/i18n/zh-TW/batch4.ts
index 132b374..b507327 100644
--- a/src/i18n/zh-TW/batch4.ts
+++ b/src/i18n/zh-TW/batch4.ts
@@ -693,6 +693,7 @@ const zhTWBatch4 = {
judges: "裁判",
organizers: "組織者",
barbers: "理髮師",
+ designers: "設計師",
showFewer: "收起",
showAllCrafts: "顯示全部 15 種手藝",
community: "社群",
diff --git a/src/pages/CommunityStatsPage.tsx b/src/pages/CommunityStatsPage.tsx
index b1f280a..28896e0 100644
--- a/src/pages/CommunityStatsPage.tsx
+++ b/src/pages/CommunityStatsPage.tsx
@@ -16,7 +16,7 @@ import { formatAge } from '@/lib/routeCache';
const ANGOR_PROJECT_URL = 'https://angor.io/project/angor1qtunna00uqyx52rr0nvqa059z2gknhrmn7urd6z';
import { SKATE_RELAY } from '@/lib/types';
import { AreaChart, Area, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell, Legend } from 'recharts';
-import { MapPin, Store, Calendar, GraduationCap, Video, Scissors, Route, Users, Users2, Camera, Hammer, TrendingUp, Radio, Zap, ExternalLink, Trophy, FlaskConical, Palette, SprayCan, PenTool, Dumbbell, Music, Gavel, Tent, Sparkles, Truck, ShoppingBag, Tag, Handshake, Globe, RefreshCw } from 'lucide-react';
+import { MapPin, Store, Calendar, GraduationCap, Video, Scissors, Route, Users, Users2, Camera, Hammer, TrendingUp, Radio, Zap, ExternalLink, Trophy, FlaskConical, Palette, SprayCan, PenTool, Dumbbell, Music, Gavel, Tent, Sparkles, Truck, Shirt, ShoppingBag, Tag, Handshake, Globe, RefreshCw } from 'lucide-react';
// ─── Helpers ─────────────────────────────────────────────────────────────────
@@ -25,13 +25,13 @@ function labCraftTotal(s: {
totalCoaches: number; totalFilmers: number; totalEditors: number;
totalPhotographers: number; totalBuilders: number; totalArtists: number;
totalGraffiti: number; totalTattoo: number; totalTrainers: number;
- totalMusicians: number; totalJudges: number; totalOrganizers: number; totalBarbers: number; totalTransport: number;
+ totalMusicians: number; totalJudges: number; totalOrganizers: number; totalBarbers: number; totalTransport: number; totalDesigners: number;
}): number {
return (
s.totalCoaches + s.totalFilmers + s.totalEditors + s.totalPhotographers +
s.totalBuilders + s.totalArtists + s.totalGraffiti + s.totalTattoo +
s.totalTrainers + s.totalMusicians + s.totalJudges + s.totalOrganizers +
- s.totalBarbers + (s.totalTransport ?? 0)
+ s.totalBarbers + (s.totalTransport ?? 0) + (s.totalDesigners ?? 0)
);
}
@@ -323,6 +323,7 @@ export default function CommunityStatsPage() {
+