Skip to content

Commit ce58f9e

Browse files
authored
Merge pull request #116 from Devminjeong-eum/feat/DEV-136
[DEV-136] TTS 적용
2 parents cfa330e + d059351 commit ce58f9e

File tree

8 files changed

+103
-38
lines changed

8 files changed

+103
-38
lines changed

next.config.mjs

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ const nextConfig = {
2222
port: '',
2323
pathname: '/**',
2424
},
25+
{
26+
protocol: 'https',
27+
hostname: 'dev-malssami-bucket.s3.ap-northeast-2.amazonaws.com',
28+
port: '',
29+
pathname: '/**',
30+
},
2531
],
2632
},
2733
};

public/sw.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/words/[wordName]/page.tsx

+14-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import PronunciationDetail from '@/components/pages/detail/PronunciationDetail.t
99
import { ResolvingMetadata } from 'next';
1010
import { DetailKoreanAlertIconSvg } from '@/components/svg-component/DetailKoreanAlertIconSvg.tsx';
1111
import React from 'react';
12+
import DetailTTSButton from '@/components/pages/detail/DetailTTSButton.tsx';
1213

1314
// eslint-disable-next-line react-refresh/only-export-components
1415
export async function generateMetadata(
@@ -103,19 +104,24 @@ export default async function WordsPage({
103104
<div>
104105
<div className="flex items-start justify-between pt-[18px] pb-[26px]">
105106
<div className="flex flex-col">
106-
<h1 className="text-[30px] align-bottom font-normal text-white">
107-
{name}
108-
</h1>
107+
<div className="flex items-center">
108+
<h1 className="text-[30px] align-bottom font-normal text-white">
109+
{name}
110+
</h1>
111+
<DetailTTSButton id={id} />
112+
</div>
109113
<span className="text-[#E1E2F8] font-normal">
110114
{/*{NOTE: 대표 발음은 스프레드시트의 첫 번째 발음으로 합니다}*/}
111115
{pronunciation[0]}
112116
</span>
113117
</div>
114-
<LikeButton
115-
initialLike={isLike}
116-
initialLikeCount={likeCount}
117-
wordId={id}
118-
/>
118+
<div className="self-center">
119+
<LikeButton
120+
initialLike={isLike}
121+
initialLikeCount={likeCount}
122+
wordId={id}
123+
/>
124+
</div>
119125
</div>
120126
<div className="text-[#F4F5FF] text-xs flex gap-[5px] pb-2.5">
121127
<DetailKoreanAlertIconSvg />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use client';
2+
3+
import useGetTTSUrl from '@/hooks/query/useGetTTSUrl.ts';
4+
import DetailSoundIconSvg from '@/components/svg-component/DetailSoundIconSvg.tsx';
5+
6+
import React from 'react';
7+
import clsx from 'clsx';
8+
import useAudioPlayer from '@/hooks/useAudioPlayer.ts';
9+
10+
interface Props {
11+
id: string;
12+
}
13+
export default function DetailTTSButton({ id }: Props) {
14+
const { data: audioUrl } = useGetTTSUrl(id);
15+
const { audioRef, startAudio, isPlaying } = useAudioPlayer(id);
16+
17+
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
18+
e.stopPropagation();
19+
20+
if (audioUrl) {
21+
startAudio(audioUrl);
22+
}
23+
};
24+
25+
return (
26+
<div
27+
className="ml-2 flex items-center justify-center w-[34px] h-[34px]"
28+
onClick={handleClick}
29+
>
30+
<DetailSoundIconSvg />
31+
<audio ref={audioRef} loop={false} />
32+
<div
33+
className={clsx(
34+
'absolute opacity-25 w-[34px] h-[34px] rounded-full cursor-pointer border bg-[#6C71E2] hover:bg-[#A19AF9]',
35+
isPlaying ? 'border-[#FFFFFF]' : 'border-[#A19AF9]',
36+
)}
37+
/>
38+
</div>
39+
);
40+
}

src/components/pages/detail/LikeButton.tsx

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
'use client';
22

3-
import DetailLikeSvg from '@/components/svg-component/DetailLikeSvg.tsx';
4-
import DetailLikeActiveSvg from '@/components/svg-component/DetailLikeActiveSvg.tsx';
53
import { useOptimisticLike } from '@/hooks/useOptimisticLike.ts';
64
import useAuthQuery from '@/hooks/query/useAuthQuery.ts';
75
import { useState } from 'react';
86
import LoginAlertModal from '@/components/common/LoginAlertModal.tsx';
7+
import DetailLikeSvg from '@/components/svg-component/DetailLikeSvg.tsx';
98

109
interface Props {
1110
wordId: string;
@@ -47,13 +46,9 @@ export default function LikeButton({
4746
<>
4847
<div className="flex flex-col justify-center items-center cursor-pointer">
4948
<button onClick={() => handleClick(optimisticLikeState.isLike)}>
50-
{optimisticLikeState.isLike ? (
51-
<DetailLikeActiveSvg />
52-
) : (
53-
<DetailLikeSvg />
54-
)}
49+
<DetailLikeSvg isLike={optimisticLikeState.isLike} />
5550
</button>
56-
<span className="text-xs text-[#E1E2F8] pt-1">
51+
<span className="text-xs font-medium text-[#E1E2F8] pt-1">
5752
{optimisticLikeState.likeCount}
5853
</span>
5954
</div>

src/components/svg-component/DetailLikeActiveSvg.tsx

-16
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
1-
export default function DetailLikeSvg() {
1+
interface Props {
2+
isLike: boolean;
3+
}
4+
export default function DetailLikeSvg({ isLike }: Props) {
25
return (
36
<svg
4-
width="23"
5-
height="21"
6-
viewBox="0 0 23 21"
7+
width="30"
8+
height="30"
9+
viewBox="0 0 30 30"
710
fill="none"
811
xmlns="http://www.w3.org/2000/svg"
912
>
1013
<path
11-
d="M2.8722 11.7978L10.8066 19.3408L10.8066 19.3408C10.9987 19.5234 11.0948 19.6148 11.1982 19.6635C11.3893 19.7535 11.6107 19.7535 11.8018 19.6635C11.9052 19.6148 12.0013 19.5234 12.1934 19.3408L20.1278 11.7978C22.3296 9.70463 22.5977 6.28762 20.7493 3.87662L20.3613 3.37057C18.1322 0.463033 13.6159 0.946756 12.0532 4.26042C11.8326 4.72804 11.1674 4.72804 10.9468 4.26042C9.38407 0.946755 4.86775 0.463033 2.63865 3.37057L2.25068 3.87662C0.402263 6.28762 0.670368 9.70463 2.8722 11.7978Z"
14+
d="M7.45067 16.9082L14.4033 23.4395C14.5078 23.5376 14.56 23.5867 14.6116 23.6205C14.8474 23.7751 15.1526 23.7751 15.3884 23.6205C15.44 23.5867 15.4922 23.5376 15.5967 23.4395L22.5493 16.9082C24.5055 15.0706 24.743 12.0466 23.0978 9.92607L22.7885 9.52734C20.8203 6.99058 16.8696 7.41601 15.4867 10.3137C15.2913 10.723 14.7087 10.723 14.5133 10.3137C13.1304 7.41601 9.17972 6.99058 7.21154 9.52735L6.90219 9.92607C5.25695 12.0466 5.4945 15.0706 7.45067 16.9082Z"
1215
fill="#4752CD"
1316
stroke="#4752CD"
1417
/>
18+
<path
19+
d="M7.45067 16.9082L14.4033 23.4395C14.5078 23.5376 14.56 23.5867 14.6116 23.6205C14.8474 23.7751 15.1526 23.7751 15.3884 23.6205C15.44 23.5867 15.4922 23.5376 15.5967 23.4395L22.5493 16.9082C24.5055 15.0706 24.743 12.0466 23.0978 9.92607L22.7885 9.52734C20.8203 6.99058 16.8696 7.41601 15.4867 10.3137C15.2913 10.723 14.7087 10.723 14.5133 10.3137C13.1304 7.41601 9.17972 6.99058 7.21154 9.52735L6.90219 9.92607C5.25695 12.0466 5.4945 15.0706 7.45067 16.9082Z"
20+
fill={isLike ? '#858EEA' : '#4752CD'}
21+
stroke="#4752CD"
22+
/>
1523
</svg>
1624
);
1725
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export default function DetailSoundIconSvg() {
2+
return (
3+
<svg
4+
width="20"
5+
height="20"
6+
viewBox="0 0 20 20"
7+
fill="none"
8+
xmlns="http://www.w3.org/2000/svg"
9+
>
10+
<path
11+
d="M3.46532 11.6089C2.87114 10.6186 2.87114 9.38143 3.46532 8.39114C3.64663 8.08895 3.94701 7.87726 4.29258 7.80815L5.70344 7.52598C5.78749 7.50917 5.86326 7.46409 5.91814 7.39824L7.52449 5.47061C8.55923 4.22893 9.07659 3.60809 9.5383 3.77524C10 3.9424 10 4.75056 10 6.36687L10 13.6331C10 15.2494 10 16.0576 9.5383 16.2248C9.0766 16.3919 8.55923 15.7711 7.52449 14.5294L5.91814 12.6018C5.86326 12.5359 5.78749 12.4908 5.70344 12.474L4.29258 12.1918C3.94701 12.1227 3.64663 11.9111 3.46532 11.6089Z"
12+
fill="#FBFCFE"
13+
/>
14+
<path
15+
d="M12.9464 7.05376C13.7238 7.83114 14.1625 8.88425 14.1668 9.98363C14.1711 11.083 13.7408 12.1395 12.9696 12.923"
16+
stroke="#FBFCFE"
17+
strokeLinecap="round"
18+
/>
19+
<path
20+
d="M15.5472 5.28599C16.791 6.5298 17.4929 8.21478 17.4998 9.97378C17.5067 11.7328 16.8182 13.4232 15.5842 14.6768"
21+
stroke="#FBFCFE"
22+
strokeLinecap="round"
23+
/>
24+
</svg>
25+
);
26+
}

0 commit comments

Comments
 (0)