From 8ac58495f6c36cc5b9623d66c992cc2013a590e8 Mon Sep 17 00:00:00 2001 From: graphemecluster Date: Sat, 31 Aug 2024 17:20:10 +0800 Subject: [PATCH] Screenshot Mode --- index.html | 6 +++--- src/App.tsx | 40 +++++++++++++++++++++++++++------------- src/AudioPlayer.tsx | 13 ++++++++----- src/SentenceCard.tsx | 8 +++++--- src/SettingsDialog.tsx | 4 ++-- src/hooks.ts | 12 +++++++++--- src/index.css | 3 +++ src/types.ts | 2 ++ tailwind.config.ts | 2 +- 9 files changed, 60 insertions(+), 30 deletions(-) diff --git a/index.html b/index.html index ff09bca..87bc77b 100644 --- a/index.html +++ b/index.html @@ -58,8 +58,8 @@

香港圍頭話及客家話文字轉語音

香港本土語言保育協會

-
@@ -70,7 +70,7 @@

-

關於

+

關於


歡迎使用香港圍頭話及客家話文字轉語音(Text-to-Speech)朗讀器!

diff --git a/src/App.tsx b/src/App.tsx index 234e97f..e8a0fc2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,8 +15,17 @@ import type { SettingsDialogPage, Sentence } from "./types"; export default function App() { const queryOptions = useQueryOptions(); - const { language, voice, inferenceMode, voiceSpeed, hakkaToneMode, setLanguage, setVoice } = queryOptions; - const [sentences, setSentences] = useState([]); + const { language, voice, inferenceMode, voiceSpeed, hakkaToneMode, setLanguage, setVoice, screenshotMode } = queryOptions; + const [sentences, setSentences] = useState( + screenshotMode + ? () => [ + { language: "waitau", voice: "male", inferenceMode: "online", voiceSpeed: 1, syllables: segment("天地玄黃,宇宙洪荒。") }, + { language: "waitau", voice: "female", inferenceMode: "online", voiceSpeed: 1, syllables: segment("日月盈昃,辰宿列張。") }, + { language: "hakka", voice: "male", inferenceMode: "online", voiceSpeed: 1, syllables: segment("天地玄黃,宇宙洪荒。") }, + { language: "hakka", voice: "female", inferenceMode: "online", voiceSpeed: 1, syllables: segment("日月盈昃,辰宿列張。") }, + ] + : [], + ); const textArea = useRef(null); const btnAddSentence = useRef(null); @@ -83,12 +92,12 @@ export default function App() {
聲線
- - + +
-
- {sentences.map((sentence, i) => ( - + {sentences.flatMap((sentence, i) => ( + !screenshotMode || sentence.language === language + ? [ + , + ] + : [] ))}
diff --git a/src/AudioPlayer.tsx b/src/AudioPlayer.tsx index 612900f..bfe1522 100644 --- a/src/AudioPlayer.tsx +++ b/src/AudioPlayer.tsx @@ -34,7 +34,10 @@ export default function AudioPlayer({ setDownloadState, currSettingsDialogPage, setCurrSettingsDialogPage, + screenshotMode, }: SentenceComponentState) { + const overrideSeekBar = screenshotMode && syllables[0][0] === "t"; + useEffect(() => void context.resume(), []); const [buffer, setBuffer] = useState(); const [sourceNode, setSourceNode] = useState(); @@ -84,7 +87,7 @@ export default function AudioPlayer({ useEffect(() => { async function getDownloadComponents() { - if (inferenceMode === "online" || !db || downloadVersion || currSettingsDialogPage) return; + if (screenshotMode || inferenceMode === "online" || !db || downloadVersion || currSettingsDialogPage) return; setDownloadVersion(undefined); setDownloadError(undefined); setBuffer(undefined); @@ -107,7 +110,7 @@ export default function AudioPlayer({ const [generationRetryCounter, generationRetry] = useReducer((n: number) => n + 1, 0); const text = syllables.join(" "); useEffect(() => { - if (inferenceMode !== "online" && !downloadVersion) return; + if (screenshotMode || inferenceMode !== "online" && !downloadVersion) return; async function generateAudio() { const key = `${inferenceMode}/${voiceSpeed}/${downloadVersion}/${language}/${voice}`; let textToBuffer = audioCache.get(key); @@ -225,14 +228,14 @@ export default function AudioPlayer({ onClick={isPlaying === false ? playAudio : pauseAudio} aria-label={isPlaying === false ? "播放" : "暫停"} tabIndex={buffer ? 0 : -1}> - {isPlaying === false ? : } + {!overrideSeekBar && isPlaying === false ? : } - {(error || !buffer) &&
+ {!screenshotMode && (error || !buffer) &&
{error ?
diff --git a/src/SentenceCard.tsx b/src/SentenceCard.tsx index 01f4290..74f2436 100644 --- a/src/SentenceCard.tsx +++ b/src/SentenceCard.tsx @@ -140,6 +140,7 @@ export default function SentenceCard({ setDownloadState, currSettingsDialogPage, setCurrSettingsDialogPage, + screenshotMode, }: SentenceCardProps) { const [enabledEdges, setEnabledEdges] = useState(new Set()); const edges = useMemo(() => { @@ -235,8 +236,8 @@ export default function SentenceCard({
{TERMINOLOGY[language]} {TERMINOLOGY[voice]} - {INFERENCE_MODE_TO_LABEL[inferenceMode]} - {voiceSpeed}× + {!screenshotMode && {INFERENCE_MODE_TO_LABEL[inferenceMode]}} + {!screenshotMode && {voiceSpeed}×}
{tables}
@@ -244,7 +245,8 @@ export default function SentenceCard({ sentence={{ language, voice, inferenceMode, voiceSpeed, syllables: inferenceMode === "lightweight" ? enabledEdgesProns : flattenedProns }} setDownloadState={setDownloadState} currSettingsDialogPage={currSettingsDialogPage} - setCurrSettingsDialogPage={setCurrSettingsDialogPage} /> + setCurrSettingsDialogPage={setCurrSettingsDialogPage} + screenshotMode={screenshotMode} />
; } diff --git a/src/SettingsDialog.tsx b/src/SettingsDialog.tsx index 17105de..2c041b3 100644 --- a/src/SettingsDialog.tsx +++ b/src/SettingsDialog.tsx @@ -50,10 +50,10 @@ const SettingsDialog = forwardRef(functio - {currSettingsDialogPage &&

+ {currSettingsDialogPage &&

{currSettingsDialogPage === "settings" ? <> - 設定 + 設定 : <>