'use client' import { useEffect, useRef, useState } from 'react' import './latest-activity.css' import { lockBodyScroll } from '../../lib/scrollLock' type Event = { id: string; service: string; state: string; message: string; started_at?: string; finished_at?: string } type Operation = { id: string; label: string; status: string; events: Event[] } export default function LatestActivity({ operation, besideDownload, onDismiss }: { operation: Operation; besideDownload: boolean; onDismiss: () => void }) { const dialog = useRef(null) const trigger = useRef(null) const [open, setOpen] = useState(true) useEffect(() => { setOpen(true) }, [operation.id]) // Events are appended in order. Client result events have no timestamp. const latest = operation.events.at(-1) const working = operation.status === 'running' || operation.status === 'searching' const message = latest?.message ?? '' const choosing = /[1-9]\d* releases? (found|shown)/i.test(message) const sent = operation.status === 'complete' && /sent|accepted.*release/i.test(message) && /download|release|Sonarr|Radarr/i.test(message) const interrupted = latest?.id === 'connection-error' const status = working ? 'Working on it' : choosing ? 'Choose a download' : operation.status === 'complete' ? 'Done' : 'Needs your attention' const currentStep = working ? /send release/i.test(operation.label) ? 'Sending your download...' : /search/i.test(operation.label) ? 'Looking for a download...' : latest?.service === 'Jellyfin' ? 'Checking if it is ready to watch...' : latest?.service === 'qBittorrent' ? 'Checking your download...' : 'Checking your request...' : interrupted ? 'The connection was lost.' : choosing ? 'The search is finished. Choose a version to download.' : sent ? 'Your download has been sent.' : operation.status === 'error' ? 'We could not finish this step.' : 'This check is finished.' const nextStep = working ? 'Please wait. You can close this box while we work.' : interrupted ? 'Close this box and check the request before trying again.' : choosing ? 'Close this box to see the available downloads.' : sent ? 'You can close this box. The request will update when the download starts.' : operation.status === 'error' ? 'Close this box to review the request and its available options.' : 'Close this box to see the updated request status.' const progress =
useEffect(() => { if (!open) return const element = dialog.current element?.showModal() const unlock = lockBodyScroll() return () => { element?.close() unlock() trigger.current?.focus() } }, [open]) return (
setOpen(false)} onClose={() => setOpen(false)}>
Request progress

{status}

{working &&

{progress}

{nextStep}

{!working && }
) }