import { Button, ButtonProps } from '@/components/ui/button' import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog' import { Drawer, DrawerContent, DrawerOverlay, DrawerTrigger } from '@/components/ui/drawer' import { Separator } from '@/components/ui/separator' import { ExtendedKind } from '@/constants' import { getReplaceableEventIdentifier, getSharableEventId } from '@/lib/event' import { toChachiChat } from '@/lib/link' import { useScreenSize } from '@/providers/ScreenSizeProvider' import clientService from '@/services/client.service' import { ExternalLink } from 'lucide-react' import { Event, kinds, nip19 } from 'nostr-tools' import { Dispatch, SetStateAction, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' const clients: Record string }> = { nosta: { name: 'Nosta', getUrl: (id: string) => `https://nosta.me/${id}` }, snort: { name: 'Snort', getUrl: (id: string) => `https://snort.social/${id}` }, olas: { name: 'Olas', getUrl: (id: string) => `https://olas.app/e/${id}` }, primal: { name: 'Primal', getUrl: (id: string) => `https://primal.net/e/${id}` }, nostrudel: { name: 'Nostrudel', getUrl: (id: string) => `https://nostrudel.ninja/l/${id}` }, nostter: { name: 'Nostter', getUrl: (id: string) => `https://nostter.app/${id}` }, coracle: { name: 'Coracle', getUrl: (id: string) => `https://coracle.social/${id}` }, iris: { name: 'Iris', getUrl: (id: string) => `https://iris.to/${id}` }, lumilumi: { name: 'Lumilumi', getUrl: (id: string) => `https://lumilumi.app/${id}` }, zapStream: { name: 'zap.stream', getUrl: (id: string) => `https://zap.stream/${id}` }, yakihonne: { name: 'YakiHonne', getUrl: (id: string) => `https://yakihonne.com/${id}` }, habla: { name: 'Habla', getUrl: (id: string) => `https://habla.news/a/${id}` }, pareto: { name: 'Pareto', getUrl: (id: string) => `https://pareto.space/a/${id}` }, njump: { name: 'Njump', getUrl: (id: string) => `https://njump.me/${id}` } } export default function ClientSelect({ event, originalNoteId, ...props }: ButtonProps & { event?: Event originalNoteId?: string }) { const { isSmallScreen } = useScreenSize() const [open, setOpen] = useState(false) const { t } = useTranslation() const supportedClients = useMemo(() => { let kind: number | undefined if (event) { kind = event.kind } else if (originalNoteId) { try { const pointer = nip19.decode(originalNoteId) if (pointer.type === 'naddr') { kind = pointer.data.kind } } catch (error) { console.error('Failed to decode NIP-19 pointer:', error) return ['njump'] } } if (!kind) { return ['njump'] } switch (kind) { case kinds.LongFormArticle: case kinds.DraftLong: return ['yakihonne', 'coracle', 'habla', 'lumilumi', 'pareto', 'njump'] case kinds.LiveEvent: return ['zapStream', 'nostrudel', 'njump'] case kinds.Date: case kinds.Time: return ['coracle', 'njump'] case kinds.CommunityDefinition: return ['coracle', 'snort', 'njump'] default: return ['njump'] } }, [event]) if (!originalNoteId && !event) { return null } const content = (
{event?.kind === ExtendedKind.GROUP_METADATA ? ( ) : ( supportedClients.map((clientId) => { const client = clients[clientId] if (!client) return null return ( setOpen(false)} href={client.getUrl(originalNoteId ?? getSharableEventId(event!))} name={client.name} /> ) }) )}
) if (isSmallScreen) { return (
e.stopPropagation()}> { e.stopPropagation() setOpen(false) }} /> {content}
) } return (
e.stopPropagation()}> e.preventDefault()}> {content}
) } function RelayBasedGroupChatSelector({ event, originalNoteId, setOpen }: { event: Event setOpen: Dispatch> originalNoteId?: string }) { const { relay, id } = useMemo(() => { let relay: string | undefined if (originalNoteId) { const pointer = nip19.decode(originalNoteId) if (pointer.type === 'naddr' && pointer.data.relays?.length) { relay = pointer.data.relays[0] } } if (!relay) { relay = clientService.getEventHint(event.id) } return { relay, id: getReplaceableEventIdentifier(event) } }, [event, originalNoteId]) return ( setOpen(false)} href={toChachiChat(relay, id)} name="Chachi Chat" /> ) } function ClientSelectItem({ onClick, href, name }: { onClick: () => void href: string name: string }) { return ( ) }