Skip to content

Commit

Permalink
Fix transcription create (#1081)
Browse files Browse the repository at this point in the history
* refactor transcription loading model

* abort transcribe when auto download

* refactor
  • Loading branch information
an-lee authored Sep 17, 2024
1 parent 1f40263 commit 3cacee1
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 114 deletions.
193 changes: 104 additions & 89 deletions enjoy/src/renderer/components/medias/media-loading-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,14 @@ import {
TabsList,
TabsTrigger,
} from "@renderer/components/ui";
import { CheckCircleIcon, CircleAlertIcon, LoaderIcon } from "lucide-react";
import { CircleAlertIcon, LoaderIcon } from "lucide-react";
import { t } from "i18next";
import { useNavigate } from "react-router-dom";
import { TranscriptionCreateForm, TranscriptionsList } from "../transcriptions";
import { SttEngineOptionEnum } from "@/types/enums";

export const MediaLoadingModal = () => {
const navigate = useNavigate();
const {
media,
decoded,
decodeError,
transcription,
transcribing,
transcribingProgress,
transcribingOutput,
generateTranscription,
} = useContext(MediaShadowProviderContext);
const { decoded, transcription } = useContext(MediaShadowProviderContext);

return (
<AlertDialog open={!decoded || !Boolean(transcription?.result?.timeline)}>
Expand All @@ -43,84 +33,109 @@ export const MediaLoadingModal = () => {
{t("itMayTakeAWhileToPrepareForTheFirstLoad")}
</AlertDialogDescription>
</AlertDialogHeader>

{decoded ? (
transcription?.result?.timeline ? (
<div className="flex items-center space-x-4">
<CheckCircleIcon className="w-4 h-4 text-green-500" />
<span>{t("transcribedSuccessfully")}</span>
</div>
) : (
<Tabs defaultValue="transcribe">
<TabsList className="w-full grid grid-cols-2 mb-4">
<TabsTrigger value="transcribe">{t("transcribe")}</TabsTrigger>
<TabsTrigger value="download">
{t("downloadTranscript")}
</TabsTrigger>
</TabsList>
<TabsContent value="transcribe">
<TranscriptionCreateForm
originalText={transcription?.result?.originalText}
onSubmit={(data) => {
generateTranscription({
originalText: data.text,
language: data.language,
service: data.service as SttEngineOptionEnum | "upload",
isolate: data.isolate,
});
}}
onCancel={() => navigate(-1)}
transcribing={transcribing}
transcribingProgress={transcribingProgress}
transcribingOutput={transcribingOutput}
/>
</TabsContent>
<TabsContent value="download">
<TranscriptionsList
media={media}
transcription={transcription}
/>
</TabsContent>
</Tabs>
)
) : (
<>
{decodeError ? (
<div className="mb-4 flex items-center space-x-4">
<div className="w-4 h-4">
<CircleAlertIcon className="text-destructive w-4 h-4" />
</div>
<div className="select-text">
<div className="mb-2">{decodeError}</div>
<div className="text-sm text-muted-foreground">
{t("failedToDecodeWaveform")}:{" "}
<span className="break-all ">{media?.src}</span>
</div>
</div>
</div>
) : (
<div className="mb-4 flex items-center space-x-4">
{media?.src ? (
<>
<LoaderIcon className="w-4 h-4 animate-spin" />
<span>{t("decodingWaveform")}</span>
</>
) : (
<>
<CircleAlertIcon className="text-destructive w-4 h-4" />
<span>{t("cannotFindSourceFile")}</span>
</>
)}
</div>
)}
<AlertDialogFooter>
<Button variant="secondary" onClick={() => navigate(-1)}>
{t("cancel")}
</Button>
</AlertDialogFooter>
</>
)}
<LoadingContent />
</AlertDialogContent>
</AlertDialog>
);
};

const LoadingContent = () => {
const navigate = useNavigate();
const {
media,
decoded,
decodeError,
transcription,
transcribing,
transcribingProgress,
transcribingOutput,
generateTranscription,
} = useContext(MediaShadowProviderContext);
if (decoded) {
// Decoded and transcription created but not ready
if (transcription && !transcription.result?.timeline) {
return (
<Tabs defaultValue="transcribe">
<TabsList className="w-full grid grid-cols-2 mb-4">
<TabsTrigger value="transcribe">{t("transcribe")}</TabsTrigger>
<TabsTrigger value="download">
{t("downloadTranscript")}
</TabsTrigger>
</TabsList>
<TabsContent value="transcribe">
<TranscriptionCreateForm
originalText={transcription?.result?.originalText}
onSubmit={(data) => {
generateTranscription({
originalText: data.text,
language: data.language,
service: data.service as SttEngineOptionEnum | "upload",
isolate: data.isolate,
});
}}
onCancel={() => navigate(-1)}
transcribing={transcribing}
transcribingProgress={transcribingProgress}
transcribingOutput={transcribingOutput}
/>
</TabsContent>
<TabsContent value="download">
<TranscriptionsList media={media} transcription={transcription} />
</TabsContent>
</Tabs>
);
} else {
return (
<div className="flex items-center space-x-4">
<LoaderIcon className="w-4 h-4 animate-spin" />
</div>
);
}
// Decode error
} else if (decodeError) {
return (
<>
<div className="mb-4 flex items-center space-x-4">
<div className="w-4 h-4">
<CircleAlertIcon className="text-destructive w-4 h-4" />
</div>
<div className="select-text">
<div className="mb-2">{decodeError}</div>
<div className="text-sm text-muted-foreground">
{t("failedToDecodeWaveform")}:{" "}
<span className="break-all ">{media?.src}</span>
</div>
</div>
</div>
<AlertDialogFooter>
<Button variant="secondary" onClick={() => navigate(-1)}>
{t("cancel")}
</Button>
</AlertDialogFooter>
</>
);
} else {
return (
<>
<div className="mb-4 flex items-center space-x-4">
{media?.src ? (
<>
<LoaderIcon className="w-4 h-4 animate-spin" />
<span>{t("decodingWaveform")}</span>
</>
) : (
<>
<CircleAlertIcon className="text-destructive w-4 h-4" />
<span>{t("cannotFindSourceFile")}</span>
</>
)}
</div>
<AlertDialogFooter>
<Button variant="secondary" onClick={() => navigate(-1)}>
{t("cancel")}
</Button>
</AlertDialogFooter>
</>
);
}
};
56 changes: 31 additions & 25 deletions enjoy/src/renderer/hooks/use-transcriptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const useTranscriptions = (media: AudioType | VideoType) => {
const { transcribe, output } = useTranscribe();
const [transcribingProgress, setTranscribingProgress] = useState<number>(0);
const [transcribing, setTranscribing] = useState<boolean>(false);
const [creating, setCreating] = useState<boolean>(false);
const [transcribingOutput, setTranscribingOutput] = useState<string>("");
const [service, setService] = useState<SttEngineOptionEnum | "upload">(
sttEngine
Expand All @@ -42,40 +43,45 @@ export const useTranscriptions = (media: AudioType | VideoType) => {
async (): Promise<TranscriptionType | void> => {
if (!media) return;
if (transcription?.targetId === media.id) return;
if (creating) return;

const tr = await EnjoyApp.transcriptions.findOrCreate({
targetId: media.id,
targetType: media.mediaType,
});
try {
setCreating(true);
const tr = await EnjoyApp.transcriptions.findOrCreate({
targetId: media.id,
targetType: media.mediaType,
});

if (!tr?.result?.timeline) {
tr.result = {
originalText: tr.result?.originalText,
};
}
if (!tr?.result?.timeline) {
tr.result = {
originalText: tr.result?.originalText,
};
}

const transcriptionOnline = await findTranscriptionOnline();
if (transcriptionOnline && !tr?.result?.timeline) {
return EnjoyApp.transcriptions
.update(tr.id, {
const transcriptionOnline = await findTranscriptionOnline();
if (transcriptionOnline && !tr?.result?.timeline) {
await EnjoyApp.transcriptions.update(tr.id, {
state: "finished",
result: transcriptionOnline.result,
engine: transcriptionOnline.engine,
model: transcriptionOnline.model,
language: transcriptionOnline.language || media.language,
})
.then(() => {
toast.success(t("downloadedTranscriptionFromCloud"));
setTranscription(transcriptionOnline);
return transcriptionOnline;
})
.catch((err) => {
console.error(err);
return tr;
});
} else {
setTranscription(tr);
return tr;
setTranscription(transcriptionOnline);
toast.success(t("downloadedTranscriptionFromCloud"));
if (transcribing) {
abortGenerateTranscription();
}
return transcriptionOnline;
} else {
setTranscription(tr);
return tr;
}
} catch (err) {
console.error(err);
return null;
} finally {
setCreating(false);
}
};

Expand Down

0 comments on commit 3cacee1

Please sign in to comment.