diff --git a/enjoy/src/i18n/en.json b/enjoy/src/i18n/en.json index 698b3a15..cb7fe01d 100644 --- a/enjoy/src/i18n/en.json +++ b/enjoy/src/i18n/en.json @@ -936,5 +936,7 @@ "exit": "Exit", "layout": "Layout", "horizontal": "Horizontal", - "vertical": "Vertical" + "vertical": "Vertical", + "copied": "Copied", + "copyFullText": "Copy full text" } diff --git a/enjoy/src/i18n/zh-CN.json b/enjoy/src/i18n/zh-CN.json index 954f0f32..85d28b1e 100644 --- a/enjoy/src/i18n/zh-CN.json +++ b/enjoy/src/i18n/zh-CN.json @@ -936,5 +936,7 @@ "exit": "退出", "layout": "布局", "horizontal": "水平", - "vertical": "垂直" + "vertical": "垂直", + "copied": "已复制", + "copyFullText": "复制全文" } diff --git a/enjoy/src/renderer/components/medias/media-left-panel/media-recordings.tsx b/enjoy/src/renderer/components/medias/media-left-panel/media-recordings.tsx index 7f7a9762..8753173a 100644 --- a/enjoy/src/renderer/components/medias/media-left-panel/media-recordings.tsx +++ b/enjoy/src/renderer/components/medias/media-left-panel/media-recordings.tsx @@ -149,7 +149,7 @@ export const MediaRecordings = () => { #{currentSegmentIndex + 1}/{transcription?.result?.timeline?.length} - + diff --git a/enjoy/src/renderer/components/medias/media-left-panel/media-transcription-print.tsx b/enjoy/src/renderer/components/medias/media-left-panel/media-transcription-print.tsx index ffe7f1d9..7e03b70f 100644 --- a/enjoy/src/renderer/components/medias/media-left-panel/media-transcription-print.tsx +++ b/enjoy/src/renderer/components/medias/media-left-panel/media-transcription-print.tsx @@ -1,4 +1,4 @@ -import { useContext } from "react"; +import { forwardRef, useContext } from "react"; import { Button, toast } from "@renderer/components/ui"; import { t } from "i18next"; import { @@ -9,7 +9,10 @@ import { AlignmentResult } from "echogarden/dist/api/API.d.js"; import { convertWordIpaToNormal } from "@/utils"; import template from "./transcription.template.html?raw"; -export const MediaTranscriptionPrint = () => { +export const MediaTranscriptionPrint = forwardRef< + HTMLButtonElement, + React.ComponentProps +>((_, ref) => { const { media, transcription } = useContext(MediaShadowProviderContext); const { EnjoyApp, learningLanguage, ipaMappings } = useContext( AppSettingsProviderContext @@ -74,8 +77,15 @@ export const MediaTranscriptionPrint = () => { } return ( - ); -}; +}); + +MediaTranscriptionPrint.displayName = "MediaTranscriptionPrint"; diff --git a/enjoy/src/renderer/components/medias/media-left-panel/media-transcription.tsx b/enjoy/src/renderer/components/medias/media-left-panel/media-transcription.tsx index 3ca71713..5c8e1114 100644 --- a/enjoy/src/renderer/components/medias/media-left-panel/media-transcription.tsx +++ b/enjoy/src/renderer/components/medias/media-left-panel/media-transcription.tsx @@ -12,6 +12,7 @@ import { DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, + toast, } from "@renderer/components/ui"; import { LoaderIcon, @@ -30,6 +31,7 @@ import { TranscriptionEditButton, } from "@renderer/components"; import { Sentence } from "@renderer/components"; +import { useCopyToClipboard } from "@uidotdev/usehooks"; export const MediaTranscription = (props: { display?: boolean }) => { const { display } = props; @@ -58,6 +60,7 @@ export const MediaTranscription = (props: { display?: boolean }) => { segment: SegmentType; }[] >([]); + const [_, copyToClipboard] = useCopyToClipboard(); const fetchSegmentStats = async () => { if (!media) return; @@ -88,6 +91,15 @@ export const MediaTranscription = (props: { display?: boolean }) => { }, 300); }; + const handleCopyFullText = () => { + if (!transcription?.result) return; + const fullText = (transcription.result as AlignmentResult).timeline + .map((s) => s.text) + .join("\n\n"); + copyToClipboard(fullText); + toast.success(t("copied")); + }; + useEffect(() => { if (!transcription?.result) return; @@ -168,6 +180,15 @@ export const MediaTranscription = (props: { display?: boolean }) => { + + +