-
Notifications
You must be signed in to change notification settings - Fork 0
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
노래 재생 화면에서 플레이 리스트에 추가 #296
Changes from 10 commits
f87ee24
fa015fe
94a7bfa
3adee93
de3d003
6eb6d42
420f42c
65722da
9272a01
f689114
5c6b966
3bc9582
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.ohdodok.catchytape.core.data.model | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class AddMusicToPlaylistRequest( | ||
val musicId: String | ||
) | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.ohdodok.catchytape.core.ui | ||
|
||
import android.os.Bundle | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import androidx.fragment.app.viewModels | ||
import androidx.lifecycle.Lifecycle | ||
import androidx.lifecycle.lifecycleScope | ||
import androidx.lifecycle.repeatOnLifecycle | ||
import androidx.navigation.fragment.findNavController | ||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment | ||
import com.ohdodok.catchytape.core.ui.databinding.BottomSheetPlaylistBinding | ||
import dagger.hilt.android.AndroidEntryPoint | ||
import kotlinx.coroutines.launch | ||
|
||
@AndroidEntryPoint | ||
class PlaylistBottomSheet : BottomSheetDialogFragment() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BottomSheetDialogFragment() 을 사용해서, Bottom Player가 안보이는 등, 적어주셨던 것 처럼 UI에 문제가 생기는 것거 같은데,
최종발표까지 시간이 얼마 안남았기에, BottomSheetDialog 나 아니면 단순하게 Dialog 등으로 하는 것도 하나의 방법일 것 같아요. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fragment가 아닌 클래스가 있었군요 |
||
val viewModel: PlaylistBottomSheetViewModel by viewModels() | ||
|
||
private var _binding: BottomSheetPlaylistBinding? = null | ||
private val binding get() = _binding!! | ||
|
||
override fun onCreateView( | ||
inflater: LayoutInflater, | ||
container: ViewGroup?, | ||
savedInstanceState: Bundle? | ||
): View { | ||
_binding = BottomSheetPlaylistBinding.inflate(inflater, container, false) | ||
binding.lifecycleOwner = viewLifecycleOwner | ||
binding.viewModel = viewModel | ||
binding.rvPlaylists.adapter = PlaylistAdapter() | ||
|
||
observeEvent() | ||
|
||
return binding.root | ||
} | ||
|
||
private fun observeEvent() { | ||
viewLifecycleOwner.lifecycleScope.launch { | ||
repeatOnLifecycle(Lifecycle.State.STARTED) { | ||
viewModel.closeEvent.collect { | ||
findNavController().popBackStack() | ||
} | ||
} | ||
} | ||
} | ||
|
||
override fun onDestroyView() { | ||
super.onDestroyView() | ||
_binding = null | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.ohdodok.catchytape.core.ui | ||
|
||
import androidx.lifecycle.SavedStateHandle | ||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import com.ohdodok.catchytape.core.domain.model.Playlist | ||
import com.ohdodok.catchytape.core.domain.repository.PlaylistRepository | ||
import com.ohdodok.catchytape.core.ui.model.PlaylistUiModel | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import kotlinx.coroutines.flow.MutableSharedFlow | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.SharedFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
import kotlinx.coroutines.flow.asSharedFlow | ||
import kotlinx.coroutines.flow.asStateFlow | ||
import kotlinx.coroutines.flow.first | ||
import kotlinx.coroutines.launch | ||
import javax.inject.Inject | ||
|
||
@HiltViewModel | ||
class PlaylistBottomSheetViewModel @Inject constructor( | ||
savedStateHandle: SavedStateHandle, | ||
private val playlistRepository: PlaylistRepository, | ||
) : ViewModel() { | ||
|
||
private val musicId: String = requireNotNull(savedStateHandle["musicId"]) { | ||
"musicId 정보가 누락되었어요." | ||
} | ||
|
||
private val _playlists = MutableStateFlow(emptyList<PlaylistUiModel>()) | ||
val playlists: StateFlow<List<PlaylistUiModel>> = _playlists.asStateFlow() | ||
|
||
private val _closeEvent = MutableSharedFlow<Unit>() | ||
val closeEvent: SharedFlow<Unit> = _closeEvent.asSharedFlow() | ||
|
||
init { | ||
fetchPlaylists() | ||
} | ||
|
||
private fun fetchPlaylists() { | ||
viewModelScope.launch { | ||
_playlists.value = playlistRepository.getPlaylists().first().toUiModels() | ||
} | ||
} | ||
|
||
private fun addMusicToPlaylist(playlistId: Int, musicId: String) { | ||
viewModelScope.launch { | ||
playlistRepository.addMusicToPlaylist(playlistId = playlistId, musicId = musicId) | ||
_closeEvent.emit(Unit) | ||
} | ||
} | ||
|
||
private fun List<Playlist>.toUiModels(): List<PlaylistUiModel> = this.map { it.toUiModel() } | ||
|
||
private fun Playlist.toUiModel(): PlaylistUiModel { | ||
Comment on lines
+53
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 함수명을 toPresentation 으로 하는 것 어떨까욥? toDomain 과 맥락이 동일하게! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나는 조금 다르게 생각했어. UiModel은 특정 UI 컴포넌트에서만 사용하는 개념으로 봤어. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. toPresentation == toUiModel 은 같은 의미라고 느껴져! 적어둔 이유처럼 특정 ui컴포넌트만을 위한 것이라면 어떤 컴포넌트의 UiModel인지 함수명을 바꿔야하지 않을까? 그게 아니라면 toPresentation 도 괜찮은 것 같아 |
||
return PlaylistUiModel( | ||
id = id, | ||
title = title, | ||
thumbnailUrl = thumbnailUrl, | ||
trackSize = trackSize, | ||
onClick = { | ||
addMusicToPlaylist( | ||
playlistId = id, | ||
musicId = musicId | ||
) | ||
} | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<layout xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:app="http://schemas.android.com/apk/res-auto" | ||
xmlns:tools="http://schemas.android.com/tools"> | ||
|
||
<data> | ||
<variable | ||
name="viewModel" | ||
type="com.ohdodok.catchytape.core.ui.PlaylistBottomSheetViewModel" /> | ||
</data> | ||
|
||
<androidx.constraintlayout.widget.ConstraintLayout | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:background="@color/surface_bright"> | ||
|
||
<TextView | ||
android:id="@+id/tv_title" | ||
style="@style/TitleMedium" | ||
android:layout_width="0dp" | ||
android:layout_height="wrap_content" | ||
android:layout_marginHorizontal="@dimen/margin_horizontal" | ||
android:layout_marginTop="@dimen/extra_large" | ||
android:text="@string/add_to_playlist" | ||
android:textColor="@color/on_surface" | ||
app:layout_constraintEnd_toEndOf="parent" | ||
app:layout_constraintStart_toStartOf="parent" | ||
app:layout_constraintTop_toTopOf="parent" /> | ||
|
||
<com.google.android.material.divider.MaterialDivider | ||
android:id="@+id/divider" | ||
android:layout_width="0dp" | ||
android:layout_height="1dp" | ||
android:layout_marginTop="@dimen/medium" | ||
app:dividerColor="@color/outline_variant" | ||
app:layout_constraintEnd_toEndOf="parent" | ||
app:layout_constraintStart_toStartOf="parent" | ||
app:layout_constraintTop_toBottomOf="@id/tv_title" /> | ||
|
||
<androidx.recyclerview.widget.RecyclerView | ||
android:id="@+id/rv_playlists" | ||
android:layout_width="0dp" | ||
android:layout_height="wrap_content" | ||
android:layout_marginTop="8dp" | ||
android:layout_marginBottom="8dp" | ||
android:maxHeight="400dp" | ||
android:orientation="vertical" | ||
android:paddingHorizontal="@dimen/margin_horizontal" | ||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" | ||
app:layout_constraintBottom_toBottomOf="parent" | ||
app:layout_constraintEnd_toEndOf="parent" | ||
app:layout_constraintStart_toStartOf="parent" | ||
app:layout_constraintTop_toBottomOf="@id/divider" | ||
app:list="@{viewModel.playlists}" | ||
tools:itemCount="3" | ||
tools:listitem="@layout/item_music_vertical" /> | ||
|
||
</androidx.constraintlayout.widget.ConstraintLayout> | ||
</layout> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,7 @@ | |
<string name="description">설명</string> | ||
<string name="select_thumbnail">썸네일 이미지 선택</string> | ||
|
||
|
||
<string name="track_size">트랙 %d개</string> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 playlist 모듈 strings 파일에 있는데 playlist 모듈에서 삭제한번 해주세요!~ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넹 삭제할게여 |
||
|
||
<string name="error_message_connection">"error_message_connection"</string> | ||
<string name="error_message_ssl_hand_shake">"error_message_ssl_hand_shake"</string> | ||
|
@@ -53,5 +53,6 @@ | |
<string name="error_message_not_exist_genre">"error_message_not_exist_genre"</string> | ||
<string name="error_message_expired_token">"error_message_expired_token"</string> | ||
<string name="error_message_service">"error_message_service"</string> | ||
<string name="add_to_playlist">재생 목록에 노래 추가</string> | ||
|
||
</resources> |
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.
오 이거 제가 올린 PR에도 생성된 requestbody 인데 자주 쓰일 것 같아서 저는 MusicIdRequest 로 클래스를 만들었습니당! 이따 통일하는 게 좋을 것 같네요~!
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.
MusicIdRequest가 더 간단해서 좋네요