๐ก ํ๋ช : FLOrida
- ๋ชจํฐ๋ธ๋ก ํ ์ฌ์ดํธ : https://www.music-flo.com/
- FE : ๊น์ง์ ๊น์ถฉ๋ง ์์ง์ ์ต์น์ฒ
- BE : ๊น๊ต์ ์ด์ ํฌ
- ๊ฐ๋ฐ๊ธฐ๊ฐ : 9/19(์) ~ 9/30(๋ชฉ) 14:00 (12์ผ)
์ฌ์ฉํ ๊ธฐ์ ์คํ
FE :JavaScript
React.js
styled-component
react-h5-audio-player
MUI
๋ฑ
BE :JavaScript
Node.js
MySQL
Express.js
jwt
bcrypt
๋ฑ
JUSTCODE ๊ณผ์ ์์ ์งํ๋ 2์ฐจ ํ ํ๋ก์ ํธ์ ๋๋ค.
์ด ํ๋ก์ ํธ๋ ํ์ฅ์ ๋ฐ๋ก ์๊ณ FE ์ด 4๋ช , BE 2๋ช ์ผ๋ก ์ด๋ฃจ์ด์ง ํ์ผ๋ก ์งํํ์ต๋๋ค.
์ฒ์์ ์ ์ทจ๋ฏธ๊ฐ ์์ ๊ฐ์์ด๋ผ ์์ ํ๋ ์ด์ด ๋ฐ ๊ฐ์ธ ํ๋ ์ด๋ฆฌ์คํธ ๊ด๋ฆฌ ๋ฑ์ ๊ธฐ๋ฅ์ ํด๋ณด๊ณ ์ถ๊ธฐ๋ ํ๊ณ , 1์ฐจ ํ๋ก์ ํธ๋ณด๋ค ๊ธฐ๋ฅ๋ ๋ค์ํ๊ธฐ ๋๋ฌธ์ ์ ์ํ๊ณ ํ์๋ถ๋ค๋ ๋ชจ๋ ๋์ํด ์ฃผ์ ์ FLO ์ฌ์ดํธ๋ฅผ ๋ชจํฐ๋ธ๋ก ์ ์ํ๊ฒ ๋์์ต๋๋ค.
์ฌ๊ธฐ์ ๋ชจํฐ๋ธ๋ก ์ ์ํ์๋ค๋ ๊ฑด, ๋๊ตฐ๊ฐ์ ์ฝ๋๋ฅผ ๊ทธ๋๋ก ๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ ํ ๊ฒ์ด ์๋ ํ์ด์ง์ ๊ตฌ์กฐ๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ง์ ์ฝ๋๋ฅผ ์์ฑํ๊ฒ์ ๋ปํฉ๋๋ค.
์ ๊ฐ ๋งก์ ๋ถ๋ถ์ ์๋ฒ๊ฐ ์ด๋ ค์์ ๋ ์ดฌ์ํ์ฌ ์ ํ๋ธ์ ์ ๋ก๋ํ์ต๋๋ค.
์์
ํ๋ ์ด์ด๋ react-h5-audio-player
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์์
ํ์ต๋๋ค.
ํ์ฌ ์ฌ์๋ชฉ๋ก์ state์ ์ธ์ ์คํ ๋ฆฌ์ง์ ์ ์ฅํ์ฌ ๊ด๋ฆฌํ์ต๋๋ค.
์ธ์ ์คํ ๋ฆฌ์ง๋ก๋ ๊ด๋ฆฌํ์ฌ ๋ง์ดํธ ์ ์ธ์ ์คํ ๋ฆฌ์ง์์ ํ์ฌ ์ฌ์๋ชฉ๋ก์ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ ์๋ก๊ณ ์นจ์ ํด๋ ํ์ฌ ์ฌ์๋ชฉ๋ก์ด ์ ์ง๋ฉ๋๋ค.
์ ํ ๊ธฐ๋ฅ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์กด์ฌํ์ง ์์์ ์ง์ ๊ตฌํํ์ต๋๋ค.
const shuffleMusic = () => {
if (JSON.parse(sessionStorage.getItem('tracks')).length !== 0) {
const randomTracks = [...musicTracks].sort(() => Math.random() - 0.5);
if (randomTracks[0] === musicTracks[0]) {
const lastIndex = randomTracks.length - 1;
const randomValue = Math.floor(Math.random() * (lastIndex - 1) + 1);
const temp = randomTracks[0];
randomTracks[0] = randomTracks[randomValue];
randomTracks[randomValue] = temp;
}
setMusicTracks(randomTracks);
}
};
array.sort
๋ฉ์๋๋ฅผ ํตํด ๋๋คํ๊ฒ ํ์ฌ ์ฌ์๋ชฉ๋ก์ ๋ค์๊ณ , ์ฒซ ๋ฒ์งธ ๊ณก์ด ๋ฐ๋์ง ์์์ ๊ฒฝ์ฐ ์ฒซ ๋ฒ์งธ ๊ณก์ ๋ ๋๋คํ ์ธ๋ฑ์ค์ ์์นํ๊ฒ ํ๋๋ก ๋ก์ง์ ๊ตฌํํ์ต๋๋ค.
๊ณก์ ๋ค์ค์ผ๋ก ์ ํํด ํ์ฌ ์ฌ์๋ชฉ๋ก์์ ์ญ์ ๋ฐ ํ๋ ์ด ๋ฆฌ์คํธ์ ์ถ๊ฐํ ์ ์๋๋ก ๊ตฌํํ์ต๋๋ค.
๊ณก์ ์ ํํ์ ๋, ๋ฐฐ์ด์ ๊ณก์ ID๋ฅผ ๋ด์ state๋ก ๊ด๋ฆฌํ์ฌ ์ญ์ ๋ฐ ๋ฐฑ์๋๋ก ์ ๋ฌ(๋ณด๊ดํจ์ ์ถ๊ฐ) ํ ์ ์๋ ๋ก์ง์ ๋๋ค.
์ฌ์ ์ค์ธ ๊ณก์ ๋ฐ๊พธ๋ ค๋ฉด ์ธ๋ฑ์ค ๊ฐ์ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ ๊ฒ์์ ํ๋ฉด ๋ฐฐ์ด์ ๊ธธ์ด๊ฐ ์ค์ด๋ค๊ธฐ ๋๋ฌธ์ ๊ณก์ ํด๋ฆญํ๋ฉด ์๋ ์ฌ์๋ชฉ๋ก์ ์ธ๋ฑ์ค์ ํด๋นํ๋ ๊ณก์ด ์คํ๋์ด๋ฒ๋ฆฝ๋๋ค.
๊ทธ๋์ ์๊ฐํ ๊ฒ์ด ๊ฒ์ ๊ธฐ๋ฅ์ ํตํด ํํฐ๋ง๋ ๊ณก๋ค์ ๊ณก url์ ๋น ๋ฌธ์์ด๋ก ์ค์ ํด๋ฒ๋ ค ๋น ๋ฌธ์์ด์ ๊ฐ์ง ๊ณก๋ค์ ์ถ๋ ฅ๋์ง ์๊ฒ ๋ก์ง์ ๊ตฌํํ์ต๋๋ค.
์์ ๊ณก ์ ํ ๋ก์ง๊ณผ ๋๊ฐ์ต๋๋ค. ํ๋ ์ด๋ฆฌ์คํธ ID๋ฅผ ๋ฐฐ์ด์ ์ ์ฅํ์ฌ state๋ก ๊ด๋ฆฌํฉ๋๋ค.
const playSongs = () => {
if (playlistSongs[0].songTitle) {
fetch(`ํ๋ ์ด๋ฆฌ์คํธ์์ฒญURL`, {
headers: {
Authorization: sessionStorage.getItem('token'),
},
})
.then(res => res.json())
.then(plData => {
const musicTracksId = musicTracks.map(el => el.songId);
const filteredNewTracks = plData.filter(
(el, i) => musicTracksId.includes(el.songId) === false
);
setMusicTracks([...filteredNewTracks, ...musicTracks]);
setAlertOn('ํ์ฌ ์ฌ์๋ชฉ๋ก์ ์ถ๊ฐ๋์์ต๋๋ค. ์ค๋ณต๋ ๊ณก์ ์ ์ธ๋ฉ๋๋ค.');
})
.catch(err => {
if (sessionStorage.getItem('token'))
setAlertOn(
'์ด์ฉ๊ถ์ ๊ตฌ๋งคํด์ผ ์์
์ฌ์ ์๋น์ค๋ฅผ ์ด์ฉํ์ค ์ ์์ต๋๋ค.'
);
});
}
};
์ ์ฒด ์ฌ์ ๋ฒํผ์ ๋๋ฅด๋ฉด ํด๋น ํ๋ ์ด๋ฆฌ์คํธ์ ๊ณก๋ค์ ์์ฒญํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ๋ ์ด๋ฆฌ์คํธ์ ๋ชจ๋ ๊ณก๋ค์ ๋ฐ์ ๋ด ํ์ฌ ํ๋ ์ด๋ฆฌ์คํธ์ ์๋ ๊ณก๋ค์ ์์ด๋๋ฅผ ํตํด ๋น๊ตํด ์ค๋ณต๋์ง ์๋ ๊ณก๋ค๋ง ์ถ๊ฐํ๋๋ก ๋ก์ง์ ๊ตฌํํ์ต๋๋ค.
์ฌ์ ๋ฒํผ์ ๋๋ฅด๋ฉด ํ์ฌ ํ๋ ์ด๋ฆฌ์คํธ์ ์ค๋ณต๋๋ ๊ณก์ด ์๋ค๋ฉด ์ถ๊ฐํ์ง ์๋๋ก ๊ตฌํํ์ต๋๋ค.
๋ฐ๋ ํ๋ ์ด๋ฆฌ์คํธ์ ๊ฐ์ ๋ฐฑ์ผ๋ก ์ ๋ฌํ๊ณ ๋ฐ๋ก ๋ฐ์ํฉ๋๋ค. ๋ํ useRef
์ focus
๋ฉ์๋๋ฅผ ํตํด ์์ ๋ฒํผ ํด๋ฆญ ์, ๋ฐ๋ก ํฌ์ปค์ฑ ๋๋๋ก ์ค์ ํ์ต๋๋ค.
์๋ฆผ ์ฐฝ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด setAlert(โ๋ฉ์ธ์งโ) ๋ฅผ ํตํด ์ํ๋ ๋ฉ์ธ์ง๋ฅผ ์ถ๋ ฅํ ์ ์๋๋ก ํ์ต๋๋ค.
alert ์ปดํฌ๋ํธ๋ ๋ํ๋ ๋ค 3์ด ํ์ ์๋์ผ๋ก ์ฌ๋ผ์ง๋๋ค.
๊ทธ ์ธ ํ์ฌ ์ฌ์๋ชฉ๋ก ์ค๋ณต ๋ฐฉ์ง ๋ฐ ๋ค์ค ์ ํ ๊ธฐ๋ฅ์ ๋์ผํฉ๋๋ค.
๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ ๊น์ง ๋ก๋ฉ ์ปดํฌ๋ํธ๊ฐ ๋น ํ๋ฉด ๋์ ์ถ๋ ฅ๋๋๋ก ํ๊ณ ๋ค๋ฅธ ๋ชจ๋ ํ์ด์ง์ ์ ์ฉํ์ต๋๋ค.
๋์ค์ ์๊ฐ์ด ๋๋ค๋ฉด ์ค์ผ๋ ํค์ผ๋ก๋ ๊ตฌํํด ๋ณด๊ณ ์ถ์ต๋๋ค.
์ด๋ฒ ํ๋ก์ ํธ ์ด๋ฐ์ ํ์์ ์ฌ์ ์ผ๋ก ์ธํด ์ฐ๋ฝ์ด ๋์ง ์์ ํ ํ์ ๊ฐ์ ํธ๋ฌ๋ธ์ด ์๊ธธ๋ป ํ ์ํฉ์ด ์์์ต๋๋ค.
ํ์ง๋ง ๊ทธ ์ดํ ํ์๋ฅผ ํตํด ์ฃผ๊ธฐ์ ์ธ ํ์ ์๊ฐ์ ์ ํด๋๊ณ , Slack (ํ์ ๋ฉ์ ์ ) ์๋ฆผ๋ ํญ์ ์ผ๋๊ธฐ๋ก ํ๋๋ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค.
์ด ์ผ์ ํตํด ํ์ ๊ฐ์ ์ปค๋ฎค๋์ผ์ด์ ์ด ์ผ๋ง๋ ์ค์ํ์ง ํ์ ํ ์ ์์๊ณ , ๋ค์์ ์ด๋ฐ ์ผ์ด ์ผ์ด๋์ง ์๋๋ก ๋ฐฉ์งํด์ผ๊ฒ ๋ค๊ณ ๋ค์งํ๊ฒ ๋์์ต๋๋ค.
์ฌ์ค ์ด๋ฒ ํ๋ก์ ํธ๊น์ง๋ ์ค๋ก์ง ๊ธฐ๋ฅ์ด ์๋ํ๋ ๋ฐ์๋ง ์์๋ฅผ ๋์ด์ ๊ฐ๋ ์ฑ์ ๊ณ ๋ คํ์ง ๋ชปํ๊ณ ์ฝ๋๋ฅผ ์์ฑํ์ต๋๋ค.
ํ์ง๋ง ํ๋ก์ ํธ๊ฐ ๋๋๊ณ ์ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ ํ๋์ ๋ค์ด์ค์ง ์๋๋ค๋ ๊ฒ์ ์๊ฒ ๋์์ต๋๋ค. ๊ทธ๋์ ์ด ํ๋ก์ ํธ๊ฐ ๋๋๊ณ ํด๋ฆฐ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๊ณต๋ถํ๊ณ ์ ์ ๊ฐ๋ ์ฑ๋ ๊ณ ๋ คํ๋ฉฐ ์ฝ๋ฉํ ์ ์๋ ๊ฐ๋ฐ์๊ฐ ๋์ด๊ฐ๊ณ ์๋ ์ค์ ๋๋ค.