drop the built-in Transcribe entry from the file browser context menu
Transcribe Audio covers it as a task, with recursion, multi-select scoping, skip-if-already-done and a choice of inline or job — none of which the one-shot menu entry had. Two ways to do the same thing from the same menu is worse than one good one. The file viewer's Transcribe button is untouched, and /file-browser/transcribe stays: it is what both that button and the task call. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
06aac5478f
commit
1263a4f851
@@ -62,7 +62,6 @@ export const FileGrid = ({ fileBrowserManager }: FileGridProps) => {
|
|||||||
setRenamingName,
|
setRenamingName,
|
||||||
handleReadAloud,
|
handleReadAloud,
|
||||||
handleOcr,
|
handleOcr,
|
||||||
handleTranscribe,
|
|
||||||
handleExtractAudio,
|
handleExtractAudio,
|
||||||
handleExtract,
|
handleExtract,
|
||||||
handlePlay,
|
handlePlay,
|
||||||
@@ -181,7 +180,6 @@ export const FileGrid = ({ fileBrowserManager }: FileGridProps) => {
|
|||||||
onRenamingChange={setRenamingName}
|
onRenamingChange={setRenamingName}
|
||||||
onReadAloud={handleReadAloud}
|
onReadAloud={handleReadAloud}
|
||||||
onOcr={handleOcr}
|
onOcr={handleOcr}
|
||||||
onTranscribe={handleTranscribe}
|
|
||||||
onExtractAudio={handleExtractAudio}
|
onExtractAudio={handleExtractAudio}
|
||||||
onExtract={handleExtract}
|
onExtract={handleExtract}
|
||||||
onPlay={handlePlay}
|
onPlay={handlePlay}
|
||||||
|
|||||||
+2
-25
@@ -13,7 +13,6 @@ import {
|
|||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
Volume2,
|
Volume2,
|
||||||
ScanText,
|
ScanText,
|
||||||
FileText,
|
|
||||||
AudioLines,
|
AudioLines,
|
||||||
FolderArchive,
|
FolderArchive,
|
||||||
ClipboardCopy,
|
ClipboardCopy,
|
||||||
@@ -65,7 +64,6 @@ export type FileItemProps = {
|
|||||||
onRenamingChange: (name: string | null) => void;
|
onRenamingChange: (name: string | null) => void;
|
||||||
onReadAloud: (entry: DirEntry) => void;
|
onReadAloud: (entry: DirEntry) => void;
|
||||||
onOcr: (entry: DirEntry) => void;
|
onOcr: (entry: DirEntry) => void;
|
||||||
onTranscribe: (entry: DirEntry) => void;
|
|
||||||
onExtractAudio: (entry: DirEntry) => void;
|
onExtractAudio: (entry: DirEntry) => void;
|
||||||
onExtract: (entry: DirEntry) => void;
|
onExtract: (entry: DirEntry) => void;
|
||||||
onPlay: (entry: DirEntry) => void;
|
onPlay: (entry: DirEntry) => void;
|
||||||
@@ -98,7 +96,6 @@ type MenuItemsProps = {
|
|||||||
onDownload: (e: DirEntry) => void;
|
onDownload: (e: DirEntry) => void;
|
||||||
onReadAloud: (e: DirEntry) => void;
|
onReadAloud: (e: DirEntry) => void;
|
||||||
onOcr: (e: DirEntry) => void;
|
onOcr: (e: DirEntry) => void;
|
||||||
onTranscribe: (e: DirEntry) => void;
|
|
||||||
onExtractAudio: (e: DirEntry) => void;
|
onExtractAudio: (e: DirEntry) => void;
|
||||||
onExtract: (e: DirEntry) => void;
|
onExtract: (e: DirEntry) => void;
|
||||||
onPlay: (e: DirEntry) => void;
|
onPlay: (e: DirEntry) => void;
|
||||||
@@ -119,7 +116,6 @@ const DropdownMenuItems = ({
|
|||||||
onDownload,
|
onDownload,
|
||||||
onReadAloud,
|
onReadAloud,
|
||||||
onOcr,
|
onOcr,
|
||||||
onTranscribe,
|
|
||||||
onExtractAudio,
|
onExtractAudio,
|
||||||
onExtract,
|
onExtract,
|
||||||
onPlay,
|
onPlay,
|
||||||
@@ -132,14 +128,12 @@ const DropdownMenuItems = ({
|
|||||||
const fileType = entry.type === 'file' ? getFileType(entry.name) : null;
|
const fileType = entry.type === 'file' ? getFileType(entry.name) : null;
|
||||||
const showReadAloud = fileType === 'markdown' || fileType === 'code' || fileType === 'text';
|
const showReadAloud = fileType === 'markdown' || fileType === 'code' || fileType === 'text';
|
||||||
const showOcr = fileType === 'image';
|
const showOcr = fileType === 'image';
|
||||||
const showTranscribe = fileType === 'audio';
|
|
||||||
const showExtractAudio = fileType === 'video';
|
const showExtractAudio = fileType === 'video';
|
||||||
const showExtract = fileType === 'archive';
|
const showExtract = fileType === 'archive';
|
||||||
const showPlay = fileType === 'audio' || entry.type === 'directory';
|
const showPlay = fileType === 'audio' || entry.type === 'directory';
|
||||||
|
|
||||||
const hasTasks = taskGroups.length > 0;
|
const hasTasks = taskGroups.length > 0;
|
||||||
const hasActions =
|
const hasActions = showPlay || showReadAloud || showOcr || showExtractAudio || showExtract || hasTasks;
|
||||||
showPlay || showReadAloud || showOcr || showTranscribe || showExtractAudio || showExtract || hasTasks;
|
|
||||||
// Only nest when more than one category matched — a file usually matches a single category, and
|
// Only nest when more than one category matched — a file usually matches a single category, and
|
||||||
// Run Task > Video > Convert would just add a hop.
|
// Run Task > Video > Convert would just add a hop.
|
||||||
const nestTasks = taskGroups.length > 1;
|
const nestTasks = taskGroups.length > 1;
|
||||||
@@ -165,12 +159,6 @@ const DropdownMenuItems = ({
|
|||||||
Extract Text (OCR)
|
Extract Text (OCR)
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
{showTranscribe && (
|
|
||||||
<DropdownMenuItem onClick={() => onTranscribe(entry)} className="cursor-pointer">
|
|
||||||
<FileText className="mr-2 h-4 w-4" />
|
|
||||||
Transcribe
|
|
||||||
</DropdownMenuItem>
|
|
||||||
)}
|
|
||||||
{showExtractAudio && (
|
{showExtractAudio && (
|
||||||
<DropdownMenuItem onClick={() => onExtractAudio(entry)} className="cursor-pointer">
|
<DropdownMenuItem onClick={() => onExtractAudio(entry)} className="cursor-pointer">
|
||||||
<AudioLines className="mr-2 h-4 w-4" />
|
<AudioLines className="mr-2 h-4 w-4" />
|
||||||
@@ -272,7 +260,6 @@ const ContextMenuItems = ({
|
|||||||
onDownload,
|
onDownload,
|
||||||
onReadAloud,
|
onReadAloud,
|
||||||
onOcr,
|
onOcr,
|
||||||
onTranscribe,
|
|
||||||
onExtractAudio,
|
onExtractAudio,
|
||||||
onExtract,
|
onExtract,
|
||||||
onPlay,
|
onPlay,
|
||||||
@@ -285,14 +272,12 @@ const ContextMenuItems = ({
|
|||||||
const fileType = entry.type === 'file' ? getFileType(entry.name) : null;
|
const fileType = entry.type === 'file' ? getFileType(entry.name) : null;
|
||||||
const showReadAloud = fileType === 'markdown' || fileType === 'code' || fileType === 'text';
|
const showReadAloud = fileType === 'markdown' || fileType === 'code' || fileType === 'text';
|
||||||
const showOcr = fileType === 'image';
|
const showOcr = fileType === 'image';
|
||||||
const showTranscribe = fileType === 'audio';
|
|
||||||
const showExtractAudio = fileType === 'video';
|
const showExtractAudio = fileType === 'video';
|
||||||
const showExtract = fileType === 'archive';
|
const showExtract = fileType === 'archive';
|
||||||
const showPlay = fileType === 'audio' || entry.type === 'directory';
|
const showPlay = fileType === 'audio' || entry.type === 'directory';
|
||||||
|
|
||||||
const hasTasks = taskGroups.length > 0;
|
const hasTasks = taskGroups.length > 0;
|
||||||
const hasActions =
|
const hasActions = showPlay || showReadAloud || showOcr || showExtractAudio || showExtract || hasTasks;
|
||||||
showPlay || showReadAloud || showOcr || showTranscribe || showExtractAudio || showExtract || hasTasks;
|
|
||||||
// Only nest when more than one category matched — a file usually matches a single category, and
|
// Only nest when more than one category matched — a file usually matches a single category, and
|
||||||
// Run Task > Video > Convert would just add a hop.
|
// Run Task > Video > Convert would just add a hop.
|
||||||
const nestTasks = taskGroups.length > 1;
|
const nestTasks = taskGroups.length > 1;
|
||||||
@@ -318,12 +303,6 @@ const ContextMenuItems = ({
|
|||||||
Extract Text (OCR)
|
Extract Text (OCR)
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
)}
|
)}
|
||||||
{showTranscribe && (
|
|
||||||
<ContextMenuItem onClick={() => onTranscribe(entry)} className="cursor-pointer">
|
|
||||||
<FileText className="mr-2 h-4 w-4" />
|
|
||||||
Transcribe
|
|
||||||
</ContextMenuItem>
|
|
||||||
)}
|
|
||||||
{showExtractAudio && (
|
{showExtractAudio && (
|
||||||
<ContextMenuItem onClick={() => onExtractAudio(entry)} className="cursor-pointer">
|
<ContextMenuItem onClick={() => onExtractAudio(entry)} className="cursor-pointer">
|
||||||
<AudioLines className="mr-2 h-4 w-4" />
|
<AudioLines className="mr-2 h-4 w-4" />
|
||||||
@@ -534,7 +513,6 @@ export const FileItem = ({
|
|||||||
onRenamingChange,
|
onRenamingChange,
|
||||||
onReadAloud,
|
onReadAloud,
|
||||||
onOcr,
|
onOcr,
|
||||||
onTranscribe,
|
|
||||||
onExtractAudio,
|
onExtractAudio,
|
||||||
onExtract,
|
onExtract,
|
||||||
onPlay,
|
onPlay,
|
||||||
@@ -617,7 +595,6 @@ export const FileItem = ({
|
|||||||
onDownload,
|
onDownload,
|
||||||
onReadAloud,
|
onReadAloud,
|
||||||
onOcr,
|
onOcr,
|
||||||
onTranscribe,
|
|
||||||
onExtractAudio,
|
onExtractAudio,
|
||||||
onExtract,
|
onExtract,
|
||||||
onPlay,
|
onPlay,
|
||||||
|
|||||||
@@ -457,19 +457,6 @@ export const useFileBrowserApp = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTranscribe = async (entry: DirEntry) => {
|
|
||||||
const filePath = entryPath(entry.name);
|
|
||||||
const toastId = toast.loading('Transcribing audio...');
|
|
||||||
try {
|
|
||||||
const { transcriptionPath } = await files.transcribe(filePath, { saveNextTo: true });
|
|
||||||
toast.dismiss(toastId);
|
|
||||||
refresh();
|
|
||||||
setSearchParams({ view: filePath, ephemeral: transcriptionPath });
|
|
||||||
} catch {
|
|
||||||
toast.error('Failed to transcribe audio', { id: toastId });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleExtractAudio = async (entry: DirEntry) => {
|
const handleExtractAudio = async (entry: DirEntry) => {
|
||||||
const filePath = entryPath(entry.name);
|
const filePath = entryPath(entry.name);
|
||||||
const toastId = toast.loading('Extracting audio from video...');
|
const toastId = toast.loading('Extracting audio from video...');
|
||||||
@@ -778,7 +765,6 @@ export const useFileBrowserApp = (
|
|||||||
handleCreateDashboardHere,
|
handleCreateDashboardHere,
|
||||||
handleReadAloud,
|
handleReadAloud,
|
||||||
handleOcr,
|
handleOcr,
|
||||||
handleTranscribe,
|
|
||||||
handleExtractAudio,
|
handleExtractAudio,
|
||||||
handleExtract,
|
handleExtract,
|
||||||
handlePlay,
|
handlePlay,
|
||||||
|
|||||||
Reference in New Issue
Block a user