diff --git a/src/assets/icons/icon-setting.svg b/src/assets/icons/icon-setting.svg
new file mode 100644
index 00000000..7899ee02
--- /dev/null
+++ b/src/assets/icons/icon-setting.svg
@@ -0,0 +1,7 @@
+
diff --git a/src/components/slide/script/ScriptBoxContent.tsx b/src/components/slide/script/ScriptBoxContent.tsx
index cbd9bb64..9577e94d 100644
--- a/src/components/slide/script/ScriptBoxContent.tsx
+++ b/src/components/slide/script/ScriptBoxContent.tsx
@@ -6,12 +6,25 @@
* Zustand store를 통해 대본을 읽고 업데이트하며,
* debounce로 자동저장됩니다.
*/
-import { useAutoSaveScript, useSlideActions, useSlideScript } from '@/hooks';
+import { useMemo, useState } from 'react';
+
+import IconSetting from '@/assets/icons/icon-setting.svg?react';
+import { useAutoSaveScript, useScriptReadingSpeed, useSlideActions, useSlideScript } from '@/hooks';
+import { estimateScriptDurationSeconds, formatScriptDuration } from '@/utils/scriptDuration';
+
+import ScriptReadingSpeedModal from './ScriptReadingSpeedModal';
export default function ScriptBoxContent() {
+ const [isSpeedModalOpen, setIsSpeedModalOpen] = useState(false);
const script = useSlideScript();
const { updateScript } = useSlideActions();
const { autoSave, flushSave } = useAutoSaveScript();
+ const { selectedSpeed } = useScriptReadingSpeed();
+
+ const estimatedDuration = useMemo(() => {
+ const durationSeconds = estimateScriptDurationSeconds(script, selectedSpeed);
+ return formatScriptDuration(durationSeconds);
+ }, [script, selectedSpeed]);
const handleChange = (value: string) => {
updateScript(value);
@@ -19,15 +32,35 @@ export default function ScriptBoxContent() {
};
return (
-
+ >
);
}
diff --git a/src/components/slide/script/ScriptBulkEditModal.tsx b/src/components/slide/script/ScriptBulkEditModal.tsx
index 43c475ec..5516df64 100644
--- a/src/components/slide/script/ScriptBulkEditModal.tsx
+++ b/src/components/slide/script/ScriptBulkEditModal.tsx
@@ -1,8 +1,11 @@
+import { useMemo } from 'react';
import type { ChangeEvent, RefObject } from 'react';
import UploadIcon from '@/assets/icons/icon-upload.svg?react';
import { Modal, SlideImage } from '@/components/common';
import type { ScriptBulkEditPreviewItem } from '@/hooks/useScriptBulkEdit';
+import { useScriptReadingSpeed } from '@/hooks/useScriptReadingSpeed';
+import { estimateScriptsDurationSeconds, formatScriptDuration } from '@/utils/scriptDuration';
interface ScriptBulkEditModalProps {
isOpen: boolean;
@@ -31,6 +34,15 @@ function ScriptBulkEditModal({
onFileChange,
onScriptChange,
}: ScriptBulkEditModalProps) {
+ const { selectedSpeed } = useScriptReadingSpeed();
+ const totalDuration = useMemo(() => {
+ const durationSeconds = estimateScriptsDurationSeconds(
+ previewItems.map((item) => item.script),
+ selectedSpeed,
+ );
+ return formatScriptDuration(durationSeconds);
+ }, [previewItems, selectedSpeed]);
+
return (
{selectedFileName}
) : null}
+
+ 전체 예상 읽기 시간:{' '}
+ {totalDuration}{' '}
+ (분당 {selectedSpeed}자 기준)
+