feat(cordn): expose and copy the Cordn group share link
This commit is contained in:
parent
74249e304e
commit
27f3434475
2 changed files with 55 additions and 10 deletions
19
AGENTS.md
19
AGENTS.md
|
|
@ -1486,7 +1486,14 @@ session with **no other memory of this project**. So:
|
|||
`send`/`createChat`/`requestJoin`/`approve`, and **filters welcomes by gid** so
|
||||
one crew can't adopt another crew's chat. Coordinator announce relays are now
|
||||
`["wss://relay.skate-spots.org"]` only (removed purplepag.es/nostr.band/nos.lol
|
||||
timeouts; logs show `local[10002=ok]`).
|
||||
timeouts; logs show `local[10002=ok]`). Advanced also exposes the Cordn share
|
||||
link `https://cordn.net/chat/<cordn1…>` (open/copy). Per Cordn's group-ref
|
||||
spec the `cordn1…` ref is a **share** primitive: a client can publish a key
|
||||
package and submit a join request, then the founder approves. The reliable
|
||||
"join us" link for normal users is still
|
||||
`https://skate-spots.org/#/crew/<pk>/<id>?tab=mls`; use the Cordn link for
|
||||
Staircase/Cordn clients. ⚠️ cordn.net's web client still stalls after NIP-42
|
||||
(upstream issue), so it is not the primary onboarding path yet.
|
||||
- **Map site-links strip (2026-10-05):** the desktop footer is hidden on the map
|
||||
(full-bleed), so `components/MapFooterStrip.tsx` surfaces the same links
|
||||
(Newsletter/License/Privacy/Collaborators + "not sponsored by OpenSats") as an
|
||||
|
|
@ -1688,6 +1695,16 @@ session with **no other memory of this project**. So:
|
|||
propagation so Radix typeahead does not hijack typing) and the inline/mobile
|
||||
variant; keys `nav.searchLanguages`/`nav.noLanguages` live in en/es only (other
|
||||
locales fall back). The Settings `LanguageSelector` grid is searchless by design.
|
||||
- **Menu audit (2026-10-27):** rendered EN/DE menus at 390×844 and 1280×900.
|
||||
Alignment was already start-aligned with no clipped labels. Fixed the real
|
||||
problems: the mobile burger's inline 28-language list made the sheet
|
||||
**3,168px** tall and buried the picker — it is now a **Language row + dedicated
|
||||
sub-view** (Back/search/list), cutting the main sheet to ~1,384px. Language
|
||||
dropdown rows are `min-h-11`; the mobile user menu is 44px; desktop More is
|
||||
40px. Language search only auto-focuses for `pointer: fine` (no phone keyboard
|
||||
covering the list). Crew tabs use `1.1fr / 1fr / 1.3fr` + 13px labels so
|
||||
“Private chat”/“Privater Chat” no longer truncate. Re-check with
|
||||
`node scripts/smoke-test.mjs` + a menu screenshot if you change the header.
|
||||
- **Community stats (`/stats`, 2026-10-01):** `useGrowthStats` + `CommunityStatsPage`.
|
||||
- ⚠️ **A relay outage used to render a board of ZEROS as truth** — every
|
||||
sub-query ended in `.catch(() => [])`. The queryFn now counts failures (a
|
||||
|
|
|
|||
|
|
@ -761,6 +761,19 @@ function AdvancedPanel({
|
|||
onCopyRef: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [copiedCordn, setCopiedCordn] = useState(false);
|
||||
const cordnUrl = groupRef ? `https://cordn.net/chat/${groupRef}` : null;
|
||||
const copyCordn = async () => {
|
||||
if (!cordnUrl) return;
|
||||
try {
|
||||
await navigator.clipboard.writeText(cordnUrl);
|
||||
setCopiedCordn(true);
|
||||
window.setTimeout(() => setCopiedCordn(false), 1500);
|
||||
} catch {
|
||||
// clipboard blocked — the link is visible to select.
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<details className="group rounded-md border border-white/10 bg-black/20 px-2.5 py-2 text-left">
|
||||
<summary className="flex cursor-pointer list-none items-center gap-1.5 text-[11px] text-gray-500">
|
||||
|
|
@ -801,15 +814,30 @@ function AdvancedPanel({
|
|||
{copied ? t('cordnUi.copied') : t('cordnUi.copyRef')}
|
||||
</Button>
|
||||
</div>
|
||||
<a
|
||||
href={`https://cordn.net/chat/${groupRef}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1 text-[11px] font-medium text-teal-300 transition-colors hover:text-teal-200"
|
||||
>
|
||||
<ExternalLink className="h-3 w-3" />{' '}
|
||||
{t('socialUi.crewCoordinator.openCordnGroup')}
|
||||
</a>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<a
|
||||
href={cordnUrl ?? '#'}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1 text-[11px] font-medium text-teal-300 transition-colors hover:text-teal-200"
|
||||
>
|
||||
<ExternalLink className="h-3 w-3" />{' '}
|
||||
{t('socialUi.crewCoordinator.openCordnGroup')}
|
||||
</a>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
className="h-7 gap-1 px-2 text-[11px] text-gray-400"
|
||||
onClick={() => void copyCordn()}
|
||||
>
|
||||
{copiedCordn ? (
|
||||
<Check className="h-3 w-3 text-teal-400" />
|
||||
) : (
|
||||
<Copy className="h-3 w-3" />
|
||||
)}
|
||||
{copiedCordn ? t('cordnUi.copied') : t('cordnUi.copyRef')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue