feat: gate Amber Cordn notices and refresh Zapstore listing

This commit is contained in:
SkateSpots 2026-10-28 14:02:04 +07:00
parent 0c0917b70b
commit 9b6bdd2b53
3 changed files with 57 additions and 57 deletions

View file

@ -225,7 +225,7 @@ export function NotificationBell({
requests: cordnJoinRequests,
isLoading: cordnJoinLoading,
dismiss: dismissCordnJoin,
} = useCordnJoinNotifications();
} = useCordnJoinNotifications(open);
const { lastRead, seenAt, markAllRead } = useNotificationsRead();
// Buying/selling steps: an offer on your listing, a counter it's your turn to

View file

@ -1,8 +1,10 @@
import { useCallback, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { useNostrLogin } from '@nostrify/react/login';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useLocalStorage } from '@/hooks/useLocalStorage';
import { useSkateRelays } from '@/hooks/useSkateRelays';
import { hasNip44, isInteractiveSigner } from '@/lib/signerCapabilities';
import { APP_DATA_KIND } from '@/lib/types';
import {
CORDN_JOIN_TAG,
@ -17,11 +19,15 @@ const DISMISSED_KEY = 'skatespots:cordn-join-dismissed';
* background watcher as encrypted NIP-78 events. The watcher also sends the
* same event as a NIP-17 DM, so the OS push path works while the app is closed.
*/
export function useCordnJoinNotifications() {
export function useCordnJoinNotifications(opened = false) {
const { user } = useCurrentUser();
const { logins } = useNostrLogin();
const interactive = isInteractiveSigner(user, logins);
const { querySkateContent, getQueryKeySuffix } = useSkateRelays();
const [dismissed, setDismissed] = useLocalStorage<string[]>(DISMISSED_KEY, []);
const canRead = !!user?.pubkey && !!user.signer.nip44;
// Amber prompts once per decrypt. Load these only when the bell is opened;
// passive signers can fetch them quietly in the background.
const canRead = !!user?.pubkey && hasNip44(user, logins) && (!interactive || opened);
const query = useQuery({
queryKey: ['cordn-join-notifications', user?.pubkey, getQueryKeySuffix()],

View file

@ -1,104 +1,98 @@
# Zapstore publish config for SkateSpots
# https://zapstore.dev
#
# HOW TO PUBLISH
# ──────────────
# 1. Build the APK locally:
# npm run android:build
#
# 2. Publish to Zapstore:
# SIGN_WITH=nsec1... zsp publish zapstore.yaml
#
# Or with browser extension (NIP-07):
# SIGN_WITH=browser zsp publish zapstore.yaml
#
# zsp will:
# - Parse the APK (version, cert, permissions, icon)
# - Upload APK + icon to cdn.zapstore.dev (Blossom)
# - Sign and publish events to relay.zapstore.dev
# Publish: scripts/release.sh patch --yes (reads ~/.config/skatespots/zsp.env)
# or: SIGN_WITH=... zsp publish --quiet zapstore.yaml
# ═══════════════════════════════════════════════════════════════════
# SOURCE CONFIGURATION
# ═══════════════════════════════════════════════════════════════════
# Source code, shown as the "Source" link in the Zapstore listing.
# This points at the NIP-34 git repository announcement (kind 30617),
# rendered as a browsable web page by nostrhub.io. A plain HTTPS URL is
# used (rather than a bare naddr) so Zapstore renders it as a clickable
# Source link — a bare naddr coordinate was published correctly but not
# surfaced in the UI.
repository: https://nostrhub.io/naddr1qvzqqqrhnypzqg88e9f588nx7wyz4wt0ura23w3yd4hmztqrkr95utwyvgachjepqyd8wumn8ghj7emfwsh8x6rpddjhxur9v9ex2tnyd9uj7qq22d4kzar92dcx7arnhyhdwn
# Local APK built by: npm run android:build
release_source: ./android/app/build/outputs/apk/release/app-release.apk
# Guard: refuse to publish if the configured signer is not the app identity.
pubkey: npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx
# ═══════════════════════════════════════════════════════════════════
# APP METADATA
# ═══════════════════════════════════════════════════════════════════
name: SkateSpots
summary: The decentralized skate map & community, built on Nostr
summary: The decentralized skate map, crews, private chat and gear — on Nostr.
description: |
Discover skate spots worldwide, start your own Crew, find coaches,
photographers, builders and filmers, join events, buy/sell gear, and
connect with the global skateboarding community.
Discover skate spots worldwide, start a crew, find coaches, filmers,
photographers, builders and editors, join events, trade gear, and connect
with the global skateboarding community.
Built on Nostr — decentralized, censorship-resistant, no ads, no tracking.
Powered by Bitcoin Lightning zaps.
Built on Nostr: decentralized, censorship-resistant, no ads, no tracking,
no central account. Lightning zaps and Cashu are supported where available.
Features:
- Interactive world map with a "Near Me" locator
- Live spot status reports — active, bust, skate-stopped, closed or gone
- Crews: build your local skate community, map-anchored
- The Lab: coaches, filmers, photographers, builders & video editors
- Events calendar
- Buy/sell used skate gear
- Private encrypted gear stash
- Local tours — guides show you the hidden spots
- Lightning zaps to content creators
- Works offline (PWA)
- Interactive world map with a Near Me locator and spot status reports
- Crews with members, roles, events and invites
- Private chat: NIP-17 DMs, plus MLS end-to-end encrypted crew rooms
- The Lab: coaches, filmers, photographers, builders and other crafts
- Events calendar, tours and local guides
- Marketplace for used gear, with barter and Lightning payments
- Private encrypted gear Stash
- On-device message translation in 24 languages (text never leaves the phone)
- Weekly newsletter and a public Cordn community room
- Works offline; web push and local Android notifications
website: https://skate-spots.org
license: AGPL-3.0-only
# App icon (local path or URL). YAML config ALWAYS wins over the icon
# extracted from the APK or pulled from external metadata sources.
# This is the orange SkateSpots logo used everywhere else.
# Launcher / listing icon.
icon: ./public/images/icon-1024.png
# Tags for Zapstore discovery
# Listing screenshots (uploaded by zsp to the Zapstore CDN).
images:
- ./public/images/screenshots/map.png
- ./public/images/screenshots/spot.png
- ./public/images/screenshots/marketplace.png
# Discovery tags.
tags:
- sports
- social
- nostr
- bitcoin
- maps
- chat
- privacy
- marketplace
# Nostr NIPs supported by this app
# Nostr NIPs used by the app.
supported_nips:
- "01"
- "05"
- "07"
- "13"
- "17"
- "19"
- "23"
- "25"
- "44"
- "46"
- "47"
- "51"
- "55"
- "56"
- "57"
- "59"
- "65"
- "75"
- "78"
- "99"
# ═══════════════════════════════════════════════════════════════════
# METADATA SOURCES
# ═══════════════════════════════════════════════════════════════════
# Do NOT enrich icon/metadata from external sources — we set everything
# explicitly here so the correct orange logo is always used. Play Store
# enrichment was overriding our icon with the wrong (blue launcher) image.
# Keep metadata source-free: the YAML is the source of truth for the icon,
# screenshots and copy.
metadata_sources: []
# ═══════════════════════════════════════════════════════════════════
# RELEASE NOTES
# ═══════════════════════════════════════════════════════════════════
# Path to a plain-text file with release notes for this version.
# zsp reads this file and publishes its contents to Zapstore.
# Release notes for this version.
release_notes: ./release-notes.txt