vRC~nAwWliB(gIec#_fL>p~X%xuZ0vYfaNPO?pW5z$Vil=XSistMqE-Wy6`8M6{ +y7Hq lO#w{FW0OYz1Dx>;`~z-?S3hhvuiO9t002ovPDHLkV1kS2ab5rb literal 0 HcmV?d00001 diff --git a/src/components/Assistant/ReadAloud/imgs/loading-dark.png b/src/components/Assistant/ReadAloud/imgs/loading-dark.png new file mode 100755 index 0000000000000000000000000000000000000000..c09b85ac29e2acd7044229f451bd1d22872a9c69 GIT binary patch literal 485 zcmV Px$pGibPR9HvdS3OGvK@3f%uolEdMYPy+X7MM8f{m5cf#6>htgLJV#h)NI<6WVM z+K6CnF_FNntjBz0SC;{=-Q?xv>rD=!@DB^ehu#F7b87(bJWpUlYyH|Mncf7fwOfez zz(I*<+ZglszX(`skBI1{uIsx{X3`2wCX-!6TsOvChH!!{;NXaO0RSJ~`@;|k2>}kS zl)3_dWg X-&J Px$rAb6VR9Hvdmpe Ll^m6Q0)I>6daL`y!WrfHse&XS-2pt3C6^w}cf*Yxg~0Te~S!M!7~ z)*c#TZY2O(>jS0KO~95WlZpDVgvkMtk3iDeA#4^phSu6$p9XY<>+g?YSBMbt%%=r| z2vJfgPI?)|E|x*B<5+TDxIrHz$)99gVbVvbL~vpwki-x_NPhDykAaAla6VA-zh<$@ hq~CjYK$;+C_YHP2!Z5#)BcA{O002ovPDHLkV1j}Z*@gfB literal 0 HcmV?d00001 diff --git a/src/components/Assistant/ReadAloud/imgs/pause-dark.png b/src/components/Assistant/ReadAloud/imgs/pause-dark.png new file mode 100755 index 0000000000000000000000000000000000000000..bbaa1adcfb39d499714631f5f5a5518c428067bb GIT binary patch literal 504 zcmV Px$vPnciR9Hvt*F8(aP!tB>^O91e{)P^vP3}#G_IEfrI`|_jRB6$nAShCb4i35q zf{213=;Y$yAc#0v5ZVqBR762U#Lo!!*p>!Fv`v#VUCf%xeV?3j@&)Sifj;NcKcHg; zOw$~Q#bWQhYE@f6wOSov<~3$s42Q$h@p$~vZ%A7}xm?ZwD7HfH08D9`wgRB$7o;12 zoq5X4X pYJWzD5hsTVg8uK+vqx{k>SA=UwK zHxR!7%}fACL^LLZIChHg70?Rh)~%Z}4CAH~q!$1?^O>1vL!r>Ts;bsskX{1pOp}?% zbzR^74G{#u&fS$#4*x_13D}cT4)p_Y2_P$k*bKS_uK)^>NTd*rM&AM*LI4|zqGS_^ z#8uF@;Rz9?rId%Ag6;Eu4dE>jO$s4agMJi$5YYk=%}6PqoL=?!bzUm4qbN#7Rn>Dh z!CqQ$1|Thj*!L3b25?{RZ(h^1WdNUkgg4)y?KY}ZDx*Zy7_24BvhvAf^1-iQM-^x+ uDwRruZohV%U_1U7IN8L@ntwpwEAR!Otg#`~8+yh70000 Px$u1Q2eR9Hvt*S|}{Kor37_p&tLpV7TT`ww(=a&+*Iuu!E%hk~F;5gi $O_#tyf#s5s=MhM-g!Y0G0t@hI8(yhI9nva=9V^EPO}rh-g{}u?7I1Do8f~zj>l* zTEVicLluZ90KaQ^o;PXR_C*{>9DwY~!@1CIx91y;#&Z-%T!7!aCZe(sViN$U8;B}^ z-#kLZamLtjScGbT?8*tqN4Ly5zX^i$0^m2F0AS8>oW)kF_5L5EmjJ(cPDB$zh@HO> zNdUgOM6@S_82ODz41kFHjIrT<04@=+#2DL7dJA5NsG3Tps`YyPHR(gRrD jeI1|_ffFkGoEJ`@e z7MyyXSFmmSAWk?6;GT#o>2!M4FpLisae0rRm(nprlm~0Yb=^v{*?dqH4mAO}D3i$y qMSa@|gAM#&5auRv)(ilBpTH;TAh#iKKw5_Y0000 rC7 z*!zC#wb=&qu1ajKd0%`^>sW=yV;@c5Yf&q&2mcdK&}W&!&3MkKVIl*ELIVR6lnBr* vSbtry#W8C0+~P~S;$r`QdzO7I<^j`Z*$#us-&JBj2QhfM`njxgN@xNA`}|9# literal 0 HcmV?d00001 diff --git a/src/components/Assistant/ReadAloud/imgs/play-light.png b/src/components/Assistant/ReadAloud/imgs/play-light.png new file mode 100755 index 0000000000000000000000000000000000000000..a5378e9f0748219be4728d2fb0d3fac4714150ad GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}b)GJcArbCx zuN!hT81S%OU=xY`VzkrY9e-r?L@riWLDuc^3xlWM-`Miy^QI+}tmI$*sY_zeNJw+m zOl5z3^G+@6_eHDJrP9}yp0ivWm;W=qL78I%3*$P414kG{7BH}CI52VrG%$%QaM*lc tbKL4z9oKTo-CtJ~|Ghpte)Bsf^FOOQ46cdqkN~=b!PC{xWt~$(69E73M|l7M literal 0 HcmV?d00001 diff --git a/src/components/Assistant/ReadAloud/index.tsx b/src/components/Assistant/ReadAloud/index.tsx new file mode 100644 index 00000000..8d2ef94e --- /dev/null +++ b/src/components/Assistant/ReadAloud/index.tsx @@ -0,0 +1,134 @@ +import { useThemeStore } from "@/stores/themeStore"; +import loadingLight from "./imgs/loading-light.png"; +import loadingDark from "./imgs/loading-dark.png"; +import playLight from "./imgs/play-light.png"; +import playDark from "./imgs/play-dark.png"; +import pauseLight from "./imgs/pause-light.png"; +import pauseDark from "./imgs/pause-dark.png"; +import backLight from "./imgs/back-light.png"; +import backDark from "./imgs/back-dark.png"; +import forwardLight from "./imgs/forward-light.png"; +import forwardDark from "./imgs/forward-dark.png"; +import closeLight from "./imgs/close-light.png"; +import closeDark from "./imgs/close-dark.png"; +import { useEffect, useMemo, useRef } from "react"; +import { useReactive } from "ahooks"; +import dayjs from "dayjs"; +import durationPlugin from "dayjs/plugin/duration"; + +dayjs.extend(durationPlugin); + +interface State { + loading: boolean; + playing: boolean; + totalDuration: number; + currentDuration: number; +} + +const ReadAloud = () => { + const isDark = useThemeStore((state) => state.isDark); + const state = useReactive ({ + loading: false, + playing: true, + totalDuration: 300, + currentDuration: 0, + }); + const timerRef = useRef >(); + + const formatTime = useMemo(() => { + return dayjs.duration(state.currentDuration * 1000).format("mm:ss"); + }, [state.currentDuration]); + + useEffect(() => { + if (state.playing && state.currentDuration >= state.totalDuration) { + state.currentDuration = 0; + } + + changeCurrentDuration(); + }, [state.playing]); + + const changeCurrentDuration = (duration = state.currentDuration) => { + clearTimeout(timerRef.current); + + let nextDuration = duration; + + if (duration < 0) { + nextDuration = 0; + } + + if (duration >= state.totalDuration) { + state.currentDuration = state.totalDuration; + + state.playing = false; + } + + if (!state.playing) return; + + state.currentDuration = nextDuration; + + timerRef.current = setTimeout(() => { + changeCurrentDuration(duration + 1); + }, 1000); + }; + + return ( + ++ ); +}; + +export default ReadAloud;+ {state.loading ? ( +++ ) : ( +
{ + state.playing = !state.playing; + }} + > + {state.playing ? ( ++ )} + + {formatTime} ++ ) : ( +
+ )} +
+ {!state.loading && ( + <> ++{ + changeCurrentDuration(state.currentDuration - 15); + }} + /> + +
{ + changeCurrentDuration(state.currentDuration + 15); + }} + /> + > + )} + +
+