-
Notifications
You must be signed in to change notification settings - Fork 2
[deploy] release v1.1.0 #177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
[chore] ์ฑํ ์๋ฒ ๋ก์ง ๋ณ๊ฒฝ ๋์
[chore] ๋๋ฌ๋ณด๊ธฐ ์๋ฒ ๋ก์ง ๋ณ๊ฒฝ ๋์
[refactor] ์ฑํ ์์ผ context ๊ตฌ์กฐ๋ก ๋ฆฌํฉํ ๋ง
๐ WalkthroughWalkthrough๋ฒ์ ์ 1.0.4์์ 1.1.0์ผ๋ก ์ ๋ฐ์ดํธํ๊ณ , ์ฑํ ์ ๊ณต์ ์ปจํ ์คํธ, ์ฌ์ ๋ชฉ๋ก API ํ์ ํต์ผ, ํ ํฐ ๊ธฐ๋ฐ ์ฑํ ์ธ์ฆ, ํ๋ ์ด์ด ์ค๋ฅ ์ฒ๋ฆฌ, ๊ทธ๋ฆฌ๊ณ ์ฌ๋ฌ ํ์ด์ง ๋ฐ ์์ ฏ ์ปดํฌ๋ํธ๋ฅผ ํจ๊ป ๋ฆฌํฉํ ๋งํ์ต๋๋ค. Changes
Estimated code review effort๐ฏ 4 (Complex) | โฑ๏ธ ~60 minutes Poem
๐ฅ Pre-merge checks | โ 2 | โ 1โ Failed checks (1 inconclusive)
โ Passed checks (2 passed)
โ๏ธ Tip: You can configure your own custom pre-merge checks in the settings. โจ Finishing touches
๐งช Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @maylh, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request marks the release of version 1.1.0, bringing significant improvements to the application's playlist and chat functionalities. It includes a comprehensive refactoring of playlist data structures and API calls, streamlining how playlist information is fetched and managed. A new ChatProvider has been introduced to centralize chat socket logic, making real-time chat features more robust and easier to integrate. Additionally, the YouTube player now includes error handling, improving playback reliability. These changes aim to enhance the overall stability, performance, and user experience of the application. Highlights
๐ง New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with ๐ and ๐ on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
v1.1.0 ๋ฆด๋ฆฌ์ฆ๋ฅผ ์ํ ๋๊ท๋ชจ ๋ฆฌํฉํ ๋ง ๋ฐ ๊ธฐ๋ฅ ์ถ๊ฐ PR์ด๋ค์. ๊ณ ์ ๋ง์ผ์
จ์ต๋๋ค! ์ ๋ฐ์ ์ผ๋ก ํ๋ ์ด๋ฆฌ์คํธ ๋ฐ์ดํฐ ๋ก๋ฉ ๋ฐฉ์์ ์ต์ ํํ๊ณ , ChatProvider๋ฅผ ๋์
ํ์ฌ ์ฑํ
๊ด๋ จ ๋ก์ง์ ๊น๋ํ๊ฒ ๋ถ๋ฆฌํ ์ ์ด ์ธ์์ ์
๋๋ค. ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ํฌ๊ฒ ํฅ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ช ๊ฐ์ง ์ถ๊ฐ ๊ฐ์ ์ ์ ๋ํ ์๊ฒฌ์ ์๋ ์ฝ๋ฉํธ๋ก ๋จ๊ฒผ์ผ๋ ํ์ธ ๋ถํ๋๋ฆฝ๋๋ค.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and canโt be posted inline due to platform limitations.
โ ๏ธ Outside diff range comments (2)
src/widgets/playlist/YoutubePlayer.tsx (1)
74-79:โ ๏ธ Potential issue | ๐ก Minor
onError๊ฐ useEffect ์์กด์ฑ ๋ฐฐ์ด์ ๋๋ฝ๋จ
onError์ฝ๋ฐฑ์ด ํ๋ ์ด์ด ์์ฑ ์ ์ฌ์ฉ๋์ง๋ง ์์กด์ฑ ๋ฐฐ์ด์ ํฌํจ๋์ด ์์ง ์์ต๋๋ค.onError์ฝ๋ฐฑ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ์๋ก์ด ์ฝ๋ฐฑ์ด ๋ฐ์๋์ง ์์ ์ ์์ต๋๋ค.๐ง ์์กด์ฑ ๋ฐฐ์ด์ onError ์ถ๊ฐ ์ ์
- }, [apiReady, videoId, isMobile, onReady, onStateChange, setIsMuted]) + }, [apiReady, videoId, isMobile, onReady, onStateChange, onError, setIsMuted])src/widgets/chat/ChatBottomSheet.tsx (1)
76-81:โ ๏ธ Potential issue | ๐ด Critical
sendMessageํธ์ถ์ ์๋ฌ ์ฒ๋ฆฌ ๋ก์ง์ด ์๋ํ์ง ์์
useChatSocket์sendMessage๋ Promise๋ฅผ ๋ฐํํ์ง ์๋ ๋๊ธฐ ํจ์์ ๋๋ค(void ๋ฐํ). ๋ฐ๋ผ์await๋ฅผ ์ฌ์ฉํด๋ ์๋ฌด ํจ๊ณผ๊ฐ ์์ผ๋ฉฐ, ๋๊ด์ ์ ๋ฐ์ดํธ ๋กค๋ฐฑ์ ์ํ try-catch ๋ธ๋ก๋ ์๋ํ์ง ์์ต๋๋ค.์ถ๊ฐ๋ก
sendMessage๋ ์ฐ๊ฒฐ์ด ๋๊ฒผ๊ฑฐ๋ ๋ด์ฉ์ด ๋น์ด์์ ๋ ์๋ฌ๋ฅผ ๋์ง์ง ์๊ณ ์กฐ์ฉํ ๋ฐํํ๋ฏ๋ก, ์ค์ ๋ก ๋ฉ์์ง ์ ์ก์ด ์คํจํด๋ catch ๋ธ๋ก์ด ์คํ๋์ง ์์ต๋๋ค. ๋๊ด์ ์ผ๋ก ์ฆ๊ฐ์ํจchat-count๊ฐ ์๋๋๋ก ๋กค๋ฐฑ๋์ง ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.๊ฐ์ ์:
sendMessage๋ฅผ ๋น๋๊ธฐ ํจ์๋ก ๋ณ๊ฒฝํ์ฌ ์ค์ ์ ์ก ๊ฒฐ๊ณผ(์ฑ๊ณต/์คํจ)๋ฅผ Promise๋ก ๋ฐํํ๊ฑฐ๋sendMessageํธ์ถ ์ ์connected์ํ๋ฅผ ๋จผ์ ๊ฒ์ฆํ ํ proceedํ๊ฑฐ๋- Promise ๊ธฐ๋ฐ ๋ฉ์์ง ์ ์ก API ์ฌ์ฉ ๊ฒํ
๐ค Fix all issues with AI agents
In `@src/features/chat/model/sendMessage.ts`:
- Line 41: Replace the inline debug logger that currently uses console.log in
the sendMessage.ts STOMP client config (the debug: (str) =>
console.log('[STOMP]', str) entry) with a call to console.warn or a
conditional/no-op logger for production; update the debug function to use
console.warn('[STOMP]', str) or gate logging by an environment flag so static
analysis rules are satisfied and production logging can be disabled.
In `@src/pages/discover/index.tsx`:
- Around line 36-49: The bug is that urlPlaylistId is stored in urlIdRef
(useRef) so route changes don't update startId, and shufflePlaylistIds is
re-created every render causing unnecessary useMemo invalidation; fix by
memoizing shufflePlaylistIds from data using useMemo (e.g., compute
shufflePlaylistIds = useMemo(() => data?.pages.flatMap(p => p.content) ?? [],
[data])), remove urlIdRef and compute startId inside the finalPlaylistIds
useMemo from Number(urlPlaylistId) (guarding against NaN), and make
finalPlaylistIds useMemo depend on [urlPlaylistId, shufflePlaylistIds] to return
either shufflePlaylistIds or [startId, ...filtered].
In `@src/shared/ui/LiveInfo.tsx`:
- Around line 6-14: The Storybook story still uses the old props interface
(isOnAir, listenerCount) but LiveInfo now reads participantCount from useChat
and must be rendered inside ChatProvider; update the LiveInfo story
(LiveInfo.stories.tsx) to wrap LiveInfo with ChatProvider or mock the useChat
context so participantCount is provided, and remove/replace the prop-based
knobs/examples with a context-based variant (or a decorator that injects
participantCount) so the story reflects the current LiveInfo implementation and
shows ON AIR when participantCount > 0.
In `@src/widgets/playlist/PlaylistInfo.tsx`:
- Line 10: Imported UI "Error" component in PlaylistInfo.tsx conflicts with the
global Error type; alias the import (e.g., import { Error as UiError, Header,
Link, Loading, SvgButton } from '@/shared/ui') and then rename all usages of the
component inside the PlaylistInfo React component (replace Error โ UiError) so
the global Error type is not shadowed and TypeScript/Biome linting errors are
resolved.
In `@src/widgets/playlist/PlaylistLayout.tsx`:
- Around line 80-86: ํ์ฌ ์ฝ๋๊ฐ currentPlaylist๊ฐ ์์ ๋ playlistId์ 0์ ๋๊ธฐ๊ณ ์์ด ๋ก๋ฉ ์ค ํด๋ฆญ
์ ์๋ชป๋ ์์ฒญ์ด ๋ฐ์ํ ์ ์์ต๋๋ค; ActionBarContainer/ActionBar๋ฅผ ๋ ๋๋งํ๊ธฐ ์ ์ currentPlaylist
์กด์ฌ์ฌ๋ถ๋ก ๊ฐ๋ํ๊ฑฐ๋ ActionBar์ playlistId๋ฅผ optional๋ก ์ ๋ฌํ๋๋ก ๋ณ๊ฒฝํ์ธ์ (์ฆ, PlaylistLayout์์
currentPlaylist๊ฐ falsy๋ฉด ActionBarContainer/ActionBar๋ฅผ ์๋ตํ๊ฑฐ๋ disabled ์ํ๋ก ๋ ๋๋งํ๊ณ ,
ActionBar ์ปดํฌ๋ํธ๋ playlistId?: number ํํ๋ฅผ ๋ฐ์ null/undefined๋ฅผ ์์ ํ๊ฒ ์ฒ๋ฆฌํ๋๋ก ์์ ).
Ensure you reference the ActionBarContainer/ActionBar render block and the props
playlistId, creatorId, stickers, and type when applying the guard.
๐งน Nitpick comments (5)
src/entities/playlist/api/playlist.ts (1)
44-46: getTracklist์ ๋์ผ ๊ฒฝ๋ก๋ผ๋ฉด ์ฌ์ฌ์ฉ์ผ๋ก ์ค๋ณต ์ ๊ฑฐ ๊ณ ๋ ค ๊ฐ๋ฅ.
์ ์ง๋ณด์ ๋ชฉ์ ์ ์ ํ ์ฌํญ์ ๋๋ค.โป๏ธ ๊ฐ๋จํ ์ค๋ณต ์ ๊ฑฐ ์์
-export const getMyPlaylistDetail = (cdId: number) => { - return api.get<PlaylistDetail>(`/main/playlist/mypage/me/${cdId}`) -} +export const getMyPlaylistDetail = getTracklistsrc/app/providers/ChatProvider.tsx (1)
10-22: Context์ Hook์ ๋ณ๋ ํ์ผ๋ก ๋ถ๋ฆฌํ์ฌ Fast Refresh ์ต์ ํ๋ฅผ ๊ณ ๋ คํ์ธ์.ํ๋ก์ ํธ์
react-refresh/only-export-componentsESLint ๊ท์น์ ๋ฐ๋ฅด๋ฉด, ์ปดํฌ๋ํธ ํ์ผ์ React ์ปดํฌ๋ํธ๋ง exportํด์ผ ํฉ๋๋ค. ํ์ฌChatProvider.tsx์์ChatContext,ChatProvider,useChat์ ํจ๊ป exportํ๋ ํจํด์ Fast Refresh ๊ฒฝ๊ณ ๋ฅผ ๋ฐ์์ํต๋๋ค.๊ถ์ฅ ๊ตฌ์กฐ:
chat.context.ts:ChatContextexportuse-chat.ts:useChathook exportChatProvider.tsx:ChatProvider์ปดํฌ๋ํธ๋ง exportsrc/app/providers/PlayerProvider.tsx (1)
81-89: nextTrack ์์กด์ฑ ๋ฐฐ์ด์ ๋ถํ์ํisMutedํฌํจ
nextTrack์ฝ๋ฐฑ์ ์์กด์ฑ ๋ฐฐ์ด์isMuted๊ฐ ํฌํจ๋์ด ์์ง๋ง, ํจ์ ๋ณธ๋ฌธ์์ ์ฌ์ฉ๋์ง ์์ต๋๋ค. ์ด๋ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ ๋ฐํ ์ ์์ต๋๋ค.๐ง ์์กด์ฑ ๋ฐฐ์ด์์ isMuted ์ ๊ฑฐ ์ ์
const nextTrack = useCallback(() => { if (currentPlaylist && currentTrackIndex < currentPlaylist.songs.length - 1) { setCurrentTrackIndex((prev) => prev + 1) setCurrentTime(0) if (playerRef.current) { playerRef.current.seekTo(0, true) } } - }, [currentPlaylist, currentTrackIndex, isMuted]) + }, [currentPlaylist, currentTrackIndex])src/pages/mycd/index.tsx (1)
131-137: useEffect ์์กด์ฑ ๋ฐฐ์ด์isMobile๋๋ฝ
isMobile๊ฐ์ดsetPlaylistํธ์ถ ์ ์ฌ์ฉ๋์ง๋ง ์์กด์ฑ ๋ฐฐ์ด์ ํฌํจ๋์ด ์์ง ์์ต๋๋ค. ๋๋ฐ์ด์ค ํ์ ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ์๋ ์ฌ์ ์ค์ ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ ์ฉ๋์ง ์์ ์ ์์ต๋๋ค.๐ง ์์กด์ฑ ๋ฐฐ์ด์ isMobile ์ถ๊ฐ
useEffect(() => { if (playlistDetail && userInfo) { if (currentPlaylist?.playlistId === playlistDetail.playlistId) return setPlaylist(playlistDetail, 0, 0, !isMobile) // ๋ชจ๋ฐ์ผ์ด๋ฉด ์๋์ฌ์ off } - }, [playlistDetail, userInfo, setPlaylist, currentPlaylist]) + }, [playlistDetail, userInfo, setPlaylist, currentPlaylist, isMobile])src/pages/home/ui/FirstSection.tsx (1)
8-28:RandomCdData๋ฅผ camelCase๋ก ์ ๋ฆฌํ์ธ์.
๋ณ์/ํ ๊ฒฐ๊ณผ๋ camelCase๊ฐ ์ปจ๋ฒค์ ์ ๋๋ค.RandomCdDataโrandomCdData๋ก ๋ณ๊ฒฝํ๊ณ ์ฌ์ฉ์ฒ๋ ํจ๊ป ์์ ํด์ฃผ์ธ์.๐ง ์ ์ ์์
- const { data: RandomCdData } = usePlaylistDetails(playlistIds) + const { data: randomCdData } = usePlaylistDetails(playlistIds)- <HomeCarousel - data={isLogin ? (MyCdData ?? RandomCdData) : RandomCdData} - isLogin={isLogin} - /> + <HomeCarousel + data={isLogin ? (MyCdData ?? randomCdData) : randomCdData} + isLogin={isLogin} + />As per coding guidelines: '์ ํธ๋ฆฌํฐ/ํ /๋ณ์: camelCase (์: getUserData, useUserInfo)'.
๐ฐ๏ธ ๊ด๋ จ ์ด์
โจ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ
2026.01.31 v1.1.0 ๋ฐฐํฌ
Summary by CodeRabbit
๋ฆด๋ฆฌ์ค ๋ ธํธ
์๋ก์ด ๊ธฐ๋ฅ
๊ฐ์ ์ฌํญ
Chores
โ๏ธ Tip: You can customize this high-level summary in your review settings.