diff --git a/android/app/src/main/java/com/ohdodok/catchytape/MainActivity.kt b/android/app/src/main/java/com/ohdodok/catchytape/MainActivity.kt index 89d1968..d4a5191 100644 --- a/android/app/src/main/java/com/ohdodok/catchytape/MainActivity.kt +++ b/android/app/src/main/java/com/ohdodok/catchytape/MainActivity.kt @@ -102,7 +102,8 @@ class MainActivity : AppCompatActivity() { navHostFragment.findNavController().addOnDestinationChangedListener { _, destination, _ -> when (destination.id) { - com.ohdodok.catchytape.feature.player.R.id.player_fragment -> { + com.ohdodok.catchytape.feature.player.R.id.player_fragment, + com.ohdodok.catchytape.feature.player.R.id.playlist_bottom_sheet -> { hideBottomNav() hidePlayerController() } diff --git a/android/core/ui/src/main/java/com/ohdodok/catchytape/core/ui/PlaylistBottomSheet.kt b/android/core/ui/src/main/java/com/ohdodok/catchytape/core/ui/PlaylistBottomSheet.kt index beefc37..1d8e0bd 100644 --- a/android/core/ui/src/main/java/com/ohdodok/catchytape/core/ui/PlaylistBottomSheet.kt +++ b/android/core/ui/src/main/java/com/ohdodok/catchytape/core/ui/PlaylistBottomSheet.kt @@ -4,12 +4,15 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast +import androidx.annotation.StringRes 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.cterror.toMessageId import com.ohdodok.catchytape.core.ui.databinding.BottomSheetPlaylistBinding import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -31,21 +34,34 @@ class PlaylistBottomSheet : BottomSheetDialogFragment() { binding.viewModel = viewModel binding.rvPlaylists.adapter = PlaylistAdapter() - observeEvent() + observeEvents() return binding.root } - private fun observeEvent() { + private fun observeEvents() { viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.closeEvent.collect { - findNavController().popBackStack() + viewModel.events.collect { event -> + when (event) { + is PlaylistBottomSheetEvent.Success -> { + showMessage(R.string.add_to_playlist_success) + findNavController().popBackStack() + } + + is PlaylistBottomSheetEvent.ShowMessage -> { + showMessage(event.error.toMessageId()) + } + } } } } } + private fun showMessage(@StringRes messageId: Int) { + Toast.makeText(requireActivity(), messageId, Toast.LENGTH_SHORT).show() + } + override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/android/core/ui/src/main/java/com/ohdodok/catchytape/core/ui/PlaylistBottomSheetViewModel.kt b/android/core/ui/src/main/java/com/ohdodok/catchytape/core/ui/PlaylistBottomSheetViewModel.kt index 32da440..f01afa4 100644 --- a/android/core/ui/src/main/java/com/ohdodok/catchytape/core/ui/PlaylistBottomSheetViewModel.kt +++ b/android/core/ui/src/main/java/com/ohdodok/catchytape/core/ui/PlaylistBottomSheetViewModel.kt @@ -3,10 +3,13 @@ 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.CtErrorType +import com.ohdodok.catchytape.core.domain.model.CtException 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.CoroutineExceptionHandler import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow @@ -17,6 +20,11 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject +sealed interface PlaylistBottomSheetEvent { + data object Success : PlaylistBottomSheetEvent + data class ShowMessage(val error: CtErrorType) : PlaylistBottomSheetEvent +} + @HiltViewModel class PlaylistBottomSheetViewModel @Inject constructor( savedStateHandle: SavedStateHandle, @@ -30,8 +38,16 @@ class PlaylistBottomSheetViewModel @Inject constructor( private val _playlists = MutableStateFlow(emptyList()) val playlists: StateFlow> = _playlists.asStateFlow() - private val _closeEvent = MutableSharedFlow() - val closeEvent: SharedFlow = _closeEvent.asSharedFlow() + private val _events = MutableSharedFlow() + val events: SharedFlow = _events.asSharedFlow() + + private val exceptionHandler = CoroutineExceptionHandler { _, throwable -> + val errorType = + if (throwable is CtException) throwable.ctError + else CtErrorType.UN_KNOWN + + viewModelScope.launch { _events.emit(PlaylistBottomSheetEvent.ShowMessage(errorType)) } + } init { fetchPlaylists() @@ -44,9 +60,9 @@ class PlaylistBottomSheetViewModel @Inject constructor( } private fun addMusicToPlaylist(playlistId: Int, musicId: String) { - viewModelScope.launch { + viewModelScope.launch(exceptionHandler) { playlistRepository.addMusicToPlaylist(playlistId = playlistId, musicId = musicId) - _closeEvent.emit(Unit) + _events.emit(PlaylistBottomSheetEvent.Success) } } diff --git a/android/core/ui/src/main/res/values/strings.xml b/android/core/ui/src/main/res/values/strings.xml index 7fa5418..249df7a 100644 --- a/android/core/ui/src/main/res/values/strings.xml +++ b/android/core/ui/src/main/res/values/strings.xml @@ -37,6 +37,7 @@ 트랙 %d개 재생 목록에 노래 추가 + 노래를 추가했어요. "error_message_connection" "error_message_ssl_hand_shake" @@ -48,7 +49,7 @@ 서버가 작업 중이에요. 잠시만 기다려주세요. "error_message_not_exist_playlist_on_user" "error_message_not_exist_music" - "error_message_already_added" + 이미 추가된 음악이에요. "error_message_invalid_input_value" "error_message_not_exist_user" 이미 회원가입이 완료된 이메일이에요 !