Skip to content

Commit

Permalink
🦄 refactor(displayname): use pronunciation component
Browse files Browse the repository at this point in the history
  • Loading branch information
summerscar committed Dec 15, 2024
1 parent 1d56804 commit 01e286a
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 49 deletions.
35 changes: 15 additions & 20 deletions app/components/home-status/display-name.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import SpeakerIcon from "@/assets/svg/speaker.svg";
import { useDevice } from "@/hooks/use-device";
import { useHoverToSearch } from "@/hooks/use-hover-to-search";
import type { DictItem } from "@/types/dict";
import { notoKR } from "@/utils/fonts";
import { generateWordSuggestionPrompt } from "@/utils/prompts";
import clsx from "clsx";
import { romanize, standardizePronunciation } from "es-hangul";
import { Pronunciation } from "../pronunciation";
import { Star } from "./star";

const DisplayName = ({
currentWord,
playWord,
isWordPlaying,
playWordRef,
isLocalDict,
className,
showStar = true,
autoPlay,
}: {
currentWord: DictItem | null;
playWord: () => void;
isWordPlaying: boolean;
isLocalDict: boolean;
showStar?: boolean;
className?: string;
playWordRef?: React.RefObject<() => void>;
autoPlay: boolean;
}) => {
const [displayNameRef, displayNameHoverPanel] = useHoverToSearch(
currentWord?.name,
Expand Down Expand Up @@ -50,21 +50,16 @@ const DisplayName = ({
>
<span ref={displayNameRef}>{displayName}</span>
<div className="absolute min-h-full top-0 right-0 translate-x-[130%] z-[2] flex flex-col justify-center gap-1">
<div
className={clsx("flex", !isTouchable && "tooltip tooltip-top")}
data-tip={`${romanized} [${standardized}]`}
>
<SpeakerIcon
width={20}
height={20}
onMouseEnter={playWord}
onTouchEnd={playWord}
className={clsx(
isWordPlaying ? "fill-current" : "text-base-content",
"cursor-pointer inline-block",
)}
/>
</div>
<Pronunciation
preload={false}
playRef={playWordRef}
tooltipText={`${romanized} [${standardized}]`}
width={20}
height={20}
text={displayName}
tooltip={!isTouchable}
autoPlay={autoPlay}
/>
{showStar && <Star dictItem={currentWord} isLocalDict={isLocalDict} />}
</div>
{displayNameHoverPanel}
Expand Down
36 changes: 23 additions & 13 deletions app/components/home-status/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import RefreshSVG from "@/assets/svg/refresh.svg";

import { useHomeProgress } from "@/components/header/_component/progress";
import { checkIsTouchable, useDevice } from "@/hooks/use-device";
import { usePronunciation } from "@/hooks/use-pronunciation";
import { type Dict, Dicts } from "@/types/dict";
import type { UserDicts } from "@/types/dict";
import type { SITES_LANGUAGE } from "@/types/site";
Expand All @@ -23,7 +22,12 @@ import { isServer } from "@/utils/is-server";
import { hangulToQwerty } from "@/utils/kr-const";
import { getLocalDict } from "@/utils/local-dict";
import { shuffleArr } from "@/utils/shuffle-array";
import { useEventListener, useLatest, useMemoizedFn } from "ahooks";
import {
useDebounceFn,
useEventListener,
useLatest,
useMemoizedFn,
} from "ahooks";
import clsx from "clsx";
import { disassemble } from "es-hangul";
import { useLocale } from "next-intl";
Expand Down Expand Up @@ -72,6 +76,7 @@ const HomeStatus = ({
const [isInputError, setIsInputError] = useState(false);
const [isInputFocused, setIsInputFocused] = useState(false);
const playExampleRef = useRef(() => {});
const playWordRef = useRef(() => {});
const slideToIndexRef = useRef<(index: number) => void>(() => {});
const { isTouchable } = useDevice();
useEffect(() => {
Expand Down Expand Up @@ -149,7 +154,7 @@ const HomeStatus = ({
return;
}
if (e.code === "Semicolon") {
playWord();
playWordRef.current();
return;
}
if (e.code === "Quote") {
Expand Down Expand Up @@ -196,11 +201,6 @@ const HomeStatus = ({
return null;
}, [curWordIndex, dict]);

const { isPlaying: isWordPlaying, play: playWord } = usePronunciation(
currentWord?.name,
{ autoPlay: setting.autoVoice },
);

/** 韩文字母 */
const hangul = parseSpaceStr(disassemble(currentWord?.name || ""));
const lastedHangul = useLatest(hangul);
Expand Down Expand Up @@ -283,6 +283,17 @@ const HomeStatus = ({
);
});

const { run: playSlideWord } = useDebounceFn(
() => {
playWordRef.current();
},
{ wait: 800 },
);
const onSlideChange = useMemoizedFn((index: number) => {
playSlideWord();
skipToNextWord(index);
});

const toPrevWord = useMemoizedFn(() => {
skipToNextWord(curWordIndex - 1);
});
Expand Down Expand Up @@ -346,9 +357,9 @@ const HomeStatus = ({
/>
<DisplayName
currentWord={currentWord}
playWord={playWord}
isWordPlaying={isWordPlaying}
playWordRef={playWordRef}
isLocalDict={isLocalDict}
autoPlay={setting.autoVoice}
/>
<WordMeaning
showMeaning={setting.showMeaning}
Expand Down Expand Up @@ -406,13 +417,12 @@ const HomeStatus = ({
<WordCards
dict={dict}
curWordIndex={curWordIndex}
onChange={skipToNextWord}
playWord={playWord}
isWordPlaying={isWordPlaying}
onChange={onSlideChange}
additionalMeaning={setting.additionalMeaning}
showMeaning={setting.showMeaning}
locale={locale}
isLocalDict={isLocalDict}
playWordRef={playWordRef}
playExampleRef={playExampleRef}
slideToIndexRef={slideToIndexRef}
/>
Expand Down
17 changes: 8 additions & 9 deletions app/components/home-status/word-cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,23 @@ const noop = () => {};
const WordCards = ({
dict,
onChange,
playWord,
isWordPlaying,
isLocalDict,
additionalMeaning,
locale,
showMeaning,
curWordIndex,
playWordRef,
playExampleRef,
slideToIndexRef,
}: {
dict: Dict;
onChange: (index: number) => void;
playWord: () => void;
isWordPlaying: boolean;
isLocalDict: boolean;
locale: SITES_LANGUAGE;
additionalMeaning: boolean;
showMeaning: boolean;
curWordIndex: number;
playWordRef: React.RefObject<() => void>;
playExampleRef: React.RefObject<() => void>;
slideToIndexRef: React.RefObject<(index: number) => void>;
}) => {
Expand All @@ -67,16 +65,17 @@ const WordCards = ({
modules={[EffectCards, Virtual]}
className="w-60 h-80"
initialSlide={curWordIndex}
runCallbacksOnInit={false}
cardsEffect={{
perSlideRotate: 3,
perSlideOffset: 9,
}}
virtual={{
slides: dict,
enabled: true,
addSlidesAfter: 5,
addSlidesBefore: 5,
cache: true,
addSlidesAfter: 4,
addSlidesBefore: 4,
cache: false,
}}
onInit={(swiper) => {
slideToIndexRef.current = (val: number) => {
Expand Down Expand Up @@ -109,11 +108,11 @@ const WordCards = ({
className="absolute top-4 right-4 size-6"
/>
<DisplayName
autoPlay={false}
showStar={false}
className="scale-75"
currentWord={word}
playWord={playWord}
isWordPlaying={isWordPlaying}
playWordRef={getIsActive(i) ? playWordRef : noopRef}
isLocalDict={isLocalDict}
/>
<WordMeaning
Expand Down
14 changes: 12 additions & 2 deletions app/components/pronunciation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ const Pronunciation = ({
text,
children,
tooltip = false,
tooltipText,
autoPlay = false,
...svgProps
}: {
text?: string;
preload?: boolean;
tooltip?: boolean;
tooltipText?: string;
autoPlay?: boolean;
playRef?: RefObject<() => void>;
} & ComponentProps<typeof SpeakerSVG>) => {
const DEFAULT_SIZE = 16;
Expand All @@ -26,7 +30,10 @@ const Pronunciation = ({
...rest
} = svgProps;
const targetText = typeof children === "string" ? children : text || "";
const { isPlaying, play } = usePronunciation(targetText, { preload });
const { isPlaying, play } = usePronunciation(targetText, {
preload,
autoPlay,
});

playRef && (playRef.current = play);

Expand All @@ -49,7 +56,10 @@ const Pronunciation = ({
<>
{children}{" "}
{tooltip && targetText.length < 10 ? (
<span className="tooltip" data-tip={romanize(targetText)}>
<span
className="tooltip"
data-tip={tooltipText || romanize(targetText)}
>
{speakerEl}
</span>
) : (
Expand Down
18 changes: 13 additions & 5 deletions app/hooks/use-pronunciation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// import { createToast } from "@/hooks/use-toast";
import { useDebounceFn, useLatest, useMemoizedFn, useThrottleFn } from "ahooks";
import {
useDebounceFn,
useLatest,
useMemoizedFn,
useThrottleFn,
useUpdateEffect,
} from "ahooks";
import { useEffect, useRef, useState } from "react";

const pronunciationApi = "https://dict.youdao.com/dictvoice?audio=";
Expand Down Expand Up @@ -38,12 +44,14 @@ const usePronunciation = (

audioRef.current.src = generateWordSoundSrc(word);
audioRef.current.preload = preload ? "auto" : "none";
}
}, [preload, word]);

if (lastedAutoPlay.current) {
debouncedPlay();
}
useUpdateEffect(() => {
if (lastedAutoPlay.current) {
debouncedPlay();
}
}, [lastedAutoPlay, preload, word]);
}, [word]);

const play = useMemoizedFn(async () => {
if (audioRef.current) {
Expand Down

0 comments on commit 01e286a

Please sign in to comment.