import React, { useEffect } from 'react'; import { createPortal } from 'react-dom'; import { Music, X } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import type { SubsonicSong } from '../../api/subsonicTypes'; import type { ServerProfile } from '../../store/authStoreTypes'; import { formatTrackTime } from '../../utils/format/formatDuration'; import type { ShareQueuePreviewState } from '../../hooks/useShareQueuePreview'; import { sharePayloadTotal, type QueueableShareSearchPayload } from '../../utils/share/shareSearch'; import CachedImage from '../CachedImage'; import { buildCoverArtUrl, buildCoverArtUrlForServer, coverArtCacheKey, coverArtCacheKeyForServer, } from '../../api/subsonicStreamUrl'; type ShareQueuePreviewModalProps = { open: boolean; onClose: () => void; payload: Extract; preview: ShareQueuePreviewState; shareServerLabel?: string | null; coverServer?: ServerProfile | null; onEnqueue: () => void; enqueueBusy: boolean; }; function QueuePreviewTrackRow({ song, coverServer, }: { song: SubsonicSong; coverServer?: ServerProfile | null; }) { const coverId = song.coverArt ?? ''; const src = coverServer ? buildCoverArtUrlForServer(coverServer.url, coverServer.username, coverServer.password, coverId || song.id, 48) : buildCoverArtUrl(coverId || song.id, 48); const cacheKey = coverServer ? coverArtCacheKeyForServer(coverServer.id, coverId || song.id, 48) : coverArtCacheKey(coverId || song.id, 48); return (
  • {coverId ? ( ) : (
    )}
    {song.title}
    {song.artist}{song.album ? ` ยท ${song.album}` : ''}
    {formatTrackTime(song.duration)}
  • ); } function PreviewBody({ preview, coverServer, }: { preview: ShareQueuePreviewState; coverServer?: ServerProfile | null; }) { const { t } = useTranslation(); if (preview.status === 'loading' || preview.status === 'idle') { return
    {t('search.shareQueuePreviewLoading')}
    ; } if (preview.status === 'error') { const msg = preview.result.type === 'not-logged-in' ? t('sharePaste.notLoggedIn') : preview.result.type === 'no-matching-server' ? t('sharePaste.noMatchingServer', { url: preview.result.url }) : preview.result.type === 'all-unavailable' ? t('search.shareQueuePreviewEmpty') : t('sharePaste.genericError'); return
    {msg}
    ; } return ( <> {preview.skipped > 0 && (

    {t('search.shareQueuePreviewSkipped', { skipped: preview.skipped, total: preview.total })}

    )} ); } export default function ShareQueuePreviewModal({ open, onClose, payload, preview, shareServerLabel, coverServer, onEnqueue, enqueueBusy, }: ShareQueuePreviewModalProps) { const { t } = useTranslation(); useEffect(() => { if (!open) return; const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', handler); return () => document.removeEventListener('keydown', handler); }, [open, onClose]); if (!open) return null; const count = sharePayloadTotal(payload); const canEnqueue = preview.status === 'ok' && preview.songs.length > 0; return createPortal(
    { if (e.target === e.currentTarget) onClose(); }} >
    e.stopPropagation()} >

    {t('search.shareQueueTitle', { count })}

    {shareServerLabel && (

    {t('search.shareFromServer', { server: shareServerLabel })}

    )}
    , document.body, ); }