Something went wrong. Try again.
FlockOff is a mass-block tool for the Atmosphere flockoff.app
Something went wrong. Try again.
3.5 kB · 103 lines
TSX
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104import { Button } from '@/components/ui/button'import { LinkButton } from '@/components/LinkButton'import type { ProgressMessage } from '@/types'
interface BlockProgressProps { progress: ProgressMessage eventRkey: string onUndo: () => void onRetry: () => void onShare: () => void undoLoading: boolean retryLoading: boolean shareLoading: boolean sharedListUrl: string | null}
export function BlockProgress({ progress, eventRkey, onUndo, onRetry, onShare, undoLoading, retryLoading, shareLoading, sharedListUrl,}: BlockProgressProps) { const { status, total, completed, failed } = progress const isDone = status === 'complete' || status === 'failed' const processed = completed + failed const percent = total > 0 ? Math.round((processed / total) * 100) : 0
return ( <div className="bg-card border border-border rounded-xl p-4 flex flex-col gap-4" style={{ boxShadow: 'var(--fo-shadow-card)' }} > {/* Progress bar + label */} <div className="flex flex-col gap-2"> <div className="bg-secondary rounded-full h-2 overflow-hidden"> <div className={`h-full rounded-full transition-all duration-300 ${ isDone && status === 'complete' ? 'bg-green-500 dark:bg-green-400' : 'bg-[var(--fo-ember)]' } ${!isDone ? 'fo-progress-stripe' : ''}`} style={{ width: `${percent}%` }} /> </div> <p className="text-xs font-mono text-[var(--fo-text2)]"> {isDone ? ( status === 'complete' ? `Done — ${completed.toLocaleString()} blocked${failed > 0 ? `, ${failed.toLocaleString()} failed` : '.'}` : `Failed — ${completed.toLocaleString()} blocked, ${failed.toLocaleString()} failed.` ) : ( `Blocking ${processed.toLocaleString()} of ${total.toLocaleString()}…` )} </p> </div>
{/* Done state: actions */} {isDone && ( <div className="flex flex-col gap-3"> {sharedListUrl && ( <a href={sharedListUrl} target="_blank" rel="noopener noreferrer" className="text-sm text-[var(--fo-follower)] hover:underline" > View shared block list on Bluesky ↗ </a> )} <div className="flex flex-wrap gap-2"> {failed > 0 && ( <Button variant="outline" size="sm" onClick={onRetry} disabled={retryLoading}> {retryLoading ? 'Retrying…' : `Retry ${failed.toLocaleString()} failed`} </Button> )} {completed > 0 && !sharedListUrl && ( <Button variant="outline" size="sm" onClick={onShare} disabled={shareLoading}> {shareLoading ? 'Creating list…' : 'Share as list'} </Button> )} <Button variant="outline" size="sm" onClick={onUndo} disabled={undoLoading}> {undoLoading ? 'Undoing…' : 'Undo all blocks'} </Button> <LinkButton href="/events" variant="ghost" size="sm"> View history → </LinkButton> </div> </div> )}
{/* In-progress note */} {!isDone && ( <p className="text-xs text-[var(--fo-text3)]"> Blocking at ~1/sec to respect the network's rate limits. You can close this tab — progress is saved to your account. </p> )} </div> )}