teqo-backup/src/lib/copyFeedback.ts
Francisco Solla 352801853f feat(C167): corta o trecho [início,fim] do acervo e publica o arquivo numa página compartilhável
Seleção do C166 ganha "Cortar vídeo": título/descrição por IA (editáveis, com fallback determinístico), job assíncrono com ffmpeg por re-encode exato e polling dos quatro passos, e página pública unlisted /corte/<id> (noindex, OG, crédito CC BY) servindo o mesmo MP4. Collection speechCut com access canReadSpeechCut (advisor/leader negados) e kill switch por status; ffmpeg entra só no runner da imagem com FFMPEG_PATH para teste.
2026-09-15 10:24:36 -03:00

46 lines
1.2 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
const COPY_FEEDBACK_RESET_MS = 2000
export type CopyFeedback = 'idle' | 'copied' | 'error'
export const copyFeedbackLabels: Record<CopyFeedback, string> = {
idle: 'Copiar link',
copied: 'Link copiado',
error: 'Não foi possível copiar',
}
export const copyFeedbackLiveMessages: Record<CopyFeedback, string> = {
idle: '',
copied: 'Link copiado.',
error: 'Não foi possível copiar o link.',
}
/**
* The one copy-to-clipboard feedback contract of the share controls (C166 share
* sheet, C167 cut share kit): the label per state, the screen-reader live
* message and the auto-reset. `copy` never throws — a denied clipboard is the
* `error` state.
*/
export const useCopyFeedback = () => {
const [feedback, setFeedback] = useState<CopyFeedback>('idle')
useEffect(() => {
if (feedback === 'idle') return
const reset = setTimeout(() => setFeedback('idle'), COPY_FEEDBACK_RESET_MS)
return () => clearTimeout(reset)
}, [feedback])
const copy = async (text: string): Promise<void> => {
try {
await navigator.clipboard.writeText(text)
setFeedback('copied')
} catch {
setFeedback('error')
}
}
return { feedback, copy }
}