From 939f82d9ef1348418fc2e70ff1762f867dcb3f5c Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 5 Jan 2025 16:42:24 +0900 Subject: [PATCH 01/46] =?UTF-8?q?[chore]=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC,=20=EC=9C=A0=EC=8A=A4=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/create/CreatePickViewModel.kt | 14 +++---- .../{pick => detail}/DetailPickScreen.kt | 42 +++++++++---------- .../{pick => detail}/DetailPickUiState.kt | 2 +- .../DetailViewModel.kt} | 14 +++---- .../components/CircleAlbumCover.kt | 6 +-- .../components/CommentText.kt | 2 +- .../components/DeletePickDialog.kt | 2 +- .../components/DetailPickTopAppBar.kt | 2 +- .../components/MusicVideoKnob.kt | 2 +- .../components/PickInformation.kt | 2 +- .../PlayCircularProgressIndicator.kt | 2 +- .../{pick => detail}/components/SongInfo.kt | 2 +- .../components/SwipeUpIcon.kt | 2 +- .../components/music/MusicPlayer.kt | 2 +- .../components/music/PlayBar.kt | 2 +- .../components/music/PlayProgressIndicator.kt | 2 +- .../components/music/PlayerControls.kt | 2 +- .../music/visualizer/BaseVisualizer.kt | 2 +- .../visualizer/CanvasCircleVisualizer.kt | 2 +- .../music/visualizer/CircleVisualizer.kt | 2 +- .../squirtles/musicroad/main/MainViewModel.kt | 10 ++--- .../main/navigations/MainNavGraph.kt | 2 +- .../squirtles/musicroad/map/MapViewModel.kt | 10 ++--- .../map/components/PickNotificationBanner.kt | 4 +- .../musicroad/picklist/PickListViewModel.kt | 10 ++--- .../musicroad/profile/ProfileViewModel.kt | 8 ++-- .../datasource/local/LocalDataSourceImpl.kt | 2 +- .../applemusic/AppleMusicDataSourceImpl.kt | 2 +- .../remote/firebase/FirebaseDataSourceImpl.kt | 2 +- .../java/com/squirtles/data/di/DataModule.kt | 12 +++--- .../repository/AppleMusicRepositoryImpl.kt | 6 +-- .../data/repository/FirebaseRepositoryImpl.kt | 6 +-- .../data/repository/LocalRepositoryImpl.kt | 4 +- .../AppleMusicException.kt | 2 +- .../AppleMusicRemoteDataSource.kt | 2 +- .../AppleMusicRepository.kt | 2 +- .../FirebaseException.kt | 2 +- .../FirebaseRemoteDataSource.kt | 4 +- .../FirebaseRepository.kt | 2 +- .../{datasource => local}/LocalDataSource.kt | 2 +- .../{repository => local}/LocalRepository.kt | 2 +- .../CreateFavoriteUseCase.kt | 4 +- .../DeleteFavoriteUseCase.kt | 4 +- .../FetchFavoritePicksUseCase.kt | 4 +- .../usecase/local/FetchLastLocationUseCase.kt | 10 ----- .../location/GetLastLocationUseCase.kt | 10 +++++ .../SaveLastLocationUseCase.kt | 4 +- .../usecase/music/FetchMusicVideoUseCase.kt | 2 +- ...chSongsUseCase.kt => FetchSongsUseCase.kt} | 4 +- .../usecase/mypick/CreatePickUseCase.kt | 2 +- .../usecase/mypick/DeletePickUseCase.kt | 2 +- .../usecase/mypick/FetchMyPicksUseCase.kt | 2 +- .../GetFavoriteListOrderUseCase.kt | 4 +- .../{local => order}/GetMyListOrderUseCase.kt | 4 +- .../SaveFavoriteListOrderUseCase.kt | 4 +- .../SaveMyListOrderUseCase.kt | 4 +- .../usecase/pick/FetchIsFavoriteUseCase.kt | 2 +- .../usecase/pick/FetchPickInAreaUseCase.kt | 4 +- .../domain/usecase/pick/FetchPickUseCase.kt | 4 +- ...UserUseCase.kt => CreateNewUserUseCase.kt} | 6 +-- .../usecase/user/FetchUserByIdUseCase.kt | 2 +- .../domain/usecase/user/FetchUserUseCase.kt | 4 +- .../{local => user}/GetCurrentUserUseCase.kt | 4 +- .../GetUserIdFromLocalStorageUseCase.kt | 4 +- ...meUserCase.kt => UpdateUserNameUseCase.kt} | 4 +- 65 files changed, 148 insertions(+), 154 deletions(-) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/DetailPickScreen.kt (92%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/DetailPickUiState.kt (88%) rename app/src/main/java/com/squirtles/musicroad/{pick/PickViewModel.kt => detail/DetailViewModel.kt} (94%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/CircleAlbumCover.kt (91%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/CommentText.kt (97%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/DeletePickDialog.kt (98%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/DetailPickTopAppBar.kt (98%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/MusicVideoKnob.kt (98%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/PickInformation.kt (96%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/PlayCircularProgressIndicator.kt (97%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/SongInfo.kt (95%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/SwipeUpIcon.kt (95%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/music/MusicPlayer.kt (97%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/music/PlayBar.kt (98%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/music/PlayProgressIndicator.kt (96%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/music/PlayerControls.kt (98%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/music/visualizer/BaseVisualizer.kt (97%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/music/visualizer/CanvasCircleVisualizer.kt (98%) rename app/src/main/java/com/squirtles/musicroad/{pick => detail}/components/music/visualizer/CircleVisualizer.kt (98%) rename domain/src/main/java/com/squirtles/domain/{exception => applemusic}/AppleMusicException.kt (91%) rename domain/src/main/java/com/squirtles/domain/{datasource => applemusic}/AppleMusicRemoteDataSource.kt (90%) rename domain/src/main/java/com/squirtles/domain/{repository => applemusic}/AppleMusicRepository.kt (90%) rename domain/src/main/java/com/squirtles/domain/{exception => firebase}/FirebaseException.kt (93%) rename domain/src/main/java/com/squirtles/domain/{datasource => firebase}/FirebaseRemoteDataSource.kt (88%) rename domain/src/main/java/com/squirtles/domain/{repository => firebase}/FirebaseRepository.kt (96%) rename domain/src/main/java/com/squirtles/domain/{datasource => local}/LocalDataSource.kt (94%) rename domain/src/main/java/com/squirtles/domain/{repository => local}/LocalRepository.kt (94%) rename domain/src/main/java/com/squirtles/domain/usecase/{favoritepick => favorite}/CreateFavoriteUseCase.kt (70%) rename domain/src/main/java/com/squirtles/domain/usecase/{favoritepick => favorite}/DeleteFavoriteUseCase.kt (70%) rename domain/src/main/java/com/squirtles/domain/usecase/{favoritepick => favorite}/FetchFavoritePicksUseCase.kt (68%) delete mode 100644 domain/src/main/java/com/squirtles/domain/usecase/local/FetchLastLocationUseCase.kt create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/location/GetLastLocationUseCase.kt rename domain/src/main/java/com/squirtles/domain/usecase/{local => location}/SaveLastLocationUseCase.kt (73%) rename domain/src/main/java/com/squirtles/domain/usecase/music/{SearchSongsUseCase.kt => FetchSongsUseCase.kt} (68%) rename domain/src/main/java/com/squirtles/domain/usecase/{local => order}/GetFavoriteListOrderUseCase.kt (67%) rename domain/src/main/java/com/squirtles/domain/usecase/{local => order}/GetMyListOrderUseCase.kt (65%) rename domain/src/main/java/com/squirtles/domain/usecase/{local => order}/SaveFavoriteListOrderUseCase.kt (73%) rename domain/src/main/java/com/squirtles/domain/usecase/{local => order}/SaveMyListOrderUseCase.kt (72%) rename domain/src/main/java/com/squirtles/domain/usecase/user/{CreateUserUseCase.kt => CreateNewUserUseCase.kt} (78%) rename domain/src/main/java/com/squirtles/domain/usecase/{local => user}/GetCurrentUserUseCase.kt (65%) rename domain/src/main/java/com/squirtles/domain/usecase/{local => user}/GetUserIdFromLocalStorageUseCase.kt (66%) rename domain/src/main/java/com/squirtles/domain/usecase/user/{UpdateUserNameUserCase.kt => UpdateUserNameUseCase.kt} (71%) diff --git a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt index 65acec1c..a439f820 100644 --- a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt @@ -10,10 +10,10 @@ import com.squirtles.domain.model.Creator import com.squirtles.domain.model.LocationPoint import com.squirtles.domain.model.Pick import com.squirtles.domain.model.Song -import com.squirtles.domain.usecase.local.FetchLastLocationUseCase -import com.squirtles.domain.usecase.local.GetCurrentUserUseCase +import com.squirtles.domain.usecase.location.GetLastLocationUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.music.FetchMusicVideoUseCase -import com.squirtles.domain.usecase.music.SearchSongsUseCase +import com.squirtles.domain.usecase.music.FetchSongsUseCase import com.squirtles.domain.usecase.mypick.CreatePickUseCase import com.squirtles.musicroad.common.throttleFirst import dagger.hilt.android.lifecycle.HiltViewModel @@ -30,8 +30,8 @@ import javax.inject.Inject @OptIn(FlowPreview::class) @HiltViewModel class CreatePickViewModel @Inject constructor( - fetchLastLocationUseCase: FetchLastLocationUseCase, - private val searchSongsUseCase: SearchSongsUseCase, + getLastLocationUseCase: GetLastLocationUseCase, + private val fetchSongsUseCase: FetchSongsUseCase, private val fetchMusicVideoUseCase: FetchMusicVideoUseCase, private val createPickUseCase: CreatePickUseCase, private val getCurrentUserUseCase: GetCurrentUserUseCase @@ -65,7 +65,7 @@ class CreatePickViewModel @Inject constructor( init { // 데이터소스의 위치값을 계속 collect하며 curLocation 변수에 저장 viewModelScope.launch { - fetchLastLocationUseCase().collect { location -> + getLastLocationUseCase().collect { location -> lastLocation = location } } @@ -94,7 +94,7 @@ class CreatePickViewModel @Inject constructor( } private suspend fun searchSongs(searchKeyword: String) { - searchSongsUseCase(searchKeyword) + fetchSongsUseCase(searchKeyword) .cachedIn(viewModelScope) .collectLatest { _searchResult.emit(it) diff --git a/app/src/main/java/com/squirtles/musicroad/pick/DetailPickScreen.kt b/app/src/main/java/com/squirtles/musicroad/detail/DetailPickScreen.kt similarity index 92% rename from app/src/main/java/com/squirtles/musicroad/pick/DetailPickScreen.kt rename to app/src/main/java/com/squirtles/musicroad/detail/DetailPickScreen.kt index 69f3487b..13230715 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/DetailPickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/DetailPickScreen.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick +package com.squirtles.musicroad.detail import android.app.Activity import android.content.Context @@ -55,16 +55,16 @@ import com.squirtles.domain.model.Pick import com.squirtles.musicroad.R import com.squirtles.musicroad.common.VerticalSpacer import com.squirtles.musicroad.media.PlayerServiceViewModel -import com.squirtles.musicroad.pick.PickViewModel.Companion.DEFAULT_PICK -import com.squirtles.musicroad.pick.components.CircleAlbumCover -import com.squirtles.musicroad.pick.components.CommentText -import com.squirtles.musicroad.pick.components.DeletePickDialog -import com.squirtles.musicroad.pick.components.DetailPickTopAppBar -import com.squirtles.musicroad.pick.components.MusicVideoKnob -import com.squirtles.musicroad.pick.components.PickInformation -import com.squirtles.musicroad.pick.components.SongInfo -import com.squirtles.musicroad.pick.components.music.MusicPlayer -import com.squirtles.musicroad.pick.components.music.visualizer.BaseVisualizer +import com.squirtles.musicroad.detail.DetailViewModel.Companion.DEFAULT_PICK +import com.squirtles.musicroad.detail.components.CircleAlbumCover +import com.squirtles.musicroad.detail.components.CommentText +import com.squirtles.musicroad.detail.components.DeletePickDialog +import com.squirtles.musicroad.detail.components.DetailPickTopAppBar +import com.squirtles.musicroad.detail.components.MusicVideoKnob +import com.squirtles.musicroad.detail.components.PickInformation +import com.squirtles.musicroad.detail.components.SongInfo +import com.squirtles.musicroad.detail.components.music.MusicPlayer +import com.squirtles.musicroad.detail.components.music.visualizer.BaseVisualizer import com.squirtles.musicroad.ui.theme.Black import com.squirtles.musicroad.ui.theme.White import com.squirtles.musicroad.videoplayer.MusicVideoScreen @@ -74,14 +74,14 @@ import kotlin.math.absoluteValue @Composable fun DetailPickScreen( pickId: String, - pickViewModel: PickViewModel = hiltViewModel(), + detailViewModel: DetailViewModel = hiltViewModel(), playerServiceViewModel: PlayerServiceViewModel, onProfileClick: (String) -> Unit, onBackClick: () -> Unit, onDeleted: (Context) -> Unit, ) { val context = LocalContext.current - val uiState by pickViewModel.detailPickUiState.collectAsStateWithLifecycle() + val uiState by detailViewModel.detailPickUiState.collectAsStateWithLifecycle() var showDeletePickDialog by rememberSaveable { mutableStateOf(false) } var showProcessIndicator by rememberSaveable { mutableStateOf(false) } var isMusicVideoAvailable by remember { mutableStateOf(false) } @@ -93,7 +93,7 @@ fun DetailPickScreen( } LaunchedEffect(Unit) { - pickViewModel.fetchPick(pickId) + detailViewModel.fetchPick(pickId) } when (uiState) { @@ -112,7 +112,7 @@ fun DetailPickScreen( val lifecycleOwner = LocalLifecycleOwner.current val pick = (uiState as DetailPickUiState.Success).pick val isFavorite = (uiState as DetailPickUiState.Success).isFavorite - val isCreatedBySelf = pickViewModel.getUserId() == pick.createdBy.userId + val isCreatedBySelf = detailViewModel.getUserId() == pick.createdBy.userId var favoriteCount by rememberSaveable { mutableIntStateOf(pick.favoriteCount) } val onActionClick: () -> Unit = { when { @@ -123,7 +123,7 @@ fun DetailPickScreen( isFavorite -> { showProcessIndicator = true - pickViewModel.toggleFavoritePick( + detailViewModel.toggleFavoritePick( pickId = pickId, isAdding = false ) @@ -131,7 +131,7 @@ fun DetailPickScreen( else -> { showProcessIndicator = true - pickViewModel.toggleFavoritePick( + detailViewModel.toggleFavoritePick( pickId = pickId, isAdding = true ) @@ -145,7 +145,7 @@ fun DetailPickScreen( ) LaunchedEffect(Unit) { - pickViewModel.favoriteAction + detailViewModel.favoriteAction .flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED) .collect { action -> when (action) { @@ -172,12 +172,12 @@ fun DetailPickScreen( } LaunchedEffect(pagerState) { - pagerState.scrollToPage(page = pickViewModel.currentTab) + pagerState.scrollToPage(page = detailViewModel.currentTab) } DisposableEffect(Unit) { onDispose { - pickViewModel.setCurrentTab(pagerState.currentPage) + detailViewModel.setCurrentTab(pagerState.currentPage) } } @@ -278,7 +278,7 @@ fun DetailPickScreen( }, onDeletion = { showDeletePickDialog = false - pickViewModel.deletePick(pickId) + detailViewModel.deletePick(pickId) } ) } diff --git a/app/src/main/java/com/squirtles/musicroad/pick/DetailPickUiState.kt b/app/src/main/java/com/squirtles/musicroad/detail/DetailPickUiState.kt similarity index 88% rename from app/src/main/java/com/squirtles/musicroad/pick/DetailPickUiState.kt rename to app/src/main/java/com/squirtles/musicroad/detail/DetailPickUiState.kt index 304686b8..75523d44 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/DetailPickUiState.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/DetailPickUiState.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick +package com.squirtles.musicroad.detail import com.squirtles.domain.model.Pick diff --git a/app/src/main/java/com/squirtles/musicroad/pick/PickViewModel.kt b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt similarity index 94% rename from app/src/main/java/com/squirtles/musicroad/pick/PickViewModel.kt rename to app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt index 0aad8b62..1f1fcfa2 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/PickViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick +package com.squirtles.musicroad.detail import androidx.core.graphics.toColorInt import androidx.lifecycle.ViewModel @@ -7,9 +7,9 @@ import com.squirtles.domain.model.Creator import com.squirtles.domain.model.LocationPoint import com.squirtles.domain.model.Pick import com.squirtles.domain.model.Song -import com.squirtles.domain.usecase.favoritepick.CreateFavoriteUseCase -import com.squirtles.domain.usecase.favoritepick.DeleteFavoriteUseCase -import com.squirtles.domain.usecase.local.GetCurrentUserUseCase +import com.squirtles.domain.usecase.favorite.CreateFavoriteUseCase +import com.squirtles.domain.usecase.favorite.DeleteFavoriteUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.mypick.DeletePickUseCase import com.squirtles.domain.usecase.pick.FetchIsFavoriteUseCase import com.squirtles.domain.usecase.pick.FetchPickUseCase @@ -23,12 +23,8 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject -enum class FavoriteAction { - ADDED, DELETED -} - @HiltViewModel -class PickViewModel @Inject constructor( +class DetailViewModel @Inject constructor( private val fetchPickUseCase: FetchPickUseCase, private val getCurrentUserUseCase: GetCurrentUserUseCase, private val deletePickUseCase: DeletePickUseCase, diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/CircleAlbumCover.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt similarity index 91% rename from app/src/main/java/com/squirtles/musicroad/pick/components/CircleAlbumCover.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt index a313f7ea..f6e315a6 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/CircleAlbumCover.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import android.util.Size import androidx.compose.foundation.layout.Box @@ -18,8 +18,8 @@ import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.squirtles.domain.model.Song import com.squirtles.musicroad.R -import com.squirtles.musicroad.pick.components.music.visualizer.BaseVisualizer -import com.squirtles.musicroad.pick.components.music.visualizer.CircleVisualizer +import com.squirtles.musicroad.detail.components.music.visualizer.BaseVisualizer +import com.squirtles.musicroad.detail.components.music.visualizer.CircleVisualizer @Composable internal fun CircleAlbumCover( diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/CommentText.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/CommentText.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/pick/components/CommentText.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/CommentText.kt index ea53839c..bf3a830e 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/CommentText.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/CommentText.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/DeletePickDialog.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/DeletePickDialog.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/pick/components/DeletePickDialog.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/DeletePickDialog.kt index 9cee806f..b7f9ec74 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/DeletePickDialog.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/DeletePickDialog.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/DetailPickTopAppBar.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/DetailPickTopAppBar.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/pick/components/DetailPickTopAppBar.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/DetailPickTopAppBar.kt index 481b29e5..b2eabde3 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/DetailPickTopAppBar.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/DetailPickTopAppBar.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/MusicVideoKnob.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/MusicVideoKnob.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/pick/components/MusicVideoKnob.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/MusicVideoKnob.kt index 19ad7557..8d7ca3b0 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/MusicVideoKnob.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/MusicVideoKnob.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import android.util.Size import androidx.compose.animation.core.FastOutSlowInEasing diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/PickInformation.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/PickInformation.kt similarity index 96% rename from app/src/main/java/com/squirtles/musicroad/pick/components/PickInformation.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/PickInformation.kt index 0a1ed0b2..51a6b925 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/PickInformation.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/PickInformation.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/PlayCircularProgressIndicator.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/PlayCircularProgressIndicator.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/pick/components/PlayCircularProgressIndicator.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/PlayCircularProgressIndicator.kt index e841107c..d9d668a0 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/PlayCircularProgressIndicator.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/PlayCircularProgressIndicator.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Box diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/SongInfo.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/SongInfo.kt similarity index 95% rename from app/src/main/java/com/squirtles/musicroad/pick/components/SongInfo.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/SongInfo.kt index d289dc43..149104a5 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/SongInfo.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/SongInfo.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/SwipeUpIcon.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/SwipeUpIcon.kt similarity index 95% rename from app/src/main/java/com/squirtles/musicroad/pick/components/SwipeUpIcon.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/SwipeUpIcon.kt index 8b0665a6..c9b4f063 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/SwipeUpIcon.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/SwipeUpIcon.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components +package com.squirtles.musicroad.detail.components import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/music/MusicPlayer.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/music/MusicPlayer.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/pick/components/music/MusicPlayer.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/music/MusicPlayer.kt index 1497778b..8f49325b 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/music/MusicPlayer.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/music/MusicPlayer.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components.music +package com.squirtles.musicroad.detail.components.music import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayBar.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayBar.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayBar.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayBar.kt index 2e4bb714..e4d91cf3 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayBar.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayBar.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components.music +package com.squirtles.musicroad.detail.components.music import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayProgressIndicator.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayProgressIndicator.kt similarity index 96% rename from app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayProgressIndicator.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayProgressIndicator.kt index 216f4506..b0586e02 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayProgressIndicator.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayProgressIndicator.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components.music +package com.squirtles.musicroad.detail.components.music import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Box diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayerControls.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayerControls.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayerControls.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayerControls.kt index 889b5bee..d24f0d45 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/music/PlayerControls.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/music/PlayerControls.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components.music +package com.squirtles.musicroad.detail.components.music import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/BaseVisualizer.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/BaseVisualizer.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/BaseVisualizer.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/BaseVisualizer.kt index 0be896a6..341d7e77 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/BaseVisualizer.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/BaseVisualizer.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components.music.visualizer +package com.squirtles.musicroad.detail.components.music.visualizer import android.media.audiofx.Visualizer import kotlinx.coroutines.flow.MutableSharedFlow diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/CanvasCircleVisualizer.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/CanvasCircleVisualizer.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/CanvasCircleVisualizer.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/CanvasCircleVisualizer.kt index efe632c8..12d9b634 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/CanvasCircleVisualizer.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/CanvasCircleVisualizer.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components.music.visualizer +package com.squirtles.musicroad.detail.components.music.visualizer import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.fillMaxSize diff --git a/app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/CircleVisualizer.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/CircleVisualizer.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/CircleVisualizer.kt rename to app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/CircleVisualizer.kt index 932713c6..39dd6a9b 100644 --- a/app/src/main/java/com/squirtles/musicroad/pick/components/music/visualizer/CircleVisualizer.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/music/visualizer/CircleVisualizer.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick.components.music.visualizer +package com.squirtles.musicroad.detail.components.music.visualizer import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.AnimationVector1D diff --git a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt index e0976a8e..c98cf693 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt @@ -2,9 +2,9 @@ package com.squirtles.musicroad.main import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.squirtles.domain.exception.FirebaseException -import com.squirtles.domain.usecase.local.GetUserIdFromLocalStorageUseCase -import com.squirtles.domain.usecase.user.CreateUserUseCase +import com.squirtles.domain.firebase.FirebaseException +import com.squirtles.domain.usecase.user.GetUserIdFromLocalStorageUseCase +import com.squirtles.domain.usecase.user.CreateNewUserUseCase import com.squirtles.domain.usecase.user.FetchUserUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow @@ -24,7 +24,7 @@ sealed class LoadingState { class MainViewModel @Inject constructor( getUserIdFromLocalStorageUseCase: GetUserIdFromLocalStorageUseCase, private val fetchUserUseCase: FetchUserUseCase, - private val createUserUseCase: CreateUserUseCase + private val createNewUserUseCase: CreateNewUserUseCase ) : ViewModel() { private val _loadingState = MutableStateFlow(LoadingState.Loading) @@ -52,7 +52,7 @@ class MainViewModel @Inject constructor( } private suspend fun createUser() { - createUserUseCase() + createNewUserUseCase() .onSuccess { _loadingState.emit(LoadingState.Success(it.userId)) } diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt index 8d0a986d..d4884d0a 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt @@ -16,7 +16,7 @@ import com.squirtles.musicroad.create.SearchMusicScreen import com.squirtles.musicroad.map.MapScreen import com.squirtles.musicroad.map.MapViewModel import com.squirtles.musicroad.media.PlayerServiceViewModel -import com.squirtles.musicroad.pick.DetailPickScreen +import com.squirtles.musicroad.detail.DetailPickScreen import com.squirtles.musicroad.picklist.PickListScreen import com.squirtles.musicroad.picklist.PickListType import com.squirtles.musicroad.profile.ProfileScreen diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt b/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt index ea70aaf0..1badea5b 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt @@ -9,9 +9,9 @@ import com.naver.maps.map.CameraPosition import com.naver.maps.map.clustering.Clusterer import com.naver.maps.map.overlay.Marker import com.squirtles.domain.model.Pick -import com.squirtles.domain.usecase.local.FetchLastLocationUseCase -import com.squirtles.domain.usecase.local.GetCurrentUserUseCase -import com.squirtles.domain.usecase.local.SaveLastLocationUseCase +import com.squirtles.domain.usecase.location.GetLastLocationUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase +import com.squirtles.domain.usecase.location.SaveLastLocationUseCase import com.squirtles.domain.usecase.pick.FetchPickInAreaUseCase import com.squirtles.musicroad.map.marker.MarkerKey import dagger.hilt.android.lifecycle.HiltViewModel @@ -29,7 +29,7 @@ data class MarkerState( @HiltViewModel class MapViewModel @Inject constructor( - fetchLastLocationUseCase: FetchLastLocationUseCase, + getLastLocationUseCase: GetLastLocationUseCase, private val saveLastLocationUseCase: SaveLastLocationUseCase, private val fetchPickInAreaUseCase: FetchPickInAreaUseCase, private val getCurrentUserUseCase: GetCurrentUserUseCase @@ -53,7 +53,7 @@ class MapViewModel @Inject constructor( // LocalDataSource에 저장되는 위치 정보 // Firestore 데이터 쿼리 작업 최소화 및 위치데이터 공유 용도 - val lastLocation: StateFlow = fetchLastLocationUseCase() + val lastLocation: StateFlow = getLastLocationUseCase() fun getUserId() = getCurrentUserUseCase().userId diff --git a/app/src/main/java/com/squirtles/musicroad/map/components/PickNotificationBanner.kt b/app/src/main/java/com/squirtles/musicroad/map/components/PickNotificationBanner.kt index b8b8d38a..ed665a9d 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/components/PickNotificationBanner.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/components/PickNotificationBanner.kt @@ -12,9 +12,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -27,7 +25,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.squirtles.domain.model.Pick import com.squirtles.musicroad.R -import com.squirtles.musicroad.pick.PickViewModel.Companion.DEFAULT_PICK +import com.squirtles.musicroad.detail.DetailViewModel.Companion.DEFAULT_PICK import com.squirtles.musicroad.ui.theme.Black import com.squirtles.musicroad.ui.theme.MusicRoadTheme import com.squirtles.musicroad.ui.theme.White diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt index 55c2a51d..714fcc4b 100644 --- a/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt @@ -4,11 +4,11 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.model.Order import com.squirtles.domain.model.Pick -import com.squirtles.domain.usecase.favoritepick.FetchFavoritePicksUseCase -import com.squirtles.domain.usecase.local.GetFavoriteListOrderUseCase -import com.squirtles.domain.usecase.local.GetMyListOrderUseCase -import com.squirtles.domain.usecase.local.SaveFavoriteListOrderUseCase -import com.squirtles.domain.usecase.local.SaveMyListOrderUseCase +import com.squirtles.domain.usecase.favorite.FetchFavoritePicksUseCase +import com.squirtles.domain.usecase.order.GetFavoriteListOrderUseCase +import com.squirtles.domain.usecase.order.GetMyListOrderUseCase +import com.squirtles.domain.usecase.order.SaveFavoriteListOrderUseCase +import com.squirtles.domain.usecase.order.SaveMyListOrderUseCase import com.squirtles.domain.usecase.mypick.FetchMyPicksUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/com/squirtles/musicroad/profile/ProfileViewModel.kt b/app/src/main/java/com/squirtles/musicroad/profile/ProfileViewModel.kt index c7a519be..376c6118 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/profile/ProfileViewModel.kt @@ -3,10 +3,10 @@ package com.squirtles.musicroad.profile import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.model.User -import com.squirtles.domain.usecase.local.GetCurrentUserUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.user.FetchUserByIdUseCase import com.squirtles.domain.usecase.user.FetchUserUseCase -import com.squirtles.domain.usecase.user.UpdateUserNameUserCase +import com.squirtles.domain.usecase.user.UpdateUserNameUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -20,7 +20,7 @@ class ProfileViewModel @Inject constructor( private val getCurrentUserUseCase: GetCurrentUserUseCase, private val fetchUserUseCase: FetchUserUseCase, private val fetchUserByIdUseCase: FetchUserByIdUseCase, - private val updateUserNameUserCase: UpdateUserNameUserCase + private val updateUserNameUseCase: UpdateUserNameUseCase ) : ViewModel() { private val _profileUser = MutableStateFlow(DEFAULT_USER) @@ -45,7 +45,7 @@ class ProfileViewModel @Inject constructor( fun updateUsername(newUserName: String) { viewModelScope.launch { val result = runCatching { - updateUserNameUserCase(currentUser.userId, newUserName).getOrThrow() + updateUserNameUseCase(currentUser.userId, newUserName).getOrThrow() fetchUserUseCase(currentUser.userId).getOrThrow() } _updateSuccess.emit(result.isSuccess) diff --git a/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt b/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt index f96a13b2..d8e8ca72 100644 --- a/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt +++ b/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt @@ -5,7 +5,7 @@ import android.location.Location import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore -import com.squirtles.domain.datasource.LocalDataSource +import com.squirtles.domain.local.LocalDataSource import com.squirtles.domain.model.Order import com.squirtles.domain.model.User import kotlinx.coroutines.flow.Flow diff --git a/data/src/main/java/com/squirtles/data/datasource/remote/applemusic/AppleMusicDataSourceImpl.kt b/data/src/main/java/com/squirtles/data/datasource/remote/applemusic/AppleMusicDataSourceImpl.kt index 6e6c5c70..38d8f8f4 100644 --- a/data/src/main/java/com/squirtles/data/datasource/remote/applemusic/AppleMusicDataSourceImpl.kt +++ b/data/src/main/java/com/squirtles/data/datasource/remote/applemusic/AppleMusicDataSourceImpl.kt @@ -7,7 +7,7 @@ import com.squirtles.data.datasource.remote.applemusic.SearchSongsPagingSource.C import com.squirtles.data.datasource.remote.applemusic.api.AppleMusicApi import com.squirtles.data.datasource.remote.applemusic.model.SearchResponse import com.squirtles.data.mapper.toMusicVideo -import com.squirtles.domain.datasource.AppleMusicRemoteDataSource +import com.squirtles.domain.applemusic.AppleMusicRemoteDataSource import com.squirtles.domain.model.MusicVideo import com.squirtles.domain.model.Song import kotlinx.coroutines.flow.Flow diff --git a/data/src/main/java/com/squirtles/data/datasource/remote/firebase/FirebaseDataSourceImpl.kt b/data/src/main/java/com/squirtles/data/datasource/remote/firebase/FirebaseDataSourceImpl.kt index bbb58c72..7222d661 100644 --- a/data/src/main/java/com/squirtles/data/datasource/remote/firebase/FirebaseDataSourceImpl.kt +++ b/data/src/main/java/com/squirtles/data/datasource/remote/firebase/FirebaseDataSourceImpl.kt @@ -18,7 +18,7 @@ import com.squirtles.data.datasource.remote.firebase.model.FirebaseUser import com.squirtles.data.mapper.toFirebasePick import com.squirtles.data.mapper.toPick import com.squirtles.data.mapper.toUser -import com.squirtles.domain.datasource.FirebaseRemoteDataSource +import com.squirtles.domain.firebase.FirebaseRemoteDataSource import com.squirtles.domain.model.Pick import com.squirtles.domain.model.User import kotlinx.coroutines.CoroutineScope diff --git a/data/src/main/java/com/squirtles/data/di/DataModule.kt b/data/src/main/java/com/squirtles/data/di/DataModule.kt index 55c8d128..e3363344 100644 --- a/data/src/main/java/com/squirtles/data/di/DataModule.kt +++ b/data/src/main/java/com/squirtles/data/di/DataModule.kt @@ -9,12 +9,12 @@ import com.squirtles.data.datasource.remote.firebase.FirebaseDataSourceImpl import com.squirtles.data.repository.AppleMusicRepositoryImpl import com.squirtles.data.repository.FirebaseRepositoryImpl import com.squirtles.data.repository.LocalRepositoryImpl -import com.squirtles.domain.datasource.AppleMusicRemoteDataSource -import com.squirtles.domain.datasource.FirebaseRemoteDataSource -import com.squirtles.domain.datasource.LocalDataSource -import com.squirtles.domain.repository.AppleMusicRepository -import com.squirtles.domain.repository.FirebaseRepository -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.applemusic.AppleMusicRemoteDataSource +import com.squirtles.domain.firebase.FirebaseRemoteDataSource +import com.squirtles.domain.local.LocalDataSource +import com.squirtles.domain.applemusic.AppleMusicRepository +import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.local.LocalRepository import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/data/src/main/java/com/squirtles/data/repository/AppleMusicRepositoryImpl.kt b/data/src/main/java/com/squirtles/data/repository/AppleMusicRepositoryImpl.kt index 90b8b0fd..1b8c20a7 100644 --- a/data/src/main/java/com/squirtles/data/repository/AppleMusicRepositoryImpl.kt +++ b/data/src/main/java/com/squirtles/data/repository/AppleMusicRepositoryImpl.kt @@ -1,11 +1,11 @@ package com.squirtles.data.repository import androidx.paging.PagingData -import com.squirtles.domain.datasource.AppleMusicRemoteDataSource -import com.squirtles.domain.exception.AppleMusicException +import com.squirtles.domain.applemusic.AppleMusicRemoteDataSource +import com.squirtles.domain.applemusic.AppleMusicException import com.squirtles.domain.model.MusicVideo import com.squirtles.domain.model.Song -import com.squirtles.domain.repository.AppleMusicRepository +import com.squirtles.domain.applemusic.AppleMusicRepository import kotlinx.coroutines.flow.Flow import javax.inject.Inject diff --git a/data/src/main/java/com/squirtles/data/repository/FirebaseRepositoryImpl.kt b/data/src/main/java/com/squirtles/data/repository/FirebaseRepositoryImpl.kt index c8195352..3657257b 100644 --- a/data/src/main/java/com/squirtles/data/repository/FirebaseRepositoryImpl.kt +++ b/data/src/main/java/com/squirtles/data/repository/FirebaseRepositoryImpl.kt @@ -1,10 +1,10 @@ package com.squirtles.data.repository -import com.squirtles.domain.datasource.FirebaseRemoteDataSource -import com.squirtles.domain.exception.FirebaseException +import com.squirtles.domain.firebase.FirebaseRemoteDataSource +import com.squirtles.domain.firebase.FirebaseException import com.squirtles.domain.model.Pick import com.squirtles.domain.model.User -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject import javax.inject.Singleton diff --git a/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt b/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt index 82c3dbe9..92269e58 100644 --- a/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt +++ b/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt @@ -1,10 +1,10 @@ package com.squirtles.data.repository import android.location.Location -import com.squirtles.domain.datasource.LocalDataSource +import com.squirtles.domain.local.LocalDataSource import com.squirtles.domain.model.Order import com.squirtles.domain.model.User -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class LocalRepositoryImpl @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/exception/AppleMusicException.kt b/domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicException.kt similarity index 91% rename from domain/src/main/java/com/squirtles/domain/exception/AppleMusicException.kt rename to domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicException.kt index a70b6e94..779ea832 100644 --- a/domain/src/main/java/com/squirtles/domain/exception/AppleMusicException.kt +++ b/domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicException.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.exception +package com.squirtles.domain.applemusic /** * 400 에러가 여러 종류가 있는데 이를 구분할 용도로 만든 예외 클래스 diff --git a/domain/src/main/java/com/squirtles/domain/datasource/AppleMusicRemoteDataSource.kt b/domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicRemoteDataSource.kt similarity index 90% rename from domain/src/main/java/com/squirtles/domain/datasource/AppleMusicRemoteDataSource.kt rename to domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicRemoteDataSource.kt index 70c1db7a..752dd499 100644 --- a/domain/src/main/java/com/squirtles/domain/datasource/AppleMusicRemoteDataSource.kt +++ b/domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicRemoteDataSource.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.datasource +package com.squirtles.domain.applemusic import androidx.paging.PagingData import com.squirtles.domain.model.MusicVideo diff --git a/domain/src/main/java/com/squirtles/domain/repository/AppleMusicRepository.kt b/domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicRepository.kt similarity index 90% rename from domain/src/main/java/com/squirtles/domain/repository/AppleMusicRepository.kt rename to domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicRepository.kt index 4b5fb745..4df96e51 100644 --- a/domain/src/main/java/com/squirtles/domain/repository/AppleMusicRepository.kt +++ b/domain/src/main/java/com/squirtles/domain/applemusic/AppleMusicRepository.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.repository +package com.squirtles.domain.applemusic import androidx.paging.PagingData import com.squirtles.domain.model.MusicVideo diff --git a/domain/src/main/java/com/squirtles/domain/exception/FirebaseException.kt b/domain/src/main/java/com/squirtles/domain/firebase/FirebaseException.kt similarity index 93% rename from domain/src/main/java/com/squirtles/domain/exception/FirebaseException.kt rename to domain/src/main/java/com/squirtles/domain/firebase/FirebaseException.kt index 81679d0b..946d7310 100644 --- a/domain/src/main/java/com/squirtles/domain/exception/FirebaseException.kt +++ b/domain/src/main/java/com/squirtles/domain/firebase/FirebaseException.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.exception +package com.squirtles.domain.firebase sealed class FirebaseException(override val message: String) : Exception() { data class CreatedUserFailedException(override val message: String = "Failed to create a user") : FirebaseException(message) diff --git a/domain/src/main/java/com/squirtles/domain/datasource/FirebaseRemoteDataSource.kt b/domain/src/main/java/com/squirtles/domain/firebase/FirebaseRemoteDataSource.kt similarity index 88% rename from domain/src/main/java/com/squirtles/domain/datasource/FirebaseRemoteDataSource.kt rename to domain/src/main/java/com/squirtles/domain/firebase/FirebaseRemoteDataSource.kt index 4c4165d6..2057f5f6 100644 --- a/domain/src/main/java/com/squirtles/domain/datasource/FirebaseRemoteDataSource.kt +++ b/domain/src/main/java/com/squirtles/domain/firebase/FirebaseRemoteDataSource.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.datasource +package com.squirtles.domain.firebase import com.squirtles.domain.model.Pick import com.squirtles.domain.model.User @@ -15,7 +15,7 @@ interface FirebaseRemoteDataSource { suspend fun fetchMyPicks(userId: String): List suspend fun fetchFavoritePicks(userId: String): List - suspend fun fetchIsFavorite(pickId: String, userId: String): Boolean + suspend fun fetchIsFaㅌvorite(pickId: String, userId: String): Boolean suspend fun createFavorite(pickId: String, userId: String): Boolean suspend fun deleteFavorite(pickId: String, userId: String): Boolean // suspend fun updatePick(pick: Pick) diff --git a/domain/src/main/java/com/squirtles/domain/repository/FirebaseRepository.kt b/domain/src/main/java/com/squirtles/domain/firebase/FirebaseRepository.kt similarity index 96% rename from domain/src/main/java/com/squirtles/domain/repository/FirebaseRepository.kt rename to domain/src/main/java/com/squirtles/domain/firebase/FirebaseRepository.kt index f89f76be..1c024a73 100644 --- a/domain/src/main/java/com/squirtles/domain/repository/FirebaseRepository.kt +++ b/domain/src/main/java/com/squirtles/domain/firebase/FirebaseRepository.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.repository +package com.squirtles.domain.firebase import com.squirtles.domain.model.Pick import com.squirtles.domain.model.User diff --git a/domain/src/main/java/com/squirtles/domain/datasource/LocalDataSource.kt b/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt similarity index 94% rename from domain/src/main/java/com/squirtles/domain/datasource/LocalDataSource.kt rename to domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt index f0666713..06057420 100644 --- a/domain/src/main/java/com/squirtles/domain/datasource/LocalDataSource.kt +++ b/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.datasource +package com.squirtles.domain.local import android.location.Location import com.squirtles.domain.model.Order diff --git a/domain/src/main/java/com/squirtles/domain/repository/LocalRepository.kt b/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt similarity index 94% rename from domain/src/main/java/com/squirtles/domain/repository/LocalRepository.kt rename to domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt index f0a2900f..af9776d1 100644 --- a/domain/src/main/java/com/squirtles/domain/repository/LocalRepository.kt +++ b/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.repository +package com.squirtles.domain.local import android.location.Location import com.squirtles.domain.model.Order diff --git a/domain/src/main/java/com/squirtles/domain/usecase/favoritepick/CreateFavoriteUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/favorite/CreateFavoriteUseCase.kt similarity index 70% rename from domain/src/main/java/com/squirtles/domain/usecase/favoritepick/CreateFavoriteUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/favorite/CreateFavoriteUseCase.kt index 2977ddd2..93292a95 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/favoritepick/CreateFavoriteUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/favorite/CreateFavoriteUseCase.kt @@ -1,6 +1,6 @@ -package com.squirtles.domain.usecase.favoritepick +package com.squirtles.domain.usecase.favorite -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class CreateFavoriteUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/favoritepick/DeleteFavoriteUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt similarity index 70% rename from domain/src/main/java/com/squirtles/domain/usecase/favoritepick/DeleteFavoriteUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt index 4185b862..9cd9a63c 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/favoritepick/DeleteFavoriteUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt @@ -1,6 +1,6 @@ -package com.squirtles.domain.usecase.favoritepick +package com.squirtles.domain.usecase.favorite -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class DeleteFavoriteUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/favoritepick/FetchFavoritePicksUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt similarity index 68% rename from domain/src/main/java/com/squirtles/domain/usecase/favoritepick/FetchFavoritePicksUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt index 5d370096..9d9a7a89 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/favoritepick/FetchFavoritePicksUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt @@ -1,6 +1,6 @@ -package com.squirtles.domain.usecase.favoritepick +package com.squirtles.domain.usecase.favorite -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class FetchFavoritePicksUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/local/FetchLastLocationUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/local/FetchLastLocationUseCase.kt deleted file mode 100644 index 3267e274..00000000 --- a/domain/src/main/java/com/squirtles/domain/usecase/local/FetchLastLocationUseCase.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.squirtles.domain.usecase.local - -import com.squirtles.domain.repository.LocalRepository -import javax.inject.Inject - -class FetchLastLocationUseCase @Inject constructor( - private val localRepository: LocalRepository -) { - operator fun invoke() = localRepository.lastLocation -} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/location/GetLastLocationUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/location/GetLastLocationUseCase.kt new file mode 100644 index 00000000..d081a9d9 --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/location/GetLastLocationUseCase.kt @@ -0,0 +1,10 @@ +package com.squirtles.domain.usecase.location + +import com.squirtles.domain.local.LocalRepository +import javax.inject.Inject + +class GetLastLocationUseCase @Inject constructor( + private val localRepository: LocalRepository +) { + operator fun invoke() = localRepository.lastLocation +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/local/SaveLastLocationUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/location/SaveLastLocationUseCase.kt similarity index 73% rename from domain/src/main/java/com/squirtles/domain/usecase/local/SaveLastLocationUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/location/SaveLastLocationUseCase.kt index 8c0d4a0e..8e333af9 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/local/SaveLastLocationUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/location/SaveLastLocationUseCase.kt @@ -1,7 +1,7 @@ -package com.squirtles.domain.usecase.local +package com.squirtles.domain.usecase.location import android.location.Location -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class SaveLastLocationUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/music/FetchMusicVideoUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/music/FetchMusicVideoUseCase.kt index 0405d30d..1f42c35b 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/music/FetchMusicVideoUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/music/FetchMusicVideoUseCase.kt @@ -2,7 +2,7 @@ package com.squirtles.domain.usecase.music import com.squirtles.domain.model.MusicVideo import com.squirtles.domain.model.Song -import com.squirtles.domain.repository.AppleMusicRepository +import com.squirtles.domain.applemusic.AppleMusicRepository import javax.inject.Inject class FetchMusicVideoUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/music/SearchSongsUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/music/FetchSongsUseCase.kt similarity index 68% rename from domain/src/main/java/com/squirtles/domain/usecase/music/SearchSongsUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/music/FetchSongsUseCase.kt index 2110c21a..54370883 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/music/SearchSongsUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/music/FetchSongsUseCase.kt @@ -1,9 +1,9 @@ package com.squirtles.domain.usecase.music -import com.squirtles.domain.repository.AppleMusicRepository +import com.squirtles.domain.applemusic.AppleMusicRepository import javax.inject.Inject -class SearchSongsUseCase @Inject constructor( +class FetchSongsUseCase @Inject constructor( private val appleMusicRepository: AppleMusicRepository ) { operator fun invoke(searchText: String) = appleMusicRepository.searchSongs(searchText) diff --git a/domain/src/main/java/com/squirtles/domain/usecase/mypick/CreatePickUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/mypick/CreatePickUseCase.kt index 0e6fef0d..f0816446 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/mypick/CreatePickUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/mypick/CreatePickUseCase.kt @@ -1,7 +1,7 @@ package com.squirtles.domain.usecase.mypick import com.squirtles.domain.model.Pick -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class CreatePickUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt index 62984c36..5f087b0d 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt @@ -1,6 +1,6 @@ package com.squirtles.domain.usecase.mypick -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class DeletePickUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt index b435985a..7993d3e3 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt @@ -1,6 +1,6 @@ package com.squirtles.domain.usecase.mypick -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class FetchMyPicksUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/local/GetFavoriteListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt similarity index 67% rename from domain/src/main/java/com/squirtles/domain/usecase/local/GetFavoriteListOrderUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt index afd4e149..0e18bb53 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/local/GetFavoriteListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt @@ -1,6 +1,6 @@ -package com.squirtles.domain.usecase.local +package com.squirtles.domain.usecase.order -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class GetFavoriteListOrderUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/local/GetMyListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyListOrderUseCase.kt similarity index 65% rename from domain/src/main/java/com/squirtles/domain/usecase/local/GetMyListOrderUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/order/GetMyListOrderUseCase.kt index 53aab216..9d50998a 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/local/GetMyListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyListOrderUseCase.kt @@ -1,6 +1,6 @@ -package com.squirtles.domain.usecase.local +package com.squirtles.domain.usecase.order -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class GetMyListOrderUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/local/SaveFavoriteListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt similarity index 73% rename from domain/src/main/java/com/squirtles/domain/usecase/local/SaveFavoriteListOrderUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt index 188536bd..05cf6613 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/local/SaveFavoriteListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt @@ -1,7 +1,7 @@ -package com.squirtles.domain.usecase.local +package com.squirtles.domain.usecase.order import com.squirtles.domain.model.Order -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class SaveFavoriteListOrderUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/local/SaveMyListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyListOrderUseCase.kt similarity index 72% rename from domain/src/main/java/com/squirtles/domain/usecase/local/SaveMyListOrderUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyListOrderUseCase.kt index 2cd36e0e..6bf9359b 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/local/SaveMyListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyListOrderUseCase.kt @@ -1,7 +1,7 @@ -package com.squirtles.domain.usecase.local +package com.squirtles.domain.usecase.order import com.squirtles.domain.model.Order -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class SaveMyListOrderUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchIsFavoriteUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchIsFavoriteUseCase.kt index b9ab367b..41ff0315 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchIsFavoriteUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchIsFavoriteUseCase.kt @@ -1,6 +1,6 @@ package com.squirtles.domain.usecase.pick -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class FetchIsFavoriteUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickInAreaUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickInAreaUseCase.kt index ef403d2f..053d230e 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickInAreaUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickInAreaUseCase.kt @@ -1,6 +1,6 @@ package com.squirtles.domain.usecase.pick -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class FetchPickInAreaUseCase @Inject constructor( @@ -8,4 +8,4 @@ class FetchPickInAreaUseCase @Inject constructor( ) { suspend operator fun invoke(lat: Double, lng: Double, radiusInM: Double) = firebaseRepository.fetchPicksInArea(lat, lng, radiusInM) -} \ No newline at end of file +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickUseCase.kt index 7c770cc6..76428ca3 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickUseCase.kt @@ -1,6 +1,6 @@ package com.squirtles.domain.usecase.pick -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class FetchPickUseCase @Inject constructor( @@ -8,4 +8,4 @@ class FetchPickUseCase @Inject constructor( ) { suspend operator fun invoke(pickId: String) = firebaseRepository.fetchPick(pickId) -} \ No newline at end of file +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/CreateUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt similarity index 78% rename from domain/src/main/java/com/squirtles/domain/usecase/user/CreateUserUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt index 89eee802..b0c39ae3 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/CreateUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt @@ -1,11 +1,11 @@ package com.squirtles.domain.usecase.user import com.squirtles.domain.model.User -import com.squirtles.domain.repository.FirebaseRepository -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject -class CreateUserUseCase @Inject constructor( +class CreateNewUserUseCase @Inject constructor( private val localRepository: LocalRepository, private val firebaseRepository: FirebaseRepository ) { diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserByIdUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserByIdUseCase.kt index d1a91c89..780d551b 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserByIdUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserByIdUseCase.kt @@ -1,6 +1,6 @@ package com.squirtles.domain.usecase.user -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject class FetchUserByIdUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt index 79287e64..63ca9841 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt @@ -1,8 +1,8 @@ package com.squirtles.domain.usecase.user import com.squirtles.domain.model.User -import com.squirtles.domain.repository.FirebaseRepository -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class FetchUserUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/local/GetCurrentUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/GetCurrentUserUseCase.kt similarity index 65% rename from domain/src/main/java/com/squirtles/domain/usecase/local/GetCurrentUserUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/user/GetCurrentUserUseCase.kt index f713a2a6..e9d77326 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/local/GetCurrentUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/GetCurrentUserUseCase.kt @@ -1,6 +1,6 @@ -package com.squirtles.domain.usecase.local +package com.squirtles.domain.usecase.user -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class GetCurrentUserUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/local/GetUserIdFromLocalStorageUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromLocalStorageUseCase.kt similarity index 66% rename from domain/src/main/java/com/squirtles/domain/usecase/local/GetUserIdFromLocalStorageUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromLocalStorageUseCase.kt index 9d7da975..6d7412fe 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/local/GetUserIdFromLocalStorageUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromLocalStorageUseCase.kt @@ -1,6 +1,6 @@ -package com.squirtles.domain.usecase.local +package com.squirtles.domain.usecase.user -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class GetUserIdFromLocalStorageUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/UpdateUserNameUserCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/UpdateUserNameUseCase.kt similarity index 71% rename from domain/src/main/java/com/squirtles/domain/usecase/user/UpdateUserNameUserCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/user/UpdateUserNameUseCase.kt index bbd45c7b..a31c886b 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/UpdateUserNameUserCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/UpdateUserNameUseCase.kt @@ -1,9 +1,9 @@ package com.squirtles.domain.usecase.user -import com.squirtles.domain.repository.FirebaseRepository +import com.squirtles.domain.firebase.FirebaseRepository import javax.inject.Inject -class UpdateUserNameUserCase @Inject constructor( +class UpdateUserNameUseCase @Inject constructor( private val firebaseRepository: FirebaseRepository ) { suspend operator fun invoke(userId: String, newUserName: String) = From c69904bb486490ec6508d616c415d5970984ff48 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 5 Jan 2025 16:56:58 +0900 Subject: [PATCH 02/46] =?UTF-8?q?[refactor]=20FavoriteAction=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/squirtles/musicroad/detail/FavoriteAction.kt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/src/main/java/com/squirtles/musicroad/detail/FavoriteAction.kt diff --git a/app/src/main/java/com/squirtles/musicroad/detail/FavoriteAction.kt b/app/src/main/java/com/squirtles/musicroad/detail/FavoriteAction.kt new file mode 100644 index 00000000..8169095b --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/detail/FavoriteAction.kt @@ -0,0 +1,5 @@ +package com.squirtles.musicroad.detail + +enum class FavoriteAction { + ADDED, DELETED +} From 7a3aac39f493fa3d716967a8ee1bf13b372074a6 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 5 Jan 2025 19:36:11 +0900 Subject: [PATCH 03/46] =?UTF-8?q?[refactor]=20Search=20feature=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/search/SearchMusicScreen.kt | 341 ++++++++++++++++++ .../musicroad/search/SearchViewModel.kt | 73 ++++ 2 files changed, 414 insertions(+) create mode 100644 app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/search/SearchViewModel.kt diff --git a/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt b/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt new file mode 100644 index 00000000..b4fd25f4 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt @@ -0,0 +1,341 @@ +package com.squirtles.musicroad.search + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBars +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBars +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.ripple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.focus.FocusManager +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.paging.LoadState +import androidx.paging.compose.LazyPagingItems +import androidx.paging.compose.collectAsLazyPagingItems +import com.squirtles.domain.model.Song +import com.squirtles.musicroad.R +import com.squirtles.musicroad.common.AlbumImage +import com.squirtles.musicroad.common.Constants.COLOR_STOPS +import com.squirtles.musicroad.common.Constants.REQUEST_IMAGE_SIZE_DEFAULT +import com.squirtles.musicroad.common.HorizontalSpacer +import com.squirtles.musicroad.common.VerticalSpacer +import com.squirtles.musicroad.create.SearchUiState +import com.squirtles.musicroad.ui.theme.Gray +import com.squirtles.musicroad.ui.theme.White + +@Composable +fun SearchMusicScreen( + searchViewModel: SearchViewModel, + onBackClick: () -> Boolean, + onItemClick: () -> Unit, +) { + val focusManager = LocalFocusManager.current + val searchText by searchViewModel.searchText.collectAsStateWithLifecycle() + val searchUiState by searchViewModel.searchUiState.collectAsStateWithLifecycle() + val searchResult = searchViewModel.searchResult.collectAsLazyPagingItems() + + Scaffold( + contentWindowInsets = WindowInsets.navigationBars, + topBar = { + Box( + modifier = Modifier + .fillMaxWidth() + .padding(WindowInsets.statusBars.asPaddingValues()) + .padding(top = 16.dp) + ) { + SearchTopBar( + keyword = searchText, + onValueChange = searchViewModel::onSearchTextChange, + onBackClick = onBackClick, + focusManager = focusManager + ) + } + }, + ) { innerPadding -> + + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.verticalGradient(colorStops = COLOR_STOPS)) + .padding(innerPadding) + .addFocusCleaner(focusManager) + ) { + if (searchResult.loadState.refresh is LoadState.Loading || + searchResult.loadState.append is LoadState.Loading + ) { + LinearProgressIndicator( + modifier = Modifier + .fillMaxWidth() + .padding(top = 10.dp), + trackColor = Gray + ) + } + + // 검색 결과 + when (searchUiState) { + is SearchUiState.HotResult -> { + // TODO HOT 리스트 + } + + is SearchUiState.SearchResult -> { + SearchResult( + searchResult = searchResult, + onItemClick = { song -> + searchViewModel.onSongItemClick(song) + focusManager.clearFocus() + onItemClick() + } + ) + } + } + } + } +} + +@Composable +private fun SearchTopBar( + keyword: String, + onValueChange: (String) -> Unit, + onBackClick: () -> Boolean, + focusManager: FocusManager +) { + + Row( + modifier = Modifier + .fillMaxWidth() + .height(SearchBarHeight) + .padding(end = DefaultPadding), + verticalAlignment = Alignment.CenterVertically + ) { + IconButton( + onClick = { + onBackClick() + }, + modifier = Modifier.padding(start = 4.dp) + ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(id = R.string.top_app_bar_back_description), + tint = White + ) + } + HorizontalSpacer(8) + + OutlinedTextField( + value = keyword, + onValueChange = onValueChange, + modifier = Modifier.weight(1f), + placeholder = { + Text(stringResource(id = R.string.search)) + }, + // 키보드 완료버튼 -> Search로 변경, 누르면 Search 동작 실행 + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Text, + imeAction = ImeAction.Search + ), + keyboardActions = KeyboardActions( + onSearch = { + focusManager.clearFocus() + } + ), + singleLine = true, + shape = CircleShape, + colors = TextFieldDefaults.colors( + focusedTextColor = White, + unfocusedTextColor = White, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + cursorColor = White, + focusedIndicatorColor = White, + unfocusedIndicatorColor = White, + focusedPlaceholderColor = Gray, + unfocusedPlaceholderColor = White + ) + ) + } +} + +@Composable +private fun SearchResult( + searchResult: LazyPagingItems, + onItemClick: (Song) -> Unit +) { + Column( + modifier = Modifier.fillMaxSize() + ) { + VerticalSpacer(20) + + TextWithColorAndStyle( + text = stringResource(id = R.string.result), + textColor = White, + textStyle = MaterialTheme.typography.titleLarge, + modifier = Modifier.padding(start = DefaultPadding) + ) + VerticalSpacer(20) + + LazyColumn(modifier = Modifier.padding(bottom = DefaultPadding)) { + items(searchResult.itemCount) { index -> + searchResult[index]?.let { + SongItem(it) { + onItemClick(it) + } + } + } + } + + if (searchResult.loadState.refresh is LoadState.NotLoading) { + if (searchResult.itemCount == 0) { + Text( + text = stringResource(id = R.string.search_music_empty_description), + modifier = Modifier.padding(horizontal = DefaultPadding), + color = White + ) + } + } else if (searchResult.loadState.refresh is LoadState.Error) { + Text( + text = stringResource(id = R.string.search_music_error_description), + modifier = Modifier.padding(horizontal = DefaultPadding), + color = White + ) + } + } +} + +@Composable +private fun SongItem( + song: Song, + onItemClick: () -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = ripple(color = White), + ) { + onItemClick() + } + .padding(horizontal = DefaultPadding, vertical = ItemSpacing / 2), + verticalAlignment = Alignment.CenterVertically + ) { + AlbumImage( + imageUrl = song.getImageUrlWithSize(REQUEST_IMAGE_SIZE_DEFAULT), + modifier = Modifier + .size(ImageSize) + .clip(RoundedCornerShape(16.dp)) + ) + + HorizontalSpacer(16) + Column { + TextWithColorAndStyle( + text = song.songName, + textColor = White, + textStyle = MaterialTheme.typography.bodyLarge + ) + TextWithColorAndStyle( + text = song.artistName, + textColor = Gray, + textStyle = MaterialTheme.typography.bodyMedium + ) + TextWithColorAndStyle( + text = song.albumName, + textColor = Gray, + textStyle = MaterialTheme.typography.bodyMedium + ) + } + } +} + +@Composable +fun TextWithColorAndStyle( + text: String, + textColor: Color, + textStyle: TextStyle, + modifier: Modifier = Modifier +) { + Text( + text = text, + modifier = modifier, + color = textColor, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = textStyle + ) +} + +fun Modifier.addFocusCleaner(focusManager: FocusManager, doOnClear: () -> Unit = {}): Modifier { + return this.pointerInput(Unit) { + detectTapGestures( + onTap = { + doOnClear() + focusManager.clearFocus() + } + ) + } +} + +@Preview +@Composable +fun SongItemPreview() { + val song = Song( + id = "1", + songName = "Ditto", + artistName = "String", + albumName = "Ditto", + imageUrl = "https://i.scdn.co/image/ab67616d0000b2733d98a0ae7c78a3a9babaf8af", + genreNames = listOf(), + bgColor = android.graphics.Color.RED, + externalUrl = "", + previewUrl = "", + ) + SongItem(song) { + + } +} + +private val SearchBarHeight = 56.dp +private val DefaultPadding = 16.dp +private val ItemSpacing = 24.dp +private val ImageSize = 56.dp diff --git a/app/src/main/java/com/squirtles/musicroad/search/SearchViewModel.kt b/app/src/main/java/com/squirtles/musicroad/search/SearchViewModel.kt new file mode 100644 index 00000000..b67a4a93 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/search/SearchViewModel.kt @@ -0,0 +1,73 @@ +package com.squirtles.musicroad.search + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.paging.PagingData +import androidx.paging.cachedIn +import com.squirtles.domain.model.Song +import com.squirtles.domain.usecase.music.FetchSongsUseCase +import com.squirtles.musicroad.create.SearchUiState +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.launch +import javax.inject.Inject + +@OptIn(FlowPreview::class) +@HiltViewModel +class SearchViewModel @Inject constructor( + private val fetchSongsUseCase: FetchSongsUseCase, +) : ViewModel() { + + // SearchMusicScreen + private val _searchUiState = MutableStateFlow(SearchUiState.HotResult) + val searchUiState = _searchUiState.asStateFlow() + + private val _searchResult = MutableStateFlow>(PagingData.empty()) + val searchResult = _searchResult.asStateFlow() + + private var _selectedSong: Song? = null + val selectedSong get() = _selectedSong + + private val _searchText = MutableStateFlow("") + val searchText = _searchText.asStateFlow() + + private var searchJob: Job? = null + + init { + viewModelScope.launch { + _searchText + .debounce(300) + .collect { searchKeyword -> + searchJob?.cancel() + if (searchKeyword.isNotBlank()) { + searchJob = launch { searchSongs(searchKeyword) } + } else { + _searchUiState.emit(SearchUiState.HotResult) + } + } + } + } + + private suspend fun searchSongs(searchKeyword: String) { + fetchSongsUseCase(searchKeyword) + .cachedIn(viewModelScope) + .collectLatest { + _searchResult.emit(it) + _searchUiState.emit(SearchUiState.SearchResult) + } + } + + fun onSongItemClick(song: Song) { + _selectedSong = song + } + + fun onSearchTextChange(text: String) { + _searchText.value = text + } + +} From fe453154af118a478aff478b06346be61e41ede5 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 5 Jan 2025 19:37:08 +0900 Subject: [PATCH 04/46] =?UTF-8?q?[style]=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=20=EC=88=9C=EC=84=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/squirtles/musicroad/detail/DetailViewModel.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt index 1f1fcfa2..7a0bfb04 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt @@ -9,10 +9,10 @@ import com.squirtles.domain.model.Pick import com.squirtles.domain.model.Song import com.squirtles.domain.usecase.favorite.CreateFavoriteUseCase import com.squirtles.domain.usecase.favorite.DeleteFavoriteUseCase -import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.mypick.DeletePickUseCase import com.squirtles.domain.usecase.pick.FetchIsFavoriteUseCase import com.squirtles.domain.usecase.pick.FetchPickUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.musicroad.common.throttleFirst import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.async @@ -26,9 +26,9 @@ import javax.inject.Inject @HiltViewModel class DetailViewModel @Inject constructor( private val fetchPickUseCase: FetchPickUseCase, + private val fetchIsFavoriteUseCase: FetchIsFavoriteUseCase, private val getCurrentUserUseCase: GetCurrentUserUseCase, private val deletePickUseCase: DeletePickUseCase, - private val fetchIsFavoriteUseCase: FetchIsFavoriteUseCase, private val createFavoriteUseCase: CreateFavoriteUseCase, private val deleteFavoriteUseCase: DeleteFavoriteUseCase, ) : ViewModel() { From d0a31862cfb7f0614c9db091d6761bc3dbf9ea23 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 5 Jan 2025 19:37:33 +0900 Subject: [PATCH 05/46] =?UTF-8?q?[style]=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/squirtles/domain/firebase/FirebaseRemoteDataSource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/src/main/java/com/squirtles/domain/firebase/FirebaseRemoteDataSource.kt b/domain/src/main/java/com/squirtles/domain/firebase/FirebaseRemoteDataSource.kt index 2057f5f6..7e7f1f45 100644 --- a/domain/src/main/java/com/squirtles/domain/firebase/FirebaseRemoteDataSource.kt +++ b/domain/src/main/java/com/squirtles/domain/firebase/FirebaseRemoteDataSource.kt @@ -15,7 +15,7 @@ interface FirebaseRemoteDataSource { suspend fun fetchMyPicks(userId: String): List suspend fun fetchFavoritePicks(userId: String): List - suspend fun fetchIsFaㅌvorite(pickId: String, userId: String): Boolean + suspend fun fetchIsFavorite(pickId: String, userId: String): Boolean suspend fun createFavorite(pickId: String, userId: String): Boolean suspend fun deleteFavorite(pickId: String, userId: String): Boolean // suspend fun updatePick(pick: Pick) From d09877a3dd163d0a0a746f403b62a4e77851f974 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 5 Jan 2025 19:38:04 +0900 Subject: [PATCH 06/46] =?UTF-8?q?[refactor]=20=EC=9C=A0=EC=8A=A4=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/squirtles/musicroad/map/MapViewModel.kt | 10 +++++----- .../musicroad/picklist/PickListViewModel.kt | 14 +++++++------- ...rderUseCase.kt => GetMyPickListOrderUseCase.kt} | 2 +- ...derUseCase.kt => SaveMyPickListOrderUseCase.kt} | 4 ++-- .../domain/usecase/pick/FetchPickUseCase.kt | 3 +++ .../domain/usecase/user/FetchUserUseCase.kt | 7 +++---- 6 files changed, 21 insertions(+), 19 deletions(-) rename domain/src/main/java/com/squirtles/domain/usecase/order/{GetMyListOrderUseCase.kt => GetMyPickListOrderUseCase.kt} (81%) rename domain/src/main/java/com/squirtles/domain/usecase/order/{SaveMyListOrderUseCase.kt => SaveMyPickListOrderUseCase.kt} (84%) diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt b/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt index 1badea5b..c5c70165 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt @@ -10,9 +10,9 @@ import com.naver.maps.map.clustering.Clusterer import com.naver.maps.map.overlay.Marker import com.squirtles.domain.model.Pick import com.squirtles.domain.usecase.location.GetLastLocationUseCase -import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.location.SaveLastLocationUseCase -import com.squirtles.domain.usecase.pick.FetchPickInAreaUseCase +import com.squirtles.domain.usecase.pick.FetchPickUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.musicroad.map.marker.MarkerKey import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow @@ -31,7 +31,7 @@ data class MarkerState( class MapViewModel @Inject constructor( getLastLocationUseCase: GetLastLocationUseCase, private val saveLastLocationUseCase: SaveLastLocationUseCase, - private val fetchPickInAreaUseCase: FetchPickInAreaUseCase, + private val fetchPickUseCase: FetchPickUseCase, private val getCurrentUserUseCase: GetCurrentUserUseCase ) : ViewModel() { @@ -136,7 +136,7 @@ class MapViewModel @Inject constructor( (leftTop.longitude + rightBottom.longitude) / 2 ) val radiusInM = leftTop.distanceTo(rightBottom) - val fetchPicks = fetchPickInAreaUseCase(center.latitude, center.longitude, radiusInM) + val fetchPicks = fetchPickUseCase(center.latitude, center.longitude, radiusInM) fetchPicks.onSuccess { pickList -> val newKeyTagMap: MutableMap = mutableMapOf() @@ -163,7 +163,7 @@ class MapViewModel @Inject constructor( fun requestPickNotificationArea(location: Location, notiRadius: Double) { viewModelScope.launch { - fetchPickInAreaUseCase(location.latitude, location.longitude, notiRadius) + fetchPickUseCase(location.latitude, location.longitude, notiRadius) .onSuccess { _nearPicks.emit(it) }.onFailure { diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt index 714fcc4b..05e62320 100644 --- a/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt @@ -5,11 +5,11 @@ import androidx.lifecycle.viewModelScope import com.squirtles.domain.model.Order import com.squirtles.domain.model.Pick import com.squirtles.domain.usecase.favorite.FetchFavoritePicksUseCase +import com.squirtles.domain.usecase.mypick.FetchMyPicksUseCase import com.squirtles.domain.usecase.order.GetFavoriteListOrderUseCase -import com.squirtles.domain.usecase.order.GetMyListOrderUseCase +import com.squirtles.domain.usecase.order.GetMyPickListOrderUseCase import com.squirtles.domain.usecase.order.SaveFavoriteListOrderUseCase -import com.squirtles.domain.usecase.order.SaveMyListOrderUseCase -import com.squirtles.domain.usecase.mypick.FetchMyPicksUseCase +import com.squirtles.domain.usecase.order.SaveMyPickListOrderUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -21,9 +21,9 @@ class PickListViewModel @Inject constructor( private val fetchFavoritePicksUseCase: FetchFavoritePicksUseCase, private val fetchMyPicksUseCase: FetchMyPicksUseCase, private val getFavoriteListOrderUseCase: GetFavoriteListOrderUseCase, - private val getMyListOrderUseCase: GetMyListOrderUseCase, + private val getMyPickListOrderUseCase: GetMyPickListOrderUseCase, private val saveFavoriteListOrderUseCase: SaveFavoriteListOrderUseCase, - private val saveMyListOrderUseCase: SaveMyListOrderUseCase, + private val saveMyPickListOrderUseCase: SaveMyPickListOrderUseCase, ) : ViewModel() { private var defaultList: List? = null @@ -49,7 +49,7 @@ class PickListViewModel @Inject constructor( fetchMyPicksUseCase(userId) .onSuccess { myPicks -> defaultList = myPicks - setList(getMyListOrderUseCase()) + setList(getMyPickListOrderUseCase()) } .onFailure { _pickListUiState.emit(PickListUiState.Error) @@ -61,7 +61,7 @@ class PickListViewModel @Inject constructor( viewModelScope.launch { when (type) { PickListType.FAVORITE -> saveFavoriteListOrderUseCase(order) - PickListType.CREATED -> saveMyListOrderUseCase(order) + PickListType.CREATED -> saveMyPickListOrderUseCase(order) } setList(order) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt similarity index 81% rename from domain/src/main/java/com/squirtles/domain/usecase/order/GetMyListOrderUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt index 9d50998a..d24a3001 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt @@ -3,7 +3,7 @@ package com.squirtles.domain.usecase.order import com.squirtles.domain.local.LocalRepository import javax.inject.Inject -class GetMyListOrderUseCase @Inject constructor( +class GetMyPickListOrderUseCase @Inject constructor( private val localRepository: LocalRepository ) { operator fun invoke() = localRepository.myListOrder diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt similarity index 84% rename from domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyListOrderUseCase.kt rename to domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt index 6bf9359b..712104f4 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt @@ -1,10 +1,10 @@ package com.squirtles.domain.usecase.order -import com.squirtles.domain.model.Order import com.squirtles.domain.local.LocalRepository +import com.squirtles.domain.model.Order import javax.inject.Inject -class SaveMyListOrderUseCase @Inject constructor( +class SaveMyPickListOrderUseCase @Inject constructor( private val localRepository: LocalRepository ) { suspend operator fun invoke(order: Order) = localRepository.saveMyListOrder(order) diff --git a/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickUseCase.kt index 76428ca3..37c7e62b 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/pick/FetchPickUseCase.kt @@ -8,4 +8,7 @@ class FetchPickUseCase @Inject constructor( ) { suspend operator fun invoke(pickId: String) = firebaseRepository.fetchPick(pickId) + + suspend operator fun invoke(lat: Double, lng: Double, radiusInM: Double) = + firebaseRepository.fetchPicksInArea(lat, lng, radiusInM) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt index 63ca9841..b9ab974b 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt @@ -1,17 +1,16 @@ package com.squirtles.domain.usecase.user -import com.squirtles.domain.model.User -import com.squirtles.domain.firebase.FirebaseRepository import com.squirtles.domain.local.LocalRepository +import com.squirtles.domain.model.User import javax.inject.Inject class FetchUserUseCase @Inject constructor( private val localRepository: LocalRepository, - private val firebaseRepository: FirebaseRepository + private val fetchUserByIdUseCase: FetchUserByIdUseCase ) { suspend operator fun invoke(userId: String): Result { // userId가 있으면 Firestore에서 유저 가져오기 - val user = firebaseRepository.fetchUser(userId) + val user = fetchUserByIdUseCase(userId) .onSuccess { user -> localRepository.saveCurrentUser(user) } From 362e1df656cfa1eb2ecb2d5b765b1c10d72932d9 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 5 Jan 2025 20:39:51 +0900 Subject: [PATCH 07/46] =?UTF-8?q?[refactor]=20Navigation=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 4 ++++ .../squirtles/musicroad/navigation/MainRoute.kt | 15 +++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 05a54221..4e08a714 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,6 +14,7 @@ plugins { alias(libs.plugins.ksp) alias(libs.plugins.hilt) alias(libs.plugins.google.services) + alias(libs.plugins.kotlin.serialization) } android { @@ -148,4 +149,7 @@ dependencies { // Paging implementation(libs.androidx.paging.runtime) implementation(libs.androidx.paging.compose.android) + + // Serialization + implementation(libs.kotlinx.serialization.json) } diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt new file mode 100644 index 00000000..ada11c33 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt @@ -0,0 +1,15 @@ +package com.squirtles.musicroad.navigation + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface MainRoute { + @Serializable + data object Search : MainRoute + + @Serializable + data class PickDetail(val pickId: String) : MainRoute + + @Serializable + data object Profile : MainRoute +} From cc5a67fa1c7a74c2b6eda98dfee867d37fea71ac Mon Sep 17 00:00:00 2001 From: miller198 Date: Tue, 7 Jan 2025 19:12:53 +0900 Subject: [PATCH 08/46] =?UTF-8?q?[refactor]=20Navigation=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit picklist -> favorite/mypick 으로 패키지 분리 --- .../musicroad/common/picklist/Extension.kt | 17 ++ .../common/picklist/OrderBottomSheet.kt | 135 +++++++++++ .../musicroad/common/picklist/PickListItem.kt | 107 +++++++++ .../common/picklist/PickListScreen.kt | 210 ++++++++++++++++++ .../musicroad/common/picklist/PickListType.kt | 5 + .../common/picklist/PickListUiState.kt | 10 + .../create/navigation/CreateNavigation.kt | 1 + .../detail/navigation/DetailNavigation.kt | 1 + .../favorite/FavoriteListViewModel.kt | 53 +++++ .../musicroad/favorite/FavoriteScreen.kt | 37 +++ .../favorite/navigation/FavoriteNavigation.kt | 3 + .../main/navigations/MainNavGraph.kt | 6 +- .../musicroad/map/navigation/MapNavigation.kt | 2 + .../musicroad/mypick/MyPickListViewModel.kt | 53 +++++ .../musicroad/mypick/MyPickScreen.kt | 37 +++ .../musicroad/navigation/DetailRoute.kt | 9 + .../musicroad/navigation/MainRoute.kt | 2 +- .../musicroad/navigation/ProfileRoute.kt | 10 + .../squirtles/musicroad/navigation/Route.kt | 9 + .../musicroad/navigation/SearchRoute.kt | 10 + .../profile/{ => components}/MenuItem.kt | 2 +- .../profile/{ => components}/ProfileMenus.kt | 2 +- .../profile/navigation/ProfileNavigation.kt | 4 + .../profile/{ => screen}/ProfileScreen.kt | 6 +- .../screen}/SettingNotificationScreen.kt | 2 +- .../screen}/SettingProfileScreen.kt | 2 +- .../search/navigation/SearchNavigation.kt | 5 + 27 files changed, 730 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/Extension.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/OrderBottomSheet.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreen.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/PickListType.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/PickListUiState.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/create/navigation/CreateNavigation.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/detail/navigation/DetailNavigation.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/favorite/navigation/FavoriteNavigation.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/DetailRoute.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/Route.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt rename app/src/main/java/com/squirtles/musicroad/profile/{ => components}/MenuItem.kt (86%) rename app/src/main/java/com/squirtles/musicroad/profile/{ => components}/ProfileMenus.kt (98%) create mode 100644 app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt rename app/src/main/java/com/squirtles/musicroad/profile/{ => screen}/ProfileScreen.kt (96%) rename app/src/main/java/com/squirtles/musicroad/{setting => profile/screen}/SettingNotificationScreen.kt (97%) rename app/src/main/java/com/squirtles/musicroad/{setting => profile/screen}/SettingProfileScreen.kt (99%) create mode 100644 app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/Extension.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/Extension.kt new file mode 100644 index 00000000..53bac7f1 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/Extension.kt @@ -0,0 +1,17 @@ +package com.squirtles.musicroad.common.picklist + +import com.squirtles.domain.model.Order +import com.squirtles.domain.model.Pick + +fun List.setOrderedList(order: Order): PickListUiState.Success { + return PickListUiState.Success( + pickList = when (order) { + Order.LATEST -> this + + Order.OLDEST -> this.reversed() + + Order.FAVORITE_DESC -> this.sortedByDescending { it.favoriteCount } + }, + order = order + ) +} diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/OrderBottomSheet.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/OrderBottomSheet.kt new file mode 100644 index 00000000..e59868a0 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/OrderBottomSheet.kt @@ -0,0 +1,135 @@ +package com.squirtles.musicroad.common.picklist + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.displayCutoutPadding +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Check +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import com.squirtles.domain.model.Order +import com.squirtles.musicroad.R +import com.squirtles.musicroad.common.Constants.DEFAULT_PADDING +import com.squirtles.musicroad.ui.theme.Dark +import com.squirtles.musicroad.ui.theme.Primary +import com.squirtles.musicroad.ui.theme.White +import kotlinx.coroutines.launch + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun OrderBottomSheet( + isFavoritePicks: Boolean, + currentOrder: Order, + onDismissRequest: () -> Unit, + onOrderClick: (Order) -> Unit, +) { + val sheetState = rememberModalBottomSheetState() + val scope = rememberCoroutineScope() + val orderList = listOf( + stringResource(if (isFavoritePicks) R.string.latest_favorite_order else R.string.latest_create_order) to Order.LATEST, + stringResource(if (isFavoritePicks) R.string.oldest_favorite_order else R.string.oldest_create_order) to Order.OLDEST, + stringResource(R.string.favorite_count_desc) to Order.FAVORITE_DESC, + ) + + ModalBottomSheet( + onDismissRequest = onDismissRequest, + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .displayCutoutPadding() + .navigationBarsPadding(), + sheetState = sheetState, + containerColor = Dark, + scrimColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.32f), + ) { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + orderList.forEach { (orderText, order) -> + BottomSheetMenu( + text = orderText, + isSelected = currentOrder == order, + ) { + scope + .launch { + if (currentOrder != order) { + onOrderClick(order) + } + sheetState.hide() + } + .invokeOnCompletion { + if (!sheetState.isVisible) { + onDismissRequest() + } + } + } + } + + HorizontalDivider(color = White) + BottomSheetMenu( + text = stringResource(R.string.close_button_text), + textAlign = TextAlign.Center, + ) { + scope + .launch { sheetState.hide() } + .invokeOnCompletion { + if (!sheetState.isVisible) { + onDismissRequest() + } + } + } + } + } +} + +@Composable +private fun BottomSheetMenu( + text: String, + textAlign: TextAlign = TextAlign.Start, + isSelected: Boolean = false, + onClick: () -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { onClick() } + .padding(DEFAULT_PADDING), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = text, + modifier = Modifier.weight(1f), + color = if (isSelected) Primary else White, + fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal, + textAlign = textAlign, + ) + + if (isSelected) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = stringResource(R.string.selected_icon_description), + tint = Primary + ) + } + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt new file mode 100644 index 00000000..6920dd2d --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt @@ -0,0 +1,107 @@ +package com.squirtles.musicroad.common.picklist + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.ripple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import com.squirtles.domain.model.Song +import com.squirtles.musicroad.common.AlbumImage +import com.squirtles.musicroad.common.CommentText +import com.squirtles.musicroad.common.Constants +import com.squirtles.musicroad.common.CreatedByOtherUserText +import com.squirtles.musicroad.common.FavoriteCountText +import com.squirtles.musicroad.common.HorizontalSpacer +import com.squirtles.musicroad.common.SongInfoText +import com.squirtles.musicroad.ui.theme.Gray +import com.squirtles.musicroad.ui.theme.White + +@Composable +fun PickListItem( + song: Song, + isCreatedByOthers: Boolean, + createUserName: String, + favoriteCount: Int, + comment: String, + createdAt: String, + onItemClick: () -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = ripple(color = White), + ) { onItemClick() } + .padding( + horizontal = Constants.DEFAULT_PADDING, + vertical = Constants.DEFAULT_PADDING / 2 + ), + horizontalArrangement = Arrangement.spacedBy(Constants.DEFAULT_PADDING), + verticalAlignment = Alignment.CenterVertically + ) { + AlbumImage( + imageUrl = song.getImageUrlWithSize(Constants.REQUEST_IMAGE_SIZE_DEFAULT), + modifier = Modifier + .size(64.dp) + .clip(RoundedCornerShape(8.dp)) + ) + + Column( + modifier = Modifier.weight(1f) + ) { + SongInfoText( + songInfo = "${song.songName} - ${song.artistName}", + color = White + ) + + Row( + verticalAlignment = Alignment.CenterVertically + ) { + if (isCreatedByOthers) { + CreatedByOtherUserText( + userName = createUserName, + modifier = Modifier.weight(weight = 1f, fill = false), + color = Gray + ) + } else { + Text( + text = createdAt, + modifier = Modifier.weight(weight = 1f, fill = false), + color = Gray, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = MaterialTheme.typography.bodyMedium, + ) + } + + HorizontalSpacer(8) + + FavoriteCountText( + favoriteCount = favoriteCount, + iconTint = Gray, + color = Gray + ) + } + + CommentText( + comment = comment, + color = Gray + ) + } + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreen.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreen.kt new file mode 100644 index 00000000..699ebbe0 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreen.kt @@ -0,0 +1,210 @@ +package com.squirtles.musicroad.common.picklist + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.displayCutoutPadding +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.CircularProgressIndicator +import com.squirtles.domain.model.Order +import com.squirtles.musicroad.R +import com.squirtles.musicroad.common.Constants.COLOR_STOPS +import com.squirtles.musicroad.common.Constants.DEFAULT_PADDING +import com.squirtles.musicroad.common.DefaultTopAppBar +import com.squirtles.musicroad.common.TotalCountText +import com.squirtles.musicroad.common.VerticalSpacer +import com.squirtles.musicroad.ui.theme.Primary +import com.squirtles.musicroad.ui.theme.White + +@Composable +fun PickListScreen( + showOrderBottomSheet: Boolean, + pickListType: PickListType, + uiState: PickListUiState, + onBackClick: () -> Unit, + onItemClick: (String) -> Unit, + setListOrder: (Order) -> Unit, + setOrderBottomSheetVisibility: (Boolean) -> Unit +) { + val isLandscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE + + Scaffold( + topBar = { + DefaultTopAppBar( + title = stringResource( + when (pickListType) { + PickListType.FAVORITE -> R.string.favorite_picks_top_app_bar_title + PickListType.CREATED -> R.string.my_picks_top_app_bar_title + } + ), + onBackClick = onBackClick + ) + }, + ) { innerPadding -> + Box( + modifier = Modifier + .fillMaxSize() + .background(Brush.verticalGradient(colorStops = COLOR_STOPS)) + .padding(innerPadding) + .then(if (isLandscape) Modifier.displayCutoutPadding() else Modifier) + ) { + when (uiState) { + PickListUiState.Loading -> { + CircularProgressIndicator( + modifier = Modifier + .size(36.dp) + .align(Alignment.Center), + indicatorColor = Primary + ) + } + + is PickListUiState.Success -> { + val pickList = uiState.pickList + val order = uiState.order + + Column( + modifier = Modifier.fillMaxSize() + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = DEFAULT_PADDING), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + TotalCountText( + totalCount = pickList.size, + defaultColor = White, + ) + + Box( + modifier = Modifier + .wrapContentSize() + .clip(CircleShape) + .clickable { setOrderBottomSheetVisibility(true) } + ) { + Text( + text = getOrderString( + pickListType = pickListType, + order = order + ), + modifier = Modifier.padding( + horizontal = DEFAULT_PADDING / 2, + vertical = DEFAULT_PADDING / 4 + ), + color = White, + style = MaterialTheme.typography.bodyMedium + ) + } + } + + VerticalSpacer(8) + + if (pickList.isEmpty()) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Text( + text = stringResource( + when (pickListType) { + PickListType.FAVORITE -> R.string.favorite_picks_empty + PickListType.CREATED -> R.string.my_picks_empty + } + ), + color = White, + style = MaterialTheme.typography.titleMedium + ) + } + } else { + LazyColumn( + modifier = Modifier.weight(1f) + ) { + items( + items = pickList, + key = { it.id } + ) { pick -> + PickListItem( + song = pick.song, + isCreatedByOthers = pickListType == PickListType.FAVORITE, + createUserName = pick.createdBy.userName, + favoriteCount = pick.favoriteCount, + comment = pick.comment, + createdAt = pick.createdAt, + onItemClick = { onItemClick(pick.id) } + ) + } + } + } + } + } + + PickListUiState.Error -> { + Text( + text = stringResource(R.string.error_loading_pick_list), + modifier = Modifier.align(Alignment.Center), + color = White, + style = MaterialTheme.typography.bodyLarge + ) + // TODO: 다시하기 버튼 같은 거 만들어서 요청 다시 하게 할 수 있도록 만드는 것도 고려해보기 + } + } + } + } + + if (showOrderBottomSheet) { + OrderBottomSheet( + isFavoritePicks = pickListType == PickListType.FAVORITE, + currentOrder = (uiState as PickListUiState.Success).order, + onDismissRequest = { setOrderBottomSheetVisibility(false) }, + onOrderClick = { order -> + setListOrder(order) + }, + ) + } +} + +@Composable +private fun getOrderString(pickListType: PickListType, order: Order): String { + return "${ + stringResource( + when (order) { + Order.LATEST -> + when (pickListType) { + PickListType.FAVORITE -> R.string.latest_favorite_order + PickListType.CREATED -> R.string.latest_create_order + } + + Order.OLDEST -> + when (pickListType) { + PickListType.FAVORITE -> R.string.oldest_favorite_order + PickListType.CREATED -> R.string.oldest_create_order + } + + Order.FAVORITE_DESC -> R.string.favorite_count_desc + } + ) + } ▼" +} diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListType.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListType.kt new file mode 100644 index 00000000..e357f48e --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListType.kt @@ -0,0 +1,5 @@ +package com.squirtles.musicroad.common.picklist + +enum class PickListType { + FAVORITE, CREATED +} diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListUiState.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListUiState.kt new file mode 100644 index 00000000..f0df5a8c --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListUiState.kt @@ -0,0 +1,10 @@ +package com.squirtles.musicroad.common.picklist + +import com.squirtles.domain.model.Order +import com.squirtles.domain.model.Pick + +sealed class PickListUiState { + data object Loading : PickListUiState() + data class Success(val pickList: List, val order: Order) : PickListUiState() + data object Error : PickListUiState() +} diff --git a/app/src/main/java/com/squirtles/musicroad/create/navigation/CreateNavigation.kt b/app/src/main/java/com/squirtles/musicroad/create/navigation/CreateNavigation.kt new file mode 100644 index 00000000..a7f70d1a --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/create/navigation/CreateNavigation.kt @@ -0,0 +1 @@ +package com.squirtles.musicroad.create.navigation diff --git a/app/src/main/java/com/squirtles/musicroad/detail/navigation/DetailNavigation.kt b/app/src/main/java/com/squirtles/musicroad/detail/navigation/DetailNavigation.kt new file mode 100644 index 00000000..4c59e66b --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/detail/navigation/DetailNavigation.kt @@ -0,0 +1 @@ +package com.squirtles.musicroad.detail.navigation diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt new file mode 100644 index 00000000..d424abc4 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt @@ -0,0 +1,53 @@ +package com.squirtles.musicroad.favorite + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.squirtles.domain.model.Order +import com.squirtles.domain.model.Pick +import com.squirtles.domain.usecase.favorite.FetchFavoritePicksUseCase +import com.squirtles.domain.usecase.order.GetFavoriteListOrderUseCase +import com.squirtles.domain.usecase.order.SaveFavoriteListOrderUseCase +import com.squirtles.musicroad.common.picklist.PickListUiState +import com.squirtles.musicroad.common.picklist.setOrderedList +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class FavoriteListViewModel @Inject constructor( + private val fetchFavoritePicksUseCase: FetchFavoritePicksUseCase, + private val getFavoriteListOrderUseCase: GetFavoriteListOrderUseCase, + private val saveFavoriteListOrderUseCase: SaveFavoriteListOrderUseCase, +) : ViewModel() { + + private var favoriteList: List = emptyList() + + private val _pickListUiState = MutableStateFlow(PickListUiState.Loading) + val pickListUiState = _pickListUiState.asStateFlow() + + fun fetchFavoritePicks(userId: String) { + viewModelScope.launch { + fetchFavoritePicksUseCase(userId) + .onSuccess { favoritePicks -> + favoriteList = favoritePicks + setList(getFavoriteListOrderUseCase()) + } + .onFailure { + _pickListUiState.emit(PickListUiState.Error) + } + } + } + + fun setListOrder(order: Order) { + viewModelScope.launch { + saveFavoriteListOrderUseCase(order) + setList(order) + } + } + + private fun setList(order: Order) { + _pickListUiState.value = favoriteList.setOrderedList(order) + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt new file mode 100644 index 00000000..eec7bc2c --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt @@ -0,0 +1,37 @@ +package com.squirtles.musicroad.favorite + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.squirtles.musicroad.common.picklist.PickListScreen +import com.squirtles.musicroad.common.picklist.PickListType + +@Composable +fun FavoriteScreen( + userId: String, + onBackClick: () -> Unit, + onItemClick: (String) -> Unit, + favoriteListViewModel: FavoriteListViewModel = hiltViewModel() +) { + val uiState by favoriteListViewModel.pickListUiState.collectAsStateWithLifecycle() + var showOrderBottomSheet by rememberSaveable { mutableStateOf(false) } + + LaunchedEffect(Unit) { + favoriteListViewModel.fetchFavoritePicks(userId) + } + + PickListScreen( + showOrderBottomSheet = showOrderBottomSheet, + pickListType = PickListType.FAVORITE, + uiState = uiState, + onBackClick = onBackClick, + onItemClick = onItemClick, + setListOrder = favoriteListViewModel::setListOrder, + setOrderBottomSheetVisibility = { showOrderBottomSheet = it }, + ) +} diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/navigation/FavoriteNavigation.kt b/app/src/main/java/com/squirtles/musicroad/favorite/navigation/FavoriteNavigation.kt new file mode 100644 index 00000000..51c89a35 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/favorite/navigation/FavoriteNavigation.kt @@ -0,0 +1,3 @@ +package com.squirtles.musicroad.favorite.navigation + + diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt index d4884d0a..f4e76c0d 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt @@ -19,9 +19,9 @@ import com.squirtles.musicroad.media.PlayerServiceViewModel import com.squirtles.musicroad.detail.DetailPickScreen import com.squirtles.musicroad.picklist.PickListScreen import com.squirtles.musicroad.picklist.PickListType -import com.squirtles.musicroad.profile.ProfileScreen -import com.squirtles.musicroad.setting.SettingNotificationScreen -import com.squirtles.musicroad.setting.SettingProfileScreen +import com.squirtles.musicroad.profile.screen.ProfileScreen +import com.squirtles.musicroad.profile.screen.SettingNotificationScreen +import com.squirtles.musicroad.profile.screen.SettingProfileScreen @Composable fun MainNavGraph( diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt new file mode 100644 index 00000000..6b4d544d --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt @@ -0,0 +1,2 @@ +package com.squirtles.musicroad.map.navigation + diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt new file mode 100644 index 00000000..49048741 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt @@ -0,0 +1,53 @@ +package com.squirtles.musicroad.mypick + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.squirtles.domain.model.Order +import com.squirtles.domain.model.Pick +import com.squirtles.domain.usecase.mypick.FetchMyPicksUseCase +import com.squirtles.domain.usecase.order.GetMyPickListOrderUseCase +import com.squirtles.domain.usecase.order.SaveMyPickListOrderUseCase +import com.squirtles.musicroad.common.picklist.PickListUiState +import com.squirtles.musicroad.common.picklist.setOrderedList +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class MyPickListViewModel @Inject constructor( + private val fetchMyPicksUseCase: FetchMyPicksUseCase, + private val getMyPickListOrderUseCase: GetMyPickListOrderUseCase, + private val saveMyPickListOrderUseCase: SaveMyPickListOrderUseCase, +) : ViewModel() { + + private var myPickList: List = emptyList() + + private val _pickListUiState = MutableStateFlow(PickListUiState.Loading) + val pickListUiState = _pickListUiState.asStateFlow() + + fun fetchMyPicks(userId: String) { + viewModelScope.launch { + fetchMyPicksUseCase(userId) + .onSuccess { myPicks -> + myPickList = myPicks + setList(getMyPickListOrderUseCase()) + } + .onFailure { + _pickListUiState.emit(PickListUiState.Error) + } + } + } + + fun setListOrder(order: Order) { + viewModelScope.launch { + saveMyPickListOrderUseCase(order) + setList(order) + } + } + + private fun setList(order: Order) { + _pickListUiState.value = myPickList.setOrderedList(order) + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt new file mode 100644 index 00000000..6b6fe42f --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt @@ -0,0 +1,37 @@ +package com.squirtles.musicroad.mypick + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.squirtles.musicroad.common.picklist.PickListScreen +import com.squirtles.musicroad.common.picklist.PickListType + +@Composable +fun MyPickScreen( + userId: String, + onBackClick: () -> Unit, + onItemClick: (String) -> Unit, + myPickListViewModel: MyPickListViewModel = hiltViewModel() +) { + val uiState by myPickListViewModel.pickListUiState.collectAsStateWithLifecycle() + var showOrderBottomSheet by rememberSaveable { mutableStateOf(false) } + + LaunchedEffect(Unit) { + myPickListViewModel.fetchMyPicks(userId) + } + + PickListScreen( + showOrderBottomSheet = showOrderBottomSheet, + pickListType = PickListType.FAVORITE, + uiState = uiState, + onBackClick = onBackClick, + onItemClick = onItemClick, + setListOrder = myPickListViewModel::setListOrder, + setOrderBottomSheetVisibility = { showOrderBottomSheet = it }, + ) +} diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/DetailRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/DetailRoute.kt new file mode 100644 index 00000000..4485708e --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/navigation/DetailRoute.kt @@ -0,0 +1,9 @@ +package com.squirtles.musicroad.navigation + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface DetailRoute : Route { + @Serializable + data object Setting : DetailRoute +} diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt index ada11c33..bdb2fff3 100644 --- a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt +++ b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt @@ -3,7 +3,7 @@ package com.squirtles.musicroad.navigation import kotlinx.serialization.Serializable @Serializable -sealed interface MainRoute { +sealed interface MainRoute : Route { @Serializable data object Search : MainRoute diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt new file mode 100644 index 00000000..2fca42c3 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt @@ -0,0 +1,10 @@ +package com.squirtles.musicroad.navigation + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface ProfileRoute : Route { + @Serializable + data object Setting : ProfileRoute +} + diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/Route.kt b/app/src/main/java/com/squirtles/musicroad/navigation/Route.kt new file mode 100644 index 00000000..ea896a82 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/navigation/Route.kt @@ -0,0 +1,9 @@ +package com.squirtles.musicroad.navigation + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface Route { + @Serializable + data object Auth : Route +} diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt new file mode 100644 index 00000000..7760b52c --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt @@ -0,0 +1,10 @@ +package com.squirtles.musicroad.navigation + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface SearchRoute : Route { + @Serializable + data object Create : SearchRoute +} + diff --git a/app/src/main/java/com/squirtles/musicroad/profile/MenuItem.kt b/app/src/main/java/com/squirtles/musicroad/profile/components/MenuItem.kt similarity index 86% rename from app/src/main/java/com/squirtles/musicroad/profile/MenuItem.kt rename to app/src/main/java/com/squirtles/musicroad/profile/components/MenuItem.kt index a37617d9..a883d509 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/MenuItem.kt +++ b/app/src/main/java/com/squirtles/musicroad/profile/components/MenuItem.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.profile +package com.squirtles.musicroad.profile.components import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector diff --git a/app/src/main/java/com/squirtles/musicroad/profile/ProfileMenus.kt b/app/src/main/java/com/squirtles/musicroad/profile/components/ProfileMenus.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/profile/ProfileMenus.kt rename to app/src/main/java/com/squirtles/musicroad/profile/components/ProfileMenus.kt index 3ef7a37d..7c145454 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/ProfileMenus.kt +++ b/app/src/main/java/com/squirtles/musicroad/profile/components/ProfileMenus.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.profile +package com.squirtles.musicroad.profile.components import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource diff --git a/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt b/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt new file mode 100644 index 00000000..da69f59f --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt @@ -0,0 +1,4 @@ +package com.squirtles.musicroad.profile.navigation + +class ProfileNavigation { +} diff --git a/app/src/main/java/com/squirtles/musicroad/profile/ProfileScreen.kt b/app/src/main/java/com/squirtles/musicroad/profile/screen/ProfileScreen.kt similarity index 96% rename from app/src/main/java/com/squirtles/musicroad/profile/ProfileScreen.kt rename to app/src/main/java/com/squirtles/musicroad/profile/screen/ProfileScreen.kt index fece167e..b592a464 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/ProfileScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/profile/screen/ProfileScreen.kt @@ -1,11 +1,10 @@ -package com.squirtles.musicroad.profile +package com.squirtles.musicroad.profile.screen import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentWidth @@ -41,6 +40,9 @@ import com.squirtles.musicroad.common.Constants.COLOR_STOPS import com.squirtles.musicroad.common.DefaultTopAppBar import com.squirtles.musicroad.common.HorizontalSpacer import com.squirtles.musicroad.common.VerticalSpacer +import com.squirtles.musicroad.profile.ProfileViewModel +import com.squirtles.musicroad.profile.components.MenuItem +import com.squirtles.musicroad.profile.components.ProfileMenus import com.squirtles.musicroad.ui.theme.Primary import com.squirtles.musicroad.ui.theme.White diff --git a/app/src/main/java/com/squirtles/musicroad/setting/SettingNotificationScreen.kt b/app/src/main/java/com/squirtles/musicroad/profile/screen/SettingNotificationScreen.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/setting/SettingNotificationScreen.kt rename to app/src/main/java/com/squirtles/musicroad/profile/screen/SettingNotificationScreen.kt index 18880510..5e2eeca5 100644 --- a/app/src/main/java/com/squirtles/musicroad/setting/SettingNotificationScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/profile/screen/SettingNotificationScreen.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.setting +package com.squirtles.musicroad.profile.screen import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box diff --git a/app/src/main/java/com/squirtles/musicroad/setting/SettingProfileScreen.kt b/app/src/main/java/com/squirtles/musicroad/profile/screen/SettingProfileScreen.kt similarity index 99% rename from app/src/main/java/com/squirtles/musicroad/setting/SettingProfileScreen.kt rename to app/src/main/java/com/squirtles/musicroad/profile/screen/SettingProfileScreen.kt index c487dd40..a4d7d14d 100644 --- a/app/src/main/java/com/squirtles/musicroad/setting/SettingProfileScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/profile/screen/SettingProfileScreen.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.setting +package com.squirtles.musicroad.profile.screen import android.content.Context import android.widget.Toast diff --git a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt new file mode 100644 index 00000000..e605226d --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt @@ -0,0 +1,5 @@ +package com.squirtles.musicroad.search.navigation + +class SearchNavigation { + +} From b120ff7aeda57a8cdacdf290fd03dfbaca56c4a8 Mon Sep 17 00:00:00 2001 From: miller198 Date: Tue, 7 Jan 2025 19:47:50 +0900 Subject: [PATCH 09/46] =?UTF-8?q?[refactor]=20Route=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../squirtles/musicroad/navigation/MainRoute.kt | 15 --------------- .../squirtles/musicroad/navigation/MapRoute.kt | 15 +++++++++++++++ .../com/squirtles/musicroad/navigation/Route.kt | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) delete mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/MapRoute.kt diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt deleted file mode 100644 index bdb2fff3..00000000 --- a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.squirtles.musicroad.navigation - -import kotlinx.serialization.Serializable - -@Serializable -sealed interface MainRoute : Route { - @Serializable - data object Search : MainRoute - - @Serializable - data class PickDetail(val pickId: String) : MainRoute - - @Serializable - data object Profile : MainRoute -} diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/MapRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/MapRoute.kt new file mode 100644 index 00000000..61a82b1a --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/navigation/MapRoute.kt @@ -0,0 +1,15 @@ +package com.squirtles.musicroad.navigation + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface MapRoute : Route { + @Serializable + data object Search : MapRoute + + @Serializable + data class PickDetail(val pickId: String) : MapRoute + + @Serializable + data object Profile : MapRoute +} diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/Route.kt b/app/src/main/java/com/squirtles/musicroad/navigation/Route.kt index ea896a82..7e7db78e 100644 --- a/app/src/main/java/com/squirtles/musicroad/navigation/Route.kt +++ b/app/src/main/java/com/squirtles/musicroad/navigation/Route.kt @@ -5,5 +5,5 @@ import kotlinx.serialization.Serializable @Serializable sealed interface Route { @Serializable - data object Auth : Route + data object Map : Route } From ad70c73f90b69c902d5d8ef264f917e798fc2d62 Mon Sep 17 00:00:00 2001 From: miller198 Date: Tue, 7 Jan 2025 19:48:06 +0900 Subject: [PATCH 10/46] =?UTF-8?q?[feature]=20MainNavigator=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/main/navigations/MainNavigator.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigator.kt diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigator.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigator.kt new file mode 100644 index 00000000..75c62e8e --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigator.kt @@ -0,0 +1,17 @@ +package com.squirtles.musicroad.main.navigations + +import androidx.compose.runtime.Composable +import androidx.navigation.NavDestination +import androidx.navigation.NavHostController +import androidx.navigation.compose.currentBackStackEntryAsState +import com.squirtles.musicroad.navigation.Route + +internal class MainNavigator( + val navController: NavHostController +) { + private val currentDestination: NavDestination? + @Composable get() = navController + .currentBackStackEntryAsState().value?.destination + + val startDestination = Route.Map +} From 0853192a50d9ab15a2a65dda97bfd616a03f8845 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sat, 18 Jan 2025 15:34:07 +0900 Subject: [PATCH 11/46] =?UTF-8?q?[feature]=20=EC=A7=80=EB=8F=84=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20Bottom=20Navigation=20Tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/map/navigation/MapTab.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 app/src/main/java/com/squirtles/musicroad/map/navigation/MapTab.kt diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapTab.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapTab.kt new file mode 100644 index 00000000..263d20c7 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapTab.kt @@ -0,0 +1,39 @@ +package com.squirtles.musicroad.map.navigation + +import androidx.annotation.StringRes +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.FavoriteBorder +import androidx.compose.material.icons.outlined.AccountCircle +import androidx.compose.material.icons.outlined.MusicNote +import androidx.compose.ui.graphics.vector.ImageVector +import com.squirtles.musicroad.R +import com.squirtles.musicroad.map.BottomNavigationIconSize +import com.squirtles.musicroad.navigation.MapRoute + +internal sealed class MapTab( + @StringRes val contentDescription: Int, + val icon: ImageVector, + val iconSize: Int?, + val route: MapRoute, +) { + data class Favorite(val favoriteRoute: MapRoute.Favorite) : MapTab( + contentDescription = R.string.map_navigation_favorite_icon_description, + icon = Icons.Default.FavoriteBorder, + iconSize = null, + route = favoriteRoute + ) + + data class Profile(val profileRoute: MapRoute.Profile) : MapTab( + contentDescription = R.string.map_navigation_setting_icon_description, + icon = Icons.Outlined.AccountCircle, + iconSize = null, + route = profileRoute + ) + + data object Search : MapTab( + contentDescription = R.string.map_navigation_center_icon_description, + icon = Icons.Outlined.MusicNote, + iconSize = BottomNavigationIconSize.CENTER_ICON.size, + route = MapRoute.Search + ) +} From c3ec27dcf7c6abf221fc78cb8bfbad09133890d3 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 19 Jan 2025 23:42:48 +0900 Subject: [PATCH 12/46] =?UTF-8?q?[refactor]=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC,=20Navigation=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 1 + ...{PickListScreen.kt => PickListContents.kt} | 2 +- .../musicroad/create/CreatePickScreen.kt | 6 +- .../musicroad/create/CreatePickViewModel.kt | 2 +- .../create/navigation/CreateNavigation.kt | 1 - .../musicroad/detail/DetailPickUiState.kt | 10 -- .../musicroad/detail/DetailViewModel.kt | 32 ++--- ...etailPickScreen.kt => PickDetailScreen.kt} | 21 ++- .../musicroad/detail/PickDetailUiState.kt | 10 ++ .../detail/navigation/DetailNavigation.kt | 1 - .../musicroad/favorite/FavoriteScreen.kt | 4 +- .../favorite/navigation/FavoriteNavigation.kt | 25 ++++ .../squirtles/musicroad/main/LoadingState.kt | 9 ++ .../squirtles/musicroad/main/MainActivity.kt | 10 +- .../squirtles/musicroad/main/MainViewModel.kt | 14 +- .../musicroad/main/navigation/MainNavHost.kt | 62 +++++++++ .../main/navigation/MainNavigator.kt | 121 ++++++++++++++++++ .../main/navigations/MainNavGraph.kt | 26 ++-- .../main/navigations/MainNavigator.kt | 17 --- .../com/squirtles/musicroad/map/Constants.kt | 16 +++ .../com/squirtles/musicroad/map/MapScreen.kt | 11 +- .../{BottomNavigation.kt => MapBottomBar.kt} | 110 +++++++++------- .../musicroad/map/navigation/MapNavigation.kt | 54 ++++++++ .../map/navigation/{MapTab.kt => NavTab.kt} | 14 +- .../musicroad/mypick/MyPickScreen.kt | 4 +- .../mypick/navigation/MyPickNavigation.kt | 28 ++++ .../musicroad/navigation/DetailRoute.kt | 9 -- .../musicroad/navigation/MainRoute.kt | 14 ++ .../musicroad/navigation/MapRoute.kt | 6 - .../musicroad/navigation/ProfileRoute.kt | 6 + .../musicroad/navigation/SearchRoute.kt | 4 +- .../profile/navigation/ProfileNavigation.kt | 43 ++++++- .../musicroad/search/SearchMusicScreen.kt | 11 +- .../search/navigation/SearchNavigation.kt | 43 ++++++- .../musicroad/utils/SerializableType.kt | 22 ++++ .../{common => utils}/ThrottleFirst.kt | 2 +- .../datasource/local/LocalDataSourceImpl.kt | 4 +- .../data/repository/LocalRepositoryImpl.kt | 6 +- domain/build.gradle.kts | 4 + .../squirtles/domain/local/LocalDataSource.kt | 4 +- .../squirtles/domain/local/LocalRepository.kt | 4 +- .../java/com/squirtles/domain/model/Song.kt | 2 + .../usecase/user/CreateNewUserUseCase.kt | 7 +- .../domain/usecase/user/FetchUserUseCase.kt | 5 +- .../user/GetUserIdFromDataStoreUseCase.kt | 13 ++ .../user/GetUserIdFromLocalStorageUseCase.kt | 10 -- gradle/libs.versions.toml | 2 + 47 files changed, 629 insertions(+), 203 deletions(-) rename app/src/main/java/com/squirtles/musicroad/common/picklist/{PickListScreen.kt => PickListContents.kt} (99%) delete mode 100644 app/src/main/java/com/squirtles/musicroad/create/navigation/CreateNavigation.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/detail/DetailPickUiState.kt rename app/src/main/java/com/squirtles/musicroad/detail/{DetailPickScreen.kt => PickDetailScreen.kt} (97%) create mode 100644 app/src/main/java/com/squirtles/musicroad/detail/PickDetailUiState.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/detail/navigation/DetailNavigation.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/main/LoadingState.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigator.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/map/Constants.kt rename app/src/main/java/com/squirtles/musicroad/map/components/{BottomNavigation.kt => MapBottomBar.kt} (52%) rename app/src/main/java/com/squirtles/musicroad/map/navigation/{MapTab.kt => NavTab.kt} (77%) create mode 100644 app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/DetailRoute.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/utils/SerializableType.kt rename app/src/main/java/com/squirtles/musicroad/{common => utils}/ThrottleFirst.kt (92%) create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt delete mode 100644 domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromLocalStorageUseCase.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4e08a714..3429eae0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -117,6 +117,7 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) + implementation(libs.kotlinx.immutable) // Hilt implementation(libs.hilt.android) diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreen.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt similarity index 99% rename from app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreen.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt index 699ebbe0..33cfbc6b 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt @@ -39,7 +39,7 @@ import com.squirtles.musicroad.ui.theme.Primary import com.squirtles.musicroad.ui.theme.White @Composable -fun PickListScreen( +fun PickListContents( showOrderBottomSheet: Boolean, pickListType: PickListType, uiState: PickListUiState, diff --git a/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt b/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt index 18de4460..aa4e3709 100644 --- a/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt @@ -54,6 +54,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.graphics.toColorInt import androidx.core.view.WindowInsetsControllerCompat +import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.squirtles.domain.model.Song import com.squirtles.musicroad.R @@ -66,11 +67,12 @@ import com.squirtles.musicroad.ui.theme.White @Composable fun CreatePickScreen( - createPickViewModel: CreatePickViewModel, + song: Song, onBackClick: () -> Unit, onCreateClick: (String) -> Unit, + createPickViewModel: CreatePickViewModel = hiltViewModel(), ) { - val song = createPickViewModel.selectedSong ?: DEFAULT_SONG +// val song = createPickViewModel.selectedSong ?: DEFAULT_SONG val comment = createPickViewModel.comment.collectAsStateWithLifecycle() val uiState by createPickViewModel.createPickUiState.collectAsStateWithLifecycle() var showCreateIndicator by rememberSaveable { mutableStateOf(false) } diff --git a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt index a439f820..7cb55587 100644 --- a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt @@ -15,7 +15,7 @@ import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.music.FetchMusicVideoUseCase import com.squirtles.domain.usecase.music.FetchSongsUseCase import com.squirtles.domain.usecase.mypick.CreatePickUseCase -import com.squirtles.musicroad.common.throttleFirst +import com.squirtles.musicroad.utils.throttleFirst import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.Job diff --git a/app/src/main/java/com/squirtles/musicroad/create/navigation/CreateNavigation.kt b/app/src/main/java/com/squirtles/musicroad/create/navigation/CreateNavigation.kt deleted file mode 100644 index a7f70d1a..00000000 --- a/app/src/main/java/com/squirtles/musicroad/create/navigation/CreateNavigation.kt +++ /dev/null @@ -1 +0,0 @@ -package com.squirtles.musicroad.create.navigation diff --git a/app/src/main/java/com/squirtles/musicroad/detail/DetailPickUiState.kt b/app/src/main/java/com/squirtles/musicroad/detail/DetailPickUiState.kt deleted file mode 100644 index 75523d44..00000000 --- a/app/src/main/java/com/squirtles/musicroad/detail/DetailPickUiState.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.squirtles.musicroad.detail - -import com.squirtles.domain.model.Pick - -sealed class DetailPickUiState { - data object Loading : DetailPickUiState() - data class Success(val pick: Pick, val isFavorite: Boolean) : DetailPickUiState() - data object Deleted : DetailPickUiState() - data object Error : DetailPickUiState() -} diff --git a/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt index 7a0bfb04..247b19c1 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt @@ -1,6 +1,7 @@ package com.squirtles.musicroad.detail import androidx.core.graphics.toColorInt +import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.model.Creator @@ -13,7 +14,7 @@ import com.squirtles.domain.usecase.mypick.DeletePickUseCase import com.squirtles.domain.usecase.pick.FetchIsFavoriteUseCase import com.squirtles.domain.usecase.pick.FetchPickUseCase import com.squirtles.domain.usecase.user.GetCurrentUserUseCase -import com.squirtles.musicroad.common.throttleFirst +import com.squirtles.musicroad.utils.throttleFirst import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.async import kotlinx.coroutines.flow.MutableSharedFlow @@ -25,6 +26,7 @@ import javax.inject.Inject @HiltViewModel class DetailViewModel @Inject constructor( + savedStateHandle: SavedStateHandle, private val fetchPickUseCase: FetchPickUseCase, private val fetchIsFavoriteUseCase: FetchIsFavoriteUseCase, private val getCurrentUserUseCase: GetCurrentUserUseCase, @@ -33,8 +35,8 @@ class DetailViewModel @Inject constructor( private val deleteFavoriteUseCase: DeleteFavoriteUseCase, ) : ViewModel() { - private val _detailPickUiState = MutableStateFlow(DetailPickUiState.Loading) - val detailPickUiState = _detailPickUiState.asStateFlow() + private val _pickDetailUiState = MutableStateFlow(PickDetailUiState.Loading) + val pickDetailUiState = _pickDetailUiState.asStateFlow() private var _currentTab = DETAIL_PICK_TAB val currentTab get() = _currentTab @@ -74,8 +76,8 @@ class DetailViewModel @Inject constructor( when { fetchPickResult.isSuccess && fetchIsFavoriteResult.isSuccess -> { - _detailPickUiState.emit( - DetailPickUiState.Success( + _pickDetailUiState.emit( + PickDetailUiState.Success( pick = fetchPickResult.getOrDefault(DEFAULT_PICK), isFavorite = fetchIsFavoriteResult.getOrDefault(false) ) @@ -83,7 +85,7 @@ class DetailViewModel @Inject constructor( } else -> { - _detailPickUiState.emit(DetailPickUiState.Error) + _pickDetailUiState.emit(PickDetailUiState.Error) } } } @@ -97,13 +99,13 @@ class DetailViewModel @Inject constructor( fun deletePick(pickId: String) { viewModelScope.launch { - _detailPickUiState.emit(DetailPickUiState.Loading) + _pickDetailUiState.emit(PickDetailUiState.Loading) deletePickUseCase(pickId, getUserId()) .onSuccess { - _detailPickUiState.emit(DetailPickUiState.Deleted) + _pickDetailUiState.emit(PickDetailUiState.Deleted) } .onFailure { - _detailPickUiState.emit(DetailPickUiState.Error) + _pickDetailUiState.emit(PickDetailUiState.Error) } } } @@ -113,13 +115,13 @@ class DetailViewModel @Inject constructor( createFavoriteUseCase(pickId, getUserId()) .onSuccess { _favoriteAction.emit(FavoriteAction.ADDED) - val currentUiState = _detailPickUiState.value as? DetailPickUiState.Success + val currentUiState = _pickDetailUiState.value as? PickDetailUiState.Success currentUiState?.let { successState -> - _detailPickUiState.emit(successState.copy(isFavorite = true)) + _pickDetailUiState.emit(successState.copy(isFavorite = true)) } } .onFailure { - _detailPickUiState.emit(DetailPickUiState.Error) + _pickDetailUiState.emit(PickDetailUiState.Error) } } } @@ -129,13 +131,13 @@ class DetailViewModel @Inject constructor( deleteFavoriteUseCase(pickId, getUserId()) .onSuccess { _favoriteAction.emit(FavoriteAction.DELETED) - val currentUiState = _detailPickUiState.value as? DetailPickUiState.Success + val currentUiState = _pickDetailUiState.value as? PickDetailUiState.Success currentUiState?.let { successState -> - _detailPickUiState.emit(successState.copy(isFavorite = false)) + _pickDetailUiState.emit(successState.copy(isFavorite = false)) } } .onFailure { - _detailPickUiState.emit(DetailPickUiState.Error) + _pickDetailUiState.emit(PickDetailUiState.Error) } } } diff --git a/app/src/main/java/com/squirtles/musicroad/detail/DetailPickScreen.kt b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/detail/DetailPickScreen.kt rename to app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt index 13230715..0604db49 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/DetailPickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt @@ -72,16 +72,16 @@ import kotlinx.coroutines.launch import kotlin.math.absoluteValue @Composable -fun DetailPickScreen( +fun PickDetailScreen( pickId: String, - detailViewModel: DetailViewModel = hiltViewModel(), - playerServiceViewModel: PlayerServiceViewModel, onProfileClick: (String) -> Unit, onBackClick: () -> Unit, onDeleted: (Context) -> Unit, + playerServiceViewModel: PlayerServiceViewModel, + detailViewModel: DetailViewModel = hiltViewModel(), ) { val context = LocalContext.current - val uiState by detailViewModel.detailPickUiState.collectAsStateWithLifecycle() + val uiState by detailViewModel.pickDetailUiState.collectAsStateWithLifecycle() var showDeletePickDialog by rememberSaveable { mutableStateOf(false) } var showProcessIndicator by rememberSaveable { mutableStateOf(false) } var isMusicVideoAvailable by remember { mutableStateOf(false) } @@ -97,7 +97,7 @@ fun DetailPickScreen( } when (uiState) { - DetailPickUiState.Loading -> { + PickDetailUiState.Loading -> { Box( modifier = Modifier .fillMaxSize() @@ -108,10 +108,10 @@ fun DetailPickScreen( } } - is DetailPickUiState.Success -> { + is PickDetailUiState.Success -> { val lifecycleOwner = LocalLifecycleOwner.current - val pick = (uiState as DetailPickUiState.Success).pick - val isFavorite = (uiState as DetailPickUiState.Success).isFavorite + val pick = (uiState as PickDetailUiState.Success).pick + val isFavorite = (uiState as PickDetailUiState.Success).isFavorite val isCreatedBySelf = detailViewModel.getUserId() == pick.createdBy.userId var favoriteCount by rememberSaveable { mutableIntStateOf(pick.favoriteCount) } val onActionClick: () -> Unit = { @@ -233,7 +233,7 @@ fun DetailPickScreen( } } - DetailPickUiState.Deleted -> { + PickDetailUiState.Deleted -> { LaunchedEffect(Unit) { onBackClick() onDeleted(context) @@ -245,7 +245,7 @@ fun DetailPickScreen( } } - DetailPickUiState.Error -> { + PickDetailUiState.Error -> { LaunchedEffect(Unit) { Toast.makeText( context, @@ -318,7 +318,6 @@ private fun DetailPick( val dynamicBackgroundColor = Color(pick.song.bgColor) val onDynamicBackgroundColor = if (dynamicBackgroundColor.luminance() >= 0.5f) Black else White val view = LocalView.current - val context = LocalContext.current val baseVisualizer = remember { BaseVisualizer() } diff --git a/app/src/main/java/com/squirtles/musicroad/detail/PickDetailUiState.kt b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailUiState.kt new file mode 100644 index 00000000..a55c5b86 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailUiState.kt @@ -0,0 +1,10 @@ +package com.squirtles.musicroad.detail + +import com.squirtles.domain.model.Pick + +sealed class PickDetailUiState { + data object Loading : PickDetailUiState() + data class Success(val pick: Pick, val isFavorite: Boolean) : PickDetailUiState() + data object Deleted : PickDetailUiState() + data object Error : PickDetailUiState() +} diff --git a/app/src/main/java/com/squirtles/musicroad/detail/navigation/DetailNavigation.kt b/app/src/main/java/com/squirtles/musicroad/detail/navigation/DetailNavigation.kt deleted file mode 100644 index 4c59e66b..00000000 --- a/app/src/main/java/com/squirtles/musicroad/detail/navigation/DetailNavigation.kt +++ /dev/null @@ -1 +0,0 @@ -package com.squirtles.musicroad.detail.navigation diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt index eec7bc2c..53b0b4d1 100644 --- a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt @@ -8,7 +8,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.squirtles.musicroad.common.picklist.PickListScreen +import com.squirtles.musicroad.common.picklist.PickListContents import com.squirtles.musicroad.common.picklist.PickListType @Composable @@ -25,7 +25,7 @@ fun FavoriteScreen( favoriteListViewModel.fetchFavoritePicks(userId) } - PickListScreen( + PickListContents( showOrderBottomSheet = showOrderBottomSheet, pickListType = PickListType.FAVORITE, uiState = uiState, diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/navigation/FavoriteNavigation.kt b/app/src/main/java/com/squirtles/musicroad/favorite/navigation/FavoriteNavigation.kt index 51c89a35..c78a57fe 100644 --- a/app/src/main/java/com/squirtles/musicroad/favorite/navigation/FavoriteNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/favorite/navigation/FavoriteNavigation.kt @@ -1,3 +1,28 @@ package com.squirtles.musicroad.favorite.navigation +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import androidx.navigation.toRoute +import com.squirtles.musicroad.favorite.FavoriteScreen +import com.squirtles.musicroad.navigation.MainRoute +fun NavController.navigateFavorite(userId: String, navOptions: NavOptions? = null) { + navigate(MainRoute.Favorite(userId), navOptions) +} + +fun NavGraphBuilder.favoriteNavGraph( + onBackClick: () -> Unit, + onItemClick: (String) -> Unit, +) { + composable { backStackEntry -> + val userId = backStackEntry.toRoute().userId + + FavoriteScreen( + userId = userId, + onBackClick = onBackClick, + onItemClick = onItemClick, + ) + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/main/LoadingState.kt b/app/src/main/java/com/squirtles/musicroad/main/LoadingState.kt new file mode 100644 index 00000000..38beedea --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/main/LoadingState.kt @@ -0,0 +1,9 @@ +package com.squirtles.musicroad.main + +sealed class LoadingState { + data object Loading : LoadingState() + data class Success(val userId: String) : LoadingState() + data class NetworkError(val error: String) : LoadingState() + data class CreatedUserError(val error: String) : LoadingState() + data class UserNotFoundError(val error: String) : LoadingState() +} diff --git a/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt b/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt index 299c7788..5ea7acf2 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt @@ -25,6 +25,9 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.compose.rememberNavController import com.squirtles.musicroad.R +import com.squirtles.musicroad.main.navigation.MainNavHost +import com.squirtles.musicroad.main.navigation.MainNavigator +import com.squirtles.musicroad.main.navigation.rememberMainNavigator import com.squirtles.musicroad.main.navigations.MainNavGraph import com.squirtles.musicroad.main.navigations.MainNavigationActions import com.squirtles.musicroad.ui.theme.MusicRoadTheme @@ -145,14 +148,15 @@ class MainActivity : AppCompatActivity() { private fun setMusicRoadContent() { setContent { + val navigator: MainNavigator = rememberMainNavigator() + MusicRoadTheme { val navController = rememberNavController() val navigationActions = remember(navController) { MainNavigationActions(navController) } - MainNavGraph( - navController = navController, - navigationActions = navigationActions + MainNavHost( + navigator = navigator, ) } } diff --git a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt index c98cf693..b7dd2e3d 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt @@ -3,7 +3,7 @@ package com.squirtles.musicroad.main import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.firebase.FirebaseException -import com.squirtles.domain.usecase.user.GetUserIdFromLocalStorageUseCase +import com.squirtles.domain.usecase.user.GetUserIdFromDataStoreUseCase import com.squirtles.domain.usecase.user.CreateNewUserUseCase import com.squirtles.domain.usecase.user.FetchUserUseCase import dagger.hilt.android.lifecycle.HiltViewModel @@ -12,17 +12,9 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject -sealed class LoadingState { - data object Loading : LoadingState() - data class Success(val userId: String) : LoadingState() - data class NetworkError(val error: String) : LoadingState() - data class CreatedUserError(val error: String) : LoadingState() - data class UserNotFoundError(val error: String) : LoadingState() -} - @HiltViewModel class MainViewModel @Inject constructor( - getUserIdFromLocalStorageUseCase: GetUserIdFromLocalStorageUseCase, + getUserIdFromDataStoreUseCase: GetUserIdFromDataStoreUseCase, private val fetchUserUseCase: FetchUserUseCase, private val createNewUserUseCase: CreateNewUserUseCase ) : ViewModel() { @@ -33,7 +25,7 @@ class MainViewModel @Inject constructor( private var _canRequestPermission = true val canRequestPermission get() = _canRequestPermission - private val _localUserId = getUserIdFromLocalStorageUseCase() + private val _localUserId = getUserIdFromDataStoreUseCase() init { viewModelScope.launch { diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt new file mode 100644 index 00000000..ad632128 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt @@ -0,0 +1,62 @@ +package com.squirtles.musicroad.main.navigation + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.compose.NavHost +import com.squirtles.musicroad.favorite.navigation.favoriteNavGraph +import com.squirtles.musicroad.map.MapViewModel +import com.squirtles.musicroad.map.navigation.mapNavGraph +import com.squirtles.musicroad.media.PlayerServiceViewModel +import com.squirtles.musicroad.mypick.navigation.myPickNavGraph +import com.squirtles.musicroad.profile.navigation.profileNavGraph +import com.squirtles.musicroad.search.navigation.searchNavGraph + +@Composable +internal fun MainNavHost( + modifier: Modifier = Modifier, + navigator: MainNavigator, + mapViewModel: MapViewModel = hiltViewModel(), + playerServiceViewModel: PlayerServiceViewModel = hiltViewModel(), +) { + NavHost( + navController = navigator.navController, + startDestination = navigator.startDestination, + ) { + mapNavGraph( + mapViewModel = mapViewModel, + playerServiceViewModel = playerServiceViewModel, + onFavoriteClick = navigator::navigateFavorite, + onCenterClick = navigator::navigateSearch, + onProfileClick = navigator::navigateProfile, + onPickSummaryClick = navigator::navigatePickDetail, + onBackClick = navigator::navigateMap, + onDeleted = mapViewModel::resetClickedMarkerState + ) + + searchNavGraph( + onBackClick = navigator::popBackStackIfNotMap, + onItemClick = navigator::navigateCreate, + onCreateClick = navigator::navigatePickDetail, + ) + + favoriteNavGraph( + onBackClick = navigator::popBackStackIfNotMap, + onItemClick = navigator::navigatePickDetail + ) + + profileNavGraph( + onBackClick = navigator::popBackStackIfNotMap, + onBackToMapClick = navigator::navigateMap, + onFavoritePicksClick = navigator::navigateFavorite, + onMyPicksClick = navigator::navigateMyPicks, + onSettingProfileClick = navigator::navigateSettingProfile, + onSettingNotificationClick = navigator::navigateSettingNotification, + ) + + myPickNavGraph( + onBackClick = navigator::popBackStackIfNotMap, + onItemClick = navigator::navigatePickDetail + ) + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt new file mode 100644 index 00000000..bf712ea6 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt @@ -0,0 +1,121 @@ +package com.squirtles.musicroad.main.navigation + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.navigation.NavDestination +import androidx.navigation.NavDestination.Companion.hasRoute +import androidx.navigation.NavHostController +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navOptions +import com.squirtles.domain.model.Song +import com.squirtles.musicroad.favorite.navigation.navigateFavorite +import com.squirtles.musicroad.map.navigation.navigateMap +import com.squirtles.musicroad.map.navigation.navigatePickDetail +import com.squirtles.musicroad.mypick.navigation.navigateMyPicks +import com.squirtles.musicroad.navigation.Route +import com.squirtles.musicroad.profile.navigation.navigateProfile +import com.squirtles.musicroad.profile.navigation.navigateSettingNotification +import com.squirtles.musicroad.profile.navigation.navigateSettingProfile +import com.squirtles.musicroad.search.navigation.navigateCreate +import com.squirtles.musicroad.search.navigation.navigateSearch + +internal class MainNavigator( + val navController: NavHostController +) { + private val currentDestination: NavDestination? + @Composable get() = navController + .currentBackStackEntryAsState().value?.destination + + val startDestination = Route.Map + + fun navigateMap() { + navController.navigateMap( + navOptions { + popUpTo(startDestination) { + inclusive = true + } + launchSingleTop = true + } + ) + } + + fun navigateFavorite(userId: String) { + navController.navigateFavorite( + userId = userId, + navOptions { + launchSingleTop = true + } + ) + } + + fun navigatePickDetail(pickId: String) { + navController.navigatePickDetail( + pickId = pickId, + navOptions = navOptions { + launchSingleTop = true + } + ) + } + + fun navigateMyPicks(userId: String) { + navController.navigateMyPicks( + userId = userId, + navOptions = navOptions { launchSingleTop = true } + ) + } + + fun navigateProfile(userId: String) { + navController.navigateProfile( + userId = userId, + navOptions = navOptions { launchSingleTop = true } + ) + } + + fun navigateSettingProfile(){ + navController.navigateSettingProfile( + navOptions = navOptions { launchSingleTop = true } + ) + } + + fun navigateSettingNotification(){ + navController.navigateSettingNotification( + navOptions = navOptions { launchSingleTop = true } + ) + } + + fun navigateSearch() { + navController.navigateSearch( + navOptions = navOptions { launchSingleTop = true } + ) + } + + fun navigateCreate(song: Song) { + navController.navigateCreate( + song = song, + navOptions = navOptions { launchSingleTop = true } + ) + } + + private fun popBackStack() { + navController.popBackStack() + } + + fun popBackStackIfNotMap() { + if (!isSameCurrentDestination()) { + popBackStack() + } + } + + private inline fun isSameCurrentDestination(): Boolean { + return navController.currentDestination?.hasRoute() == true + } + +} + +@Composable +internal fun rememberMainNavigator( + navController: NavHostController = rememberNavController(), +): MainNavigator = remember(navController) { + MainNavigator(navController) +} diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt index f4e76c0d..8fd5bb7f 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt @@ -16,9 +16,9 @@ import com.squirtles.musicroad.create.SearchMusicScreen import com.squirtles.musicroad.map.MapScreen import com.squirtles.musicroad.map.MapViewModel import com.squirtles.musicroad.media.PlayerServiceViewModel -import com.squirtles.musicroad.detail.DetailPickScreen -import com.squirtles.musicroad.picklist.PickListScreen -import com.squirtles.musicroad.picklist.PickListType +import com.squirtles.musicroad.detail.PickDetailScreen +import com.squirtles.musicroad.favorite.FavoriteScreen +import com.squirtles.musicroad.mypick.MyPickScreen import com.squirtles.musicroad.profile.screen.ProfileScreen import com.squirtles.musicroad.profile.screen.SettingNotificationScreen import com.squirtles.musicroad.profile.screen.SettingProfileScreen @@ -42,7 +42,7 @@ fun MainNavGraph( playerServiceViewModel = playerServiceViewModel, onFavoriteClick = { userId -> navigationActions.navigateToFavoritePicks(userId) }, onCenterClick = navigationActions.navigateToSearch, - onUserInfoClick = { userId -> navigationActions.navigateToProfile(userId) }, + onProfileClick = { userId -> navigationActions.navigateToProfile(userId) }, onPickSummaryClick = { pickId -> navigationActions.navigateToPickDetail(pickId) }, ) } @@ -53,9 +53,8 @@ fun MainNavGraph( ) { backStackEntry -> val userId = backStackEntry.arguments?.getString("userId") ?: "" - PickListScreen( + FavoriteScreen( userId = userId, - pickListType = PickListType.FAVORITE, onBackClick = { navController.navigateUp() }, onItemClick = { pickId -> navigationActions.navigateToPickDetail(pickId) } ) @@ -67,9 +66,8 @@ fun MainNavGraph( ) { backStackEntry -> val userId = backStackEntry.arguments?.getString("userId") ?: "" - PickListScreen( + MyPickScreen( userId = userId, - pickListType = PickListType.CREATED, onBackClick = { navController.navigateUp() }, onItemClick = { pickId -> navigationActions.navigateToPickDetail(pickId) } ) @@ -119,11 +117,11 @@ fun MainNavGraph( val parentEntry = remember(it) { navController.getBackStackEntry(CreatePickDestinations.CREATE_ROUTE) } - CreatePickScreen( - createPickViewModel = hiltViewModel(parentEntry), - onBackClick = { navController.navigateUp() }, - onCreateClick = { pickId -> navigationActions.navigateToPickDetail(pickId) } - ) +// CreatePickScreen( +// createPickViewModel = hiltViewModel(parentEntry), +// onBackClick = { navController.navigateUp() }, +// onCreateClick = { pickId -> navigationActions.navigateToPickDetail(pickId) } +// ) } } @@ -133,7 +131,7 @@ fun MainNavGraph( ) { backStackEntry -> val pickId = backStackEntry.arguments?.getString("pickId") ?: "" - DetailPickScreen( + PickDetailScreen( pickId = pickId, playerServiceViewModel = playerServiceViewModel, onProfileClick = { userId -> navigationActions.navigateToProfile(userId) }, diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigator.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigator.kt deleted file mode 100644 index 75c62e8e..00000000 --- a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigator.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.squirtles.musicroad.main.navigations - -import androidx.compose.runtime.Composable -import androidx.navigation.NavDestination -import androidx.navigation.NavHostController -import androidx.navigation.compose.currentBackStackEntryAsState -import com.squirtles.musicroad.navigation.Route - -internal class MainNavigator( - val navController: NavHostController -) { - private val currentDestination: NavDestination? - @Composable get() = navController - .currentBackStackEntryAsState().value?.destination - - val startDestination = Route.Map -} diff --git a/app/src/main/java/com/squirtles/musicroad/map/Constants.kt b/app/src/main/java/com/squirtles/musicroad/map/Constants.kt new file mode 100644 index 00000000..92fad232 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/map/Constants.kt @@ -0,0 +1,16 @@ +package com.squirtles.musicroad.map + +internal enum class BottomNavigationSize( + val size: Int +) { + WIDTH(245), + HEIGHT(50), + HORIZONTAL_PADDING(32) +} + +internal enum class BottomNavigationIconSize( + val size: Int, +) { + CENTER(82), + CENTER_ICON(34) +} diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt index e5ee5366..90a2dcf8 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt @@ -25,7 +25,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.squirtles.musicroad.common.VerticalSpacer import com.squirtles.musicroad.main.MainActivity -import com.squirtles.musicroad.map.components.BottomNavigation +import com.squirtles.musicroad.map.components.MapBottomBar import com.squirtles.musicroad.map.components.ClusterBottomSheet import com.squirtles.musicroad.map.components.InfoWindow import com.squirtles.musicroad.map.components.LoadingDialog @@ -38,7 +38,7 @@ fun MapScreen( playerServiceViewModel: PlayerServiceViewModel, onFavoriteClick: (String) -> Unit, onCenterClick: () -> Unit, - onUserInfoClick: (String) -> Unit, + onProfileClick: (String) -> Unit, onPickSummaryClick: (String) -> Unit, ) { val nearPicks by mapViewModel.nearPicks.collectAsStateWithLifecycle() @@ -123,8 +123,9 @@ fun MapScreen( VerticalSpacer(16) - BottomNavigation( + MapBottomBar( modifier = Modifier.padding(bottom = 16.dp), + userId = mapViewModel.getUserId(), lastLocation = lastLocation, onFavoriteClick = { onFavoriteClick(mapViewModel.getUserId()) @@ -133,8 +134,8 @@ fun MapScreen( onCenterClick() mapViewModel.saveCurLocationForced() }, - onUserInfoClick = { - onUserInfoClick(mapViewModel.getUserId()) + onProfileClick = { + onProfileClick(mapViewModel.getUserId()) } ) } diff --git a/app/src/main/java/com/squirtles/musicroad/map/components/BottomNavigation.kt b/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt similarity index 52% rename from app/src/main/java/com/squirtles/musicroad/map/components/BottomNavigation.kt rename to app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt index 6cc689f6..f2a81f25 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/components/BottomNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt @@ -10,9 +10,6 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.FavoriteBorder -import androidx.compose.material.icons.outlined.AccountCircle import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable @@ -20,20 +17,28 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.squirtles.musicroad.R +import com.squirtles.musicroad.map.BottomNavigationIconSize +import com.squirtles.musicroad.map.BottomNavigationSize +import com.squirtles.musicroad.map.navigation.NavTab +import com.squirtles.musicroad.navigation.MainRoute import com.squirtles.musicroad.ui.theme.MusicRoadTheme +import com.squirtles.musicroad.ui.theme.Primary @Composable -fun BottomNavigation( +internal fun MapBottomBar( modifier: Modifier = Modifier, + userId: String, lastLocation: Location?, onFavoriteClick: () -> Unit, onCenterClick: () -> Unit, - onUserInfoClick: () -> Unit + onProfileClick: () -> Unit ) { Box( modifier = modifier, @@ -41,65 +46,72 @@ fun BottomNavigation( ) { Row( modifier = Modifier - .size(245.dp, 50.dp) + .size(BottomNavigationSize.WIDTH.size.dp, BottomNavigationSize.HEIGHT.size.dp) .clip(CircleShape) .background(color = MaterialTheme.colorScheme.surface) ) { // 왼쪽 버튼 - Box( + MapBottomNavigationItem( modifier = Modifier .weight(1f) .fillMaxHeight() - .clickable { onFavoriteClick() }, - contentAlignment = Alignment.CenterStart - ) { - Icon( - imageVector = Icons.Default.FavoriteBorder, - contentDescription = stringResource(R.string.map_navigation_favorite_icon_description), - modifier = Modifier.padding(start = BottomNavigationHorizontalPadding), - tint = MaterialTheme.colorScheme.primary - ) - } + .padding(end = BottomNavigationSize.HORIZONTAL_PADDING.size.dp), + tab = NavTab.Favorite(MainRoute.Favorite(userId)), + painter = null, + tint = Primary, + onClick = onFavoriteClick + ) // 오른쪽 버튼 - Box( + MapBottomNavigationItem( modifier = Modifier .weight(1f) .fillMaxHeight() - .clickable { onUserInfoClick() }, - contentAlignment = Alignment.CenterEnd - ) { - Icon( - imageVector = Icons.Outlined.AccountCircle, - contentDescription = stringResource(R.string.map_navigation_setting_icon_description), - modifier = Modifier.padding(end = BottomNavigationHorizontalPadding), - tint = MaterialTheme.colorScheme.primary - ) - } + .padding(start = BottomNavigationSize.HORIZONTAL_PADDING.size.dp), + tab = NavTab.Profile(MainRoute.Profile(userId)), + painter = null, + tint = Primary, + onClick = onProfileClick + ) } // 중앙 버튼 - Box( + MapBottomNavigationItem( modifier = Modifier - .size(82.dp) + .size(BottomNavigationIconSize.CENTER.size.dp) .clip(CircleShape) .background( color = lastLocation?.let { MaterialTheme.colorScheme.primary } ?: Color.Gray - ) - .clickable(enabled = lastLocation != null) { - onCenterClick() - }, - contentAlignment = Alignment.Center - ) { - Icon( - painter = painterResource(R.drawable.ic_musical_note_64), - contentDescription = stringResource(R.string.map_navigation_center_icon_description), - modifier = Modifier.size(34.dp), - tint = MaterialTheme.colorScheme.onPrimary - ) - } + ), + tab = NavTab.Search, + painter = painterResource(R.drawable.ic_musical_note_64), + tint = MaterialTheme.colorScheme.onPrimary, + onClick = onCenterClick + ) + } +} + +@Composable +private fun MapBottomNavigationItem( + modifier: Modifier = Modifier, + tab: NavTab, + painter: Painter?, + tint: Color, + onClick: () -> Unit +) { + Box( + modifier = modifier + .clickable { onClick() }, + contentAlignment = Alignment.Center, + ) { + Icon( + modifier = if (tab.iconSize != null) Modifier.size(tab.iconSize.dp) else Modifier, + painter = painter ?: rememberVectorPainter(tab.icon), + contentDescription = stringResource(tab.contentDescription), + tint = tint + ) } } @@ -107,11 +119,12 @@ fun BottomNavigation( @Composable fun BottomNavigationLightPreview() { MusicRoadTheme { - BottomNavigation( + MapBottomBar( + userId = "", onFavoriteClick = {}, lastLocation = null, onCenterClick = {}, - onUserInfoClick = {} + onProfileClick = {} ) } } @@ -120,13 +133,12 @@ fun BottomNavigationLightPreview() { @Composable fun BottomNavigationDarkPreview() { MusicRoadTheme { - BottomNavigation( + MapBottomBar( + userId = "", onFavoriteClick = {}, lastLocation = null, onCenterClick = {}, - onUserInfoClick = {} + onProfileClick = {} ) } } - -private val BottomNavigationHorizontalPadding = 32.dp diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt index 6b4d544d..d4336ab0 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt @@ -1,2 +1,56 @@ package com.squirtles.musicroad.map.navigation +import android.content.Context +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import androidx.navigation.toRoute +import com.squirtles.musicroad.detail.PickDetailScreen +import com.squirtles.musicroad.map.MapScreen +import com.squirtles.musicroad.map.MapViewModel +import com.squirtles.musicroad.media.PlayerServiceViewModel +import com.squirtles.musicroad.navigation.MapRoute +import com.squirtles.musicroad.navigation.Route + +fun NavController.navigateMap(navOptions: NavOptions? = null) { + navigate(Route.Map, navOptions) +} + +fun NavController.navigatePickDetail(pickId: String, navOptions: NavOptions? = null) { + navigate(MapRoute.PickDetail(pickId), navOptions) +} + +fun NavGraphBuilder.mapNavGraph( + mapViewModel: MapViewModel, + playerServiceViewModel: PlayerServiceViewModel, + onFavoriteClick: (String) -> Unit, + onCenterClick: () -> Unit, + onProfileClick: (String) -> Unit, + onPickSummaryClick: (String) -> Unit, + onBackClick: () -> Unit, + onDeleted: (Context) -> Unit, +) { + composable { + MapScreen( + mapViewModel = mapViewModel, + playerServiceViewModel = playerServiceViewModel, + onFavoriteClick = onFavoriteClick, + onCenterClick = onCenterClick, + onProfileClick = onProfileClick, + onPickSummaryClick = onPickSummaryClick, + ) + } + + composable { backStackEntry -> + val pickId = backStackEntry.toRoute().pickId + + PickDetailScreen( + pickId = pickId, + playerServiceViewModel = playerServiceViewModel, + onProfileClick = onProfileClick, + onBackClick = onBackClick, + onDeleted = onDeleted, + ) + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapTab.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt similarity index 77% rename from app/src/main/java/com/squirtles/musicroad/map/navigation/MapTab.kt rename to app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt index 263d20c7..4f7853e0 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapTab.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt @@ -8,32 +8,32 @@ import androidx.compose.material.icons.outlined.MusicNote import androidx.compose.ui.graphics.vector.ImageVector import com.squirtles.musicroad.R import com.squirtles.musicroad.map.BottomNavigationIconSize -import com.squirtles.musicroad.navigation.MapRoute +import com.squirtles.musicroad.navigation.MainRoute -internal sealed class MapTab( +internal sealed class NavTab( @StringRes val contentDescription: Int, val icon: ImageVector, val iconSize: Int?, - val route: MapRoute, + val route: MainRoute, ) { - data class Favorite(val favoriteRoute: MapRoute.Favorite) : MapTab( + data class Favorite(val favoriteRoute: MainRoute.Favorite) : NavTab( contentDescription = R.string.map_navigation_favorite_icon_description, icon = Icons.Default.FavoriteBorder, iconSize = null, route = favoriteRoute ) - data class Profile(val profileRoute: MapRoute.Profile) : MapTab( + data class Profile(val profileRoute: MainRoute.Profile) : NavTab( contentDescription = R.string.map_navigation_setting_icon_description, icon = Icons.Outlined.AccountCircle, iconSize = null, route = profileRoute ) - data object Search : MapTab( + data object Search : NavTab( contentDescription = R.string.map_navigation_center_icon_description, icon = Icons.Outlined.MusicNote, iconSize = BottomNavigationIconSize.CENTER_ICON.size, - route = MapRoute.Search + route = MainRoute.Search ) } diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt index 6b6fe42f..45461e44 100644 --- a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt @@ -8,7 +8,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.squirtles.musicroad.common.picklist.PickListScreen +import com.squirtles.musicroad.common.picklist.PickListContents import com.squirtles.musicroad.common.picklist.PickListType @Composable @@ -25,7 +25,7 @@ fun MyPickScreen( myPickListViewModel.fetchMyPicks(userId) } - PickListScreen( + PickListContents( showOrderBottomSheet = showOrderBottomSheet, pickListType = PickListType.FAVORITE, uiState = uiState, diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt b/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt new file mode 100644 index 00000000..fee5742e --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt @@ -0,0 +1,28 @@ +package com.squirtles.musicroad.mypick.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import androidx.navigation.toRoute +import com.squirtles.musicroad.mypick.MyPickScreen +import com.squirtles.musicroad.navigation.ProfileRoute + +fun NavController.navigateMyPicks(userId: String, navOptions: NavOptions) { + navigate(ProfileRoute.MyPicks(userId), navOptions) +} + +fun NavGraphBuilder.myPickNavGraph( + onBackClick: () -> Unit, + onItemClick: (String) -> Unit, +) { + composable { backStackEntry -> + val userId = backStackEntry.toRoute().userId + + MyPickScreen( + userId = userId, + onBackClick = onBackClick, + onItemClick = onItemClick + ) + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/DetailRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/DetailRoute.kt deleted file mode 100644 index 4485708e..00000000 --- a/app/src/main/java/com/squirtles/musicroad/navigation/DetailRoute.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.squirtles.musicroad.navigation - -import kotlinx.serialization.Serializable - -@Serializable -sealed interface DetailRoute : Route { - @Serializable - data object Setting : DetailRoute -} diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt new file mode 100644 index 00000000..aca1b147 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt @@ -0,0 +1,14 @@ +package com.squirtles.musicroad.navigation + +import kotlinx.serialization.Serializable + +sealed interface MainRoute : Route { + @Serializable + data object Search : MainRoute + + @Serializable + data class Favorite(val userId: String) : MainRoute + + @Serializable + data class Profile(val userId: String) : MainRoute +} diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/MapRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/MapRoute.kt index 61a82b1a..4a38424e 100644 --- a/app/src/main/java/com/squirtles/musicroad/navigation/MapRoute.kt +++ b/app/src/main/java/com/squirtles/musicroad/navigation/MapRoute.kt @@ -4,12 +4,6 @@ import kotlinx.serialization.Serializable @Serializable sealed interface MapRoute : Route { - @Serializable - data object Search : MapRoute - @Serializable data class PickDetail(val pickId: String) : MapRoute - - @Serializable - data object Profile : MapRoute } diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt index 2fca42c3..8cdd03be 100644 --- a/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt +++ b/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt @@ -4,7 +4,13 @@ import kotlinx.serialization.Serializable @Serializable sealed interface ProfileRoute : Route { + @Serializable + data class MyPicks(val userId: String) : ProfileRoute + @Serializable data object Setting : ProfileRoute + + @Serializable + data object Notification : ProfileRoute } diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt index 7760b52c..f4a6bc6f 100644 --- a/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt +++ b/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt @@ -1,10 +1,10 @@ package com.squirtles.musicroad.navigation +import com.squirtles.domain.model.Song import kotlinx.serialization.Serializable @Serializable sealed interface SearchRoute : Route { @Serializable - data object Create : SearchRoute + data class Create(val song: Song) : SearchRoute } - diff --git a/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt b/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt index da69f59f..be187715 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt @@ -1,4 +1,45 @@ package com.squirtles.musicroad.profile.navigation -class ProfileNavigation { +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import androidx.navigation.toRoute +import com.squirtles.musicroad.navigation.MainRoute +import com.squirtles.musicroad.navigation.ProfileRoute +import com.squirtles.musicroad.profile.screen.ProfileScreen + +fun NavController.navigateProfile(userId: String, navOptions: NavOptions? = null) { + navigate(MainRoute.Profile(userId), navOptions) +} + +fun NavController.navigateSettingProfile(navOptions: NavOptions? = null) { + navigate(ProfileRoute.Setting, navOptions) +} + +fun NavController.navigateSettingNotification(navOptions: NavOptions? = null) { + navigate(ProfileRoute.Notification, navOptions) +} + +fun NavGraphBuilder.profileNavGraph( + onBackClick: () -> Unit, + onBackToMapClick: () -> Unit, + onFavoritePicksClick: (String) -> Unit, + onMyPicksClick: (String) -> Unit, + onSettingProfileClick: () -> Unit, + onSettingNotificationClick: () -> Unit, +) { + composable { backStackEntry -> + val userId = backStackEntry.toRoute().userId + + ProfileScreen( + userId = userId, + onBackClick = onBackClick, + onBackToMapClick = onBackToMapClick, + onFavoritePicksClick = onFavoritePicksClick, + onMyPicksClick = onMyPicksClick, + onSettingProfileClick = onSettingProfileClick, + onSettingNotificationClick = onSettingNotificationClick, + ) + } } diff --git a/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt b/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt index b4fd25f4..220ddc3b 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt @@ -50,6 +50,7 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.paging.LoadState import androidx.paging.compose.LazyPagingItems @@ -67,9 +68,9 @@ import com.squirtles.musicroad.ui.theme.White @Composable fun SearchMusicScreen( - searchViewModel: SearchViewModel, - onBackClick: () -> Boolean, - onItemClick: () -> Unit, + onBackClick: () -> Unit, + onItemClick: (Song) -> Unit, + searchViewModel: SearchViewModel = hiltViewModel(), ) { val focusManager = LocalFocusManager.current val searchText by searchViewModel.searchText.collectAsStateWithLifecycle() @@ -125,7 +126,7 @@ fun SearchMusicScreen( onItemClick = { song -> searchViewModel.onSongItemClick(song) focusManager.clearFocus() - onItemClick() + onItemClick(song) } ) } @@ -138,7 +139,7 @@ fun SearchMusicScreen( private fun SearchTopBar( keyword: String, onValueChange: (String) -> Unit, - onBackClick: () -> Boolean, + onBackClick: () -> Unit, focusManager: FocusManager ) { diff --git a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt index e605226d..e3e2bb4d 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt @@ -1,5 +1,46 @@ package com.squirtles.musicroad.search.navigation -class SearchNavigation { +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import androidx.navigation.toRoute +import com.squirtles.domain.model.Song +import com.squirtles.musicroad.create.CreatePickScreen +import com.squirtles.musicroad.navigation.MainRoute +import com.squirtles.musicroad.navigation.SearchRoute +import com.squirtles.musicroad.search.SearchMusicScreen +import com.squirtles.musicroad.utils.serializableType +import kotlin.reflect.typeOf +fun NavController.navigateSearch(navOptions: NavOptions? = null) { + navigate(MainRoute.Search, navOptions) +} + +fun NavController.navigateCreate(song: Song, navOptions: NavOptions? = null) { + navigate(SearchRoute.Create(song), navOptions) +} + +fun NavGraphBuilder.searchNavGraph( + onBackClick: () -> Unit, + onItemClick: (Song) -> Unit, + onCreateClick: (String) -> Unit +) { + composable { + SearchMusicScreen( + onBackClick = onBackClick, + onItemClick = onItemClick, // Create 이동 + ) + } + composable( + typeMap = mapOf(typeOf() to serializableType()) + ) { backStackEntry -> + val song = backStackEntry.toRoute().song + + CreatePickScreen( + song = song, + onBackClick = onBackClick, + onCreateClick = onCreateClick, + ) + } } diff --git a/app/src/main/java/com/squirtles/musicroad/utils/SerializableType.kt b/app/src/main/java/com/squirtles/musicroad/utils/SerializableType.kt new file mode 100644 index 00000000..3741f31c --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/utils/SerializableType.kt @@ -0,0 +1,22 @@ +package com.squirtles.musicroad.utils + +import android.os.Bundle +import androidx.navigation.NavType +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +inline fun serializableType( + isNullableAllowed: Boolean = false, + json: Json = Json, +) = object : NavType(isNullableAllowed = isNullableAllowed) { + override fun get(bundle: Bundle, key: String) = + bundle.getString(key)?.let(json::decodeFromString) + + override fun parseValue(value: String): T = json.decodeFromString(value) + + override fun serializeAsValue(value: T): String = json.encodeToString(value) + + override fun put(bundle: Bundle, key: String, value: T) { + bundle.putString(key, json.encodeToString(value)) + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/common/ThrottleFirst.kt b/app/src/main/java/com/squirtles/musicroad/utils/ThrottleFirst.kt similarity index 92% rename from app/src/main/java/com/squirtles/musicroad/common/ThrottleFirst.kt rename to app/src/main/java/com/squirtles/musicroad/utils/ThrottleFirst.kt index b409ff23..cc768826 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/ThrottleFirst.kt +++ b/app/src/main/java/com/squirtles/musicroad/utils/ThrottleFirst.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.common +package com.squirtles.musicroad.utils import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow diff --git a/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt b/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt index d8e8ca72..a5278cbd 100644 --- a/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt +++ b/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt @@ -33,14 +33,14 @@ class LocalDataSourceImpl @Inject constructor( private var _myListOrder = Order.LATEST override val myListOrder get() = _myListOrder - override fun readUserId(): Flow { + override fun readUserIdDataStore(): Flow { val dataStoreKey = stringPreferencesKey(USER_ID_KEY) return context.dataStore.data.map { preferences -> preferences[dataStoreKey] } } - override suspend fun saveUserId(userId: String) { + override suspend fun writeUserIdDataStore(userId: String) { val dataStoreKey = stringPreferencesKey(USER_ID_KEY) context.dataStore.edit { preferences -> preferences[dataStoreKey] = userId diff --git a/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt b/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt index 92269e58..54e78416 100644 --- a/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt +++ b/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt @@ -10,14 +10,14 @@ import javax.inject.Inject class LocalRepositoryImpl @Inject constructor( private val localDataSource: LocalDataSource, ) : LocalRepository { - override val userId get() = localDataSource.readUserId() + override val userIdFromDataStore get() = localDataSource.readUserIdDataStore() override val currentUser get() = localDataSource.currentUser override val lastLocation get() = localDataSource.lastLocation override val favoriteListOrder get() = localDataSource.favoriteListOrder override val myListOrder get() = localDataSource.myListOrder - override suspend fun saveUserId(userId: String) { - localDataSource.saveUserId(userId) + override suspend fun writeUserIdDataStore(userId: String) { + localDataSource.writeUserIdDataStore(userId) } override suspend fun saveCurrentUser(user: User) { diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index 304b69ea..5255e9d6 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -3,6 +3,7 @@ plugins { alias(libs.plugins.jetbrains.kotlin.android) alias(libs.plugins.ksp) alias(libs.plugins.hilt) + alias(libs.plugins.kotlin.serialization) } android { @@ -51,4 +52,7 @@ dependencies { implementation(libs.androidx.media3.common) implementation(libs.androidx.media3.session) + + // Serialization + implementation(libs.kotlinx.serialization.json) } diff --git a/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt b/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt index 06057420..c6911094 100644 --- a/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt +++ b/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt @@ -12,8 +12,8 @@ interface LocalDataSource { val favoriteListOrder: Order val myListOrder: Order - fun readUserId(): Flow - suspend fun saveUserId(userId: String) + fun readUserIdDataStore(): Flow + suspend fun writeUserIdDataStore(userId: String) suspend fun saveCurrentUser(user: User) suspend fun saveCurrentLocation(location: Location) suspend fun saveFavoriteListOrder(order: Order) diff --git a/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt b/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt index af9776d1..9111840b 100644 --- a/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt +++ b/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt @@ -7,13 +7,13 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow interface LocalRepository { - val userId: Flow // 기기에 저장된 userId + val userIdFromDataStore: Flow // 기기에 저장된 userId val currentUser: User val lastLocation: StateFlow val favoriteListOrder: Order // 픽 보관함 정렬 순서 val myListOrder: Order // 등록한 픽 정렬 순서 - suspend fun saveUserId(userId: String) + suspend fun writeUserIdDataStore(userId: String) suspend fun saveCurrentUser(user: User) suspend fun saveCurrentLocation(location: Location) suspend fun saveFavoriteListOrder(order: Order) diff --git a/domain/src/main/java/com/squirtles/domain/model/Song.kt b/domain/src/main/java/com/squirtles/domain/model/Song.kt index 04faad64..af13b4e2 100644 --- a/domain/src/main/java/com/squirtles/domain/model/Song.kt +++ b/domain/src/main/java/com/squirtles/domain/model/Song.kt @@ -2,10 +2,12 @@ package com.squirtles.domain.model import android.util.Size import androidx.annotation.ColorInt +import kotlinx.serialization.Serializable /** * 애플뮤직에서 불러온 노래 정보를 비즈니스 로직에서 사용하기 위해 변환한 클래스 */ +@Serializable data class Song( val id: String, val songName: String, diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt index b0c39ae3..65730f1b 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt @@ -11,11 +11,10 @@ class CreateNewUserUseCase @Inject constructor( ) { suspend operator fun invoke(): Result { - val createdUser = firebaseRepository.createUser() + val createdUser = firebaseRepository.createUser() // Firebase에 유저 생성 .onSuccess { user -> - // 생성된 유저의 userId 저장 후 user 반환 - localRepository.saveUserId(user.userId) - localRepository.saveCurrentUser(user) + localRepository.writeUserIdDataStore(user.userId) // 생성된 유저의 userId를 DataStore에 저장 후 user 반환 + localRepository.saveCurrentUser(user) // 생성된 유저를 LocalDataSource currentUser 에 저장 } return createdUser } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt index b9ab974b..89ad06c1 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt @@ -9,10 +9,9 @@ class FetchUserUseCase @Inject constructor( private val fetchUserByIdUseCase: FetchUserByIdUseCase ) { suspend operator fun invoke(userId: String): Result { - // userId가 있으면 Firestore에서 유저 가져오기 - val user = fetchUserByIdUseCase(userId) + val user = fetchUserByIdUseCase(userId) // userId가 있으면 Firestore에서 유저 가져오기 .onSuccess { user -> - localRepository.saveCurrentUser(user) + localRepository.saveCurrentUser(user) // Firestore에서 가져온 user를 LocalDataSource에 저장 } return user } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt new file mode 100644 index 00000000..ef192b89 --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt @@ -0,0 +1,13 @@ +package com.squirtles.domain.usecase.user + +import com.squirtles.domain.local.LocalRepository +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class GetUserIdFromDataStoreUseCase @Inject constructor( + private val localRepository: LocalRepository +) { + operator fun invoke() : Flow { + return localRepository.userIdFromDataStore + } +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromLocalStorageUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromLocalStorageUseCase.kt deleted file mode 100644 index 6d7412fe..00000000 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromLocalStorageUseCase.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.squirtles.domain.usecase.user - -import com.squirtles.domain.local.LocalRepository -import javax.inject.Inject - -class GetUserIdFromLocalStorageUseCase @Inject constructor( - private val localRepository: LocalRepository -) { - operator fun invoke() = localRepository.userId -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ccb88c71..2e585f8e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,6 +39,7 @@ retrofit = "2.11.0" splashscreen = "1.0.1" uiViewbinding = "1.7.5" pagingComposeAndroid = "3.3.4" +kotlinxImmutable = "0.3.7" [libraries] # AndroidX @@ -71,6 +72,7 @@ androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", versi androidx-compose-material = { group = "androidx.wear.compose", name = "compose-material", version.ref = "composeMaterial" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutinesCore" } kotlinx-coroutines-guava = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-guava", version.ref = "kotlinxCoroutinesGuava" } +kotlinx-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version.ref = "kotlinxImmutable" } # Firebase firebase-analytics = { module = "com.google.firebase:firebase-analytics" } From f90f54a99a704238ddc3baf468fa75d01b1b5e14 Mon Sep 17 00:00:00 2001 From: miller198 Date: Tue, 21 Jan 2025 03:11:26 +0900 Subject: [PATCH 13/46] =?UTF-8?q?[refactor]=20UseCase=EC=97=90=EC=84=9C=20?= =?UTF-8?q?collect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../squirtles/musicroad/main/MainViewModel.kt | 30 ++++++++++++++----- .../squirtles/musicroad/map/MapViewModel.kt | 5 ++++ .../data/repository/LocalRepositoryImpl.kt | 9 ++++-- .../squirtles/domain/local/LocalRepository.kt | 3 +- .../user/GetUserIdFromDataStoreUseCase.kt | 12 ++++++-- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt index b7dd2e3d..6ff045a6 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt @@ -1,5 +1,6 @@ package com.squirtles.musicroad.main +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.firebase.FirebaseException @@ -9,6 +10,7 @@ import com.squirtles.domain.usecase.user.FetchUserUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch import javax.inject.Inject @@ -25,16 +27,28 @@ class MainViewModel @Inject constructor( private var _canRequestPermission = true val canRequestPermission get() = _canRequestPermission - private val _localUserId = getUserIdFromDataStoreUseCase() - init { +// viewModelScope.launch { +// getUserIdFromDataStoreUseCase() +// .catch { e -> +// Log.e("MainViewModel", "Error collecting flow: $e") +// } +// .collect { localUid -> +// Log.d("MainViewModel", "localUid: $localUid") +// if (localUid == null) { +// createUser() +// } else { +// fetchUser(localUid) +// } +// } +// } + viewModelScope.launch { - _localUserId.collect { localUid -> - if (localUid == null) { - createUser() - } else { - fetchUser(localUid) - } + val userId = getUserIdFromDataStoreUseCase() + if(userId == null) { + createUser() + } else { + fetchUser(userId) } } } diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt b/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt index c5c70165..3ce3a103 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt @@ -2,6 +2,7 @@ package com.squirtles.musicroad.map import android.content.Context import android.location.Location +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.naver.maps.geometry.LatLng @@ -55,6 +56,10 @@ class MapViewModel @Inject constructor( // Firestore 데이터 쿼리 작업 최소화 및 위치데이터 공유 용도 val lastLocation: StateFlow = getLastLocationUseCase() + init { + Log.d("MapViewModel", "init") + } + fun getUserId() = getCurrentUserUseCase().userId fun setLastCameraPosition(cameraPosition: CameraPosition) { diff --git a/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt b/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt index 54e78416..6394d7f2 100644 --- a/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt +++ b/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt @@ -2,19 +2,24 @@ package com.squirtles.data.repository import android.location.Location import com.squirtles.domain.local.LocalDataSource +import com.squirtles.domain.local.LocalRepository import com.squirtles.domain.model.Order import com.squirtles.domain.model.User -import com.squirtles.domain.local.LocalRepository +import kotlinx.coroutines.flow.Flow import javax.inject.Inject class LocalRepositoryImpl @Inject constructor( private val localDataSource: LocalDataSource, ) : LocalRepository { - override val userIdFromDataStore get() = localDataSource.readUserIdDataStore() override val currentUser get() = localDataSource.currentUser override val lastLocation get() = localDataSource.lastLocation override val favoriteListOrder get() = localDataSource.favoriteListOrder override val myListOrder get() = localDataSource.myListOrder + override var userIdFromDataStore: String? = null + + override fun readUserIdDataStore(): Flow { + return localDataSource.readUserIdDataStore() + } override suspend fun writeUserIdDataStore(userId: String) { localDataSource.writeUserIdDataStore(userId) diff --git a/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt b/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt index 9111840b..c2912b45 100644 --- a/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt +++ b/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt @@ -7,12 +7,13 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow interface LocalRepository { - val userIdFromDataStore: Flow // 기기에 저장된 userId + var userIdFromDataStore: String? // 기기에 저장된 userId val currentUser: User val lastLocation: StateFlow val favoriteListOrder: Order // 픽 보관함 정렬 순서 val myListOrder: Order // 등록한 픽 정렬 순서 + fun readUserIdDataStore(): Flow suspend fun writeUserIdDataStore(userId: String) suspend fun saveCurrentUser(user: User) suspend fun saveCurrentLocation(location: Location) diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt index ef192b89..e1dc8407 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt @@ -1,13 +1,21 @@ package com.squirtles.domain.usecase.user +import android.util.Log import com.squirtles.domain.local.LocalRepository import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.first import javax.inject.Inject class GetUserIdFromDataStoreUseCase @Inject constructor( private val localRepository: LocalRepository ) { - operator fun invoke() : Flow { - return localRepository.userIdFromDataStore + suspend operator fun invoke() : String? { + return try { + val userId = localRepository.readUserIdDataStore().first() + if (userId.isNullOrBlank()) null else userId + } catch (e: Exception) { + Log.e("GetUserIdUseCase", "Error reading DataStore", e) + null + } } } From 26a85653f29f29aacf0082d34a9c0283dee5686e Mon Sep 17 00:00:00 2001 From: miller198 Date: Tue, 21 Jan 2025 20:47:09 +0900 Subject: [PATCH 14/46] =?UTF-8?q?[refactor]=20@Serialization=20=EC=96=B4?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/squirtles/musicroad/navigation/MainRoute.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt index aca1b147..d7f03191 100644 --- a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt +++ b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt @@ -2,6 +2,7 @@ package com.squirtles.musicroad.navigation import kotlinx.serialization.Serializable +@Serializable sealed interface MainRoute : Route { @Serializable data object Search : MainRoute From d3771491634e975413e00a18c5e9ca940f3e8d03 Mon Sep 17 00:00:00 2001 From: miller198 Date: Tue, 21 Jan 2025 21:22:08 +0900 Subject: [PATCH 15/46] =?UTF-8?q?[refactor]=20merge=EC=A4=91=20=EB=B9=A0?= =?UTF-8?q?=EC=A7=84=EA=B2=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../squirtles/musicroad/common/MessageAlertDialog.kt | 4 ---- .../musicroad/common/picklist/PickListContents.kt | 4 ++-- .../com/squirtles/musicroad/detail/DetailViewModel.kt | 1 + .../com/squirtles/musicroad/detail/PickDetailScreen.kt | 10 ++-------- .../musicroad/main/navigations/MainNavGraph.kt | 5 ++--- .../musicroad/map/navigation/MapNavigation.kt | 2 +- 6 files changed, 8 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt b/app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt index effa7b5a..f902e027 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt @@ -1,8 +1,4 @@ -<<<<<<<< HEAD:app/src/main/java/com/squirtles/musicroad/detail/components/DeletePickDialog.kt -package com.squirtles.musicroad.detail.components -======== package com.squirtles.musicroad.common ->>>>>>>> develop:app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt index 33cfbc6b..973c4fbb 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt @@ -32,8 +32,8 @@ import com.squirtles.domain.model.Order import com.squirtles.musicroad.R import com.squirtles.musicroad.common.Constants.COLOR_STOPS import com.squirtles.musicroad.common.Constants.DEFAULT_PADDING +import com.squirtles.musicroad.common.CountText import com.squirtles.musicroad.common.DefaultTopAppBar -import com.squirtles.musicroad.common.TotalCountText import com.squirtles.musicroad.common.VerticalSpacer import com.squirtles.musicroad.ui.theme.Primary import com.squirtles.musicroad.ui.theme.White @@ -94,7 +94,7 @@ fun PickListContents( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { - TotalCountText( + CountText( totalCount = pickList.size, defaultColor = White, ) diff --git a/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt index 247b19c1..779175ff 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt @@ -14,6 +14,7 @@ import com.squirtles.domain.usecase.mypick.DeletePickUseCase import com.squirtles.domain.usecase.pick.FetchIsFavoriteUseCase import com.squirtles.domain.usecase.pick.FetchPickUseCase import com.squirtles.domain.usecase.user.GetCurrentUserUseCase +import com.squirtles.musicroad.pick.DETAIL_PICK_TAB import com.squirtles.musicroad.utils.throttleFirst import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.async diff --git a/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt index ed216207..f059607b 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt @@ -1,7 +1,5 @@ package com.squirtles.musicroad.pick -import DialogTextButton -import MessageAlertDialog import android.app.Activity import android.content.Context import android.widget.Toast @@ -62,7 +60,6 @@ import com.squirtles.musicroad.common.HorizontalSpacer import com.squirtles.musicroad.common.MessageAlertDialog import com.squirtles.musicroad.common.VerticalSpacer import com.squirtles.musicroad.detail.DetailViewModel -import com.squirtles.musicroad.media.PlayerServiceViewModel import com.squirtles.musicroad.detail.DetailViewModel.Companion.DEFAULT_PICK import com.squirtles.musicroad.detail.FavoriteAction import com.squirtles.musicroad.detail.PickDetailUiState @@ -74,6 +71,7 @@ import com.squirtles.musicroad.detail.components.PickInformation import com.squirtles.musicroad.detail.components.SongInfo import com.squirtles.musicroad.detail.components.music.MusicPlayer import com.squirtles.musicroad.detail.components.music.visualizer.BaseVisualizer +import com.squirtles.musicroad.media.PlayerServiceViewModel import com.squirtles.musicroad.ui.theme.Black import com.squirtles.musicroad.ui.theme.Primary import com.squirtles.musicroad.ui.theme.White @@ -286,10 +284,6 @@ fun PickDetailScreen( onDismissRequest = { showDeletePickDialog = false }, - onDeletion = { - showDeletePickDialog = false - detailViewModel.deletePick(pickId) - } title = stringResource(R.string.delete_pick_dialog_title), body = stringResource(R.string.delete_pick_dialog_body), buttons = { @@ -305,7 +299,7 @@ fun PickDetailScreen( DialogTextButton( onClick = { showDeletePickDialog = false - pickViewModel.deletePick(pickId) + detailViewModel.deletePick(pickId) }, text = stringResource(R.string.delete_pick_dialog_delete), textColor = Primary, diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt index 8fd5bb7f..21cc5eac 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt @@ -10,15 +10,14 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.navigation import androidx.navigation.navArgument -import com.squirtles.musicroad.create.CreatePickScreen import com.squirtles.musicroad.create.CreatePickViewModel import com.squirtles.musicroad.create.SearchMusicScreen +import com.squirtles.musicroad.favorite.FavoriteScreen import com.squirtles.musicroad.map.MapScreen import com.squirtles.musicroad.map.MapViewModel import com.squirtles.musicroad.media.PlayerServiceViewModel -import com.squirtles.musicroad.detail.PickDetailScreen -import com.squirtles.musicroad.favorite.FavoriteScreen import com.squirtles.musicroad.mypick.MyPickScreen +import com.squirtles.musicroad.pick.PickDetailScreen import com.squirtles.musicroad.profile.screen.ProfileScreen import com.squirtles.musicroad.profile.screen.SettingNotificationScreen import com.squirtles.musicroad.profile.screen.SettingProfileScreen diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt index d4336ab0..ac6a46a6 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt @@ -6,12 +6,12 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.toRoute -import com.squirtles.musicroad.detail.PickDetailScreen import com.squirtles.musicroad.map.MapScreen import com.squirtles.musicroad.map.MapViewModel import com.squirtles.musicroad.media.PlayerServiceViewModel import com.squirtles.musicroad.navigation.MapRoute import com.squirtles.musicroad.navigation.Route +import com.squirtles.musicroad.pick.PickDetailScreen fun NavController.navigateMap(navOptions: NavOptions? = null) { navigate(Route.Map, navOptions) From 6a076eead3f19b8a739c643be576c9f467440ae0 Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 23 Jan 2025 21:46:22 +0900 Subject: [PATCH 16/46] =?UTF-8?q?[refactor]=20=EB=B9=A0=EC=A7=84=20?= =?UTF-8?q?=EB=A3=A8=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 프로필설정, 알람설정 --- .../profile/navigation/ProfileNavigation.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt b/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt index be187715..41f22e57 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt @@ -8,6 +8,8 @@ import androidx.navigation.toRoute import com.squirtles.musicroad.navigation.MainRoute import com.squirtles.musicroad.navigation.ProfileRoute import com.squirtles.musicroad.profile.screen.ProfileScreen +import com.squirtles.musicroad.profile.screen.SettingNotificationScreen +import com.squirtles.musicroad.profile.screen.SettingProfileScreen fun NavController.navigateProfile(userId: String, navOptions: NavOptions? = null) { navigate(MainRoute.Profile(userId), navOptions) @@ -42,4 +44,16 @@ fun NavGraphBuilder.profileNavGraph( onSettingNotificationClick = onSettingNotificationClick, ) } + + composable { backStackEntry -> + SettingProfileScreen( + onBackClick = onBackClick, + ) + } + + composable { backStackEntry -> + SettingNotificationScreen( + onBackClick = onBackClick + ) + } } From 0b901f160fa531d99691726ba0ac1bf03be56da5 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 24 Jan 2025 20:32:53 +0900 Subject: [PATCH 17/46] =?UTF-8?q?[refactor]=20=EC=8B=A4=ED=96=89=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../squirtles/musicroad/main/MainActivity.kt | 1 - .../squirtles/musicroad/main/MainViewModel.kt | 21 ++----------------- .../com/squirtles/musicroad/map/MapScreen.kt | 3 +-- .../squirtles/musicroad/map/MapViewModel.kt | 4 ---- .../musicroad/map/components/MapBottomBar.kt | 12 ++++------- .../musicroad/map/navigation/NavTab.kt | 19 +++++++---------- 6 files changed, 14 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt b/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt index 5ea7acf2..f2ace62c 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt @@ -28,7 +28,6 @@ import com.squirtles.musicroad.R import com.squirtles.musicroad.main.navigation.MainNavHost import com.squirtles.musicroad.main.navigation.MainNavigator import com.squirtles.musicroad.main.navigation.rememberMainNavigator -import com.squirtles.musicroad.main.navigations.MainNavGraph import com.squirtles.musicroad.main.navigations.MainNavigationActions import com.squirtles.musicroad.ui.theme.MusicRoadTheme import dagger.hilt.android.AndroidEntryPoint diff --git a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt index 6ff045a6..800e7876 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt @@ -1,16 +1,14 @@ package com.squirtles.musicroad.main -import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.firebase.FirebaseException -import com.squirtles.domain.usecase.user.GetUserIdFromDataStoreUseCase import com.squirtles.domain.usecase.user.CreateNewUserUseCase import com.squirtles.domain.usecase.user.FetchUserUseCase +import com.squirtles.domain.usecase.user.GetUserIdFromDataStoreUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch import javax.inject.Inject @@ -28,24 +26,9 @@ class MainViewModel @Inject constructor( val canRequestPermission get() = _canRequestPermission init { -// viewModelScope.launch { -// getUserIdFromDataStoreUseCase() -// .catch { e -> -// Log.e("MainViewModel", "Error collecting flow: $e") -// } -// .collect { localUid -> -// Log.d("MainViewModel", "localUid: $localUid") -// if (localUid == null) { -// createUser() -// } else { -// fetchUser(localUid) -// } -// } -// } - viewModelScope.launch { val userId = getUserIdFromDataStoreUseCase() - if(userId == null) { + if (userId == null) { createUser() } else { fetchUser(userId) diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt index 90a2dcf8..367cfe13 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt @@ -25,10 +25,10 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.squirtles.musicroad.common.VerticalSpacer import com.squirtles.musicroad.main.MainActivity -import com.squirtles.musicroad.map.components.MapBottomBar import com.squirtles.musicroad.map.components.ClusterBottomSheet import com.squirtles.musicroad.map.components.InfoWindow import com.squirtles.musicroad.map.components.LoadingDialog +import com.squirtles.musicroad.map.components.MapBottomBar import com.squirtles.musicroad.map.components.PickNotificationBanner import com.squirtles.musicroad.media.PlayerServiceViewModel @@ -125,7 +125,6 @@ fun MapScreen( MapBottomBar( modifier = Modifier.padding(bottom = 16.dp), - userId = mapViewModel.getUserId(), lastLocation = lastLocation, onFavoriteClick = { onFavoriteClick(mapViewModel.getUserId()) diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt b/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt index cc92fefa..163861e2 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapViewModel.kt @@ -59,10 +59,6 @@ class MapViewModel @Inject constructor( // Firestore 데이터 쿼리 작업 최소화 및 위치데이터 공유 용도 val lastLocation: StateFlow = getLastLocationUseCase() - init { - Log.d("MapViewModel", "init") - } - fun getUserId() = getCurrentUserUseCase().userId fun setLastCameraPosition(cameraPosition: CameraPosition) { diff --git a/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt b/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt index f2a81f25..fc830aa3 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt @@ -27,18 +27,16 @@ import com.squirtles.musicroad.R import com.squirtles.musicroad.map.BottomNavigationIconSize import com.squirtles.musicroad.map.BottomNavigationSize import com.squirtles.musicroad.map.navigation.NavTab -import com.squirtles.musicroad.navigation.MainRoute import com.squirtles.musicroad.ui.theme.MusicRoadTheme import com.squirtles.musicroad.ui.theme.Primary @Composable internal fun MapBottomBar( modifier: Modifier = Modifier, - userId: String, lastLocation: Location?, onFavoriteClick: () -> Unit, onCenterClick: () -> Unit, - onProfileClick: () -> Unit + onProfileClick: () -> Unit, ) { Box( modifier = modifier, @@ -56,7 +54,7 @@ internal fun MapBottomBar( .weight(1f) .fillMaxHeight() .padding(end = BottomNavigationSize.HORIZONTAL_PADDING.size.dp), - tab = NavTab.Favorite(MainRoute.Favorite(userId)), + tab = NavTab.FAVORITE, painter = null, tint = Primary, onClick = onFavoriteClick @@ -68,7 +66,7 @@ internal fun MapBottomBar( .weight(1f) .fillMaxHeight() .padding(start = BottomNavigationSize.HORIZONTAL_PADDING.size.dp), - tab = NavTab.Profile(MainRoute.Profile(userId)), + tab = NavTab.PROFILE, painter = null, tint = Primary, onClick = onProfileClick @@ -85,7 +83,7 @@ internal fun MapBottomBar( MaterialTheme.colorScheme.primary } ?: Color.Gray ), - tab = NavTab.Search, + tab = NavTab.SEARCH, painter = painterResource(R.drawable.ic_musical_note_64), tint = MaterialTheme.colorScheme.onPrimary, onClick = onCenterClick @@ -120,7 +118,6 @@ private fun MapBottomNavigationItem( fun BottomNavigationLightPreview() { MusicRoadTheme { MapBottomBar( - userId = "", onFavoriteClick = {}, lastLocation = null, onCenterClick = {}, @@ -134,7 +131,6 @@ fun BottomNavigationLightPreview() { fun BottomNavigationDarkPreview() { MusicRoadTheme { MapBottomBar( - userId = "", onFavoriteClick = {}, lastLocation = null, onCenterClick = {}, diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt index 4f7853e0..63721b07 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt @@ -8,32 +8,27 @@ import androidx.compose.material.icons.outlined.MusicNote import androidx.compose.ui.graphics.vector.ImageVector import com.squirtles.musicroad.R import com.squirtles.musicroad.map.BottomNavigationIconSize -import com.squirtles.musicroad.navigation.MainRoute -internal sealed class NavTab( +internal enum class NavTab( @StringRes val contentDescription: Int, val icon: ImageVector, val iconSize: Int?, - val route: MainRoute, ) { - data class Favorite(val favoriteRoute: MainRoute.Favorite) : NavTab( + FAVORITE( contentDescription = R.string.map_navigation_favorite_icon_description, icon = Icons.Default.FavoriteBorder, iconSize = null, - route = favoriteRoute - ) + ), - data class Profile(val profileRoute: MainRoute.Profile) : NavTab( + PROFILE( contentDescription = R.string.map_navigation_setting_icon_description, icon = Icons.Outlined.AccountCircle, iconSize = null, - route = profileRoute - ) + ), - data object Search : NavTab( + SEARCH( contentDescription = R.string.map_navigation_center_icon_description, icon = Icons.Outlined.MusicNote, iconSize = BottomNavigationIconSize.CENTER_ICON.size, - route = MainRoute.Search - ) + ), } From ad911da03dd8bada58083ab4ce78eca6cb6e16b8 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 24 Jan 2025 23:13:57 +0900 Subject: [PATCH 18/46] =?UTF-8?q?[refactor]=20MapBottomBar=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -> MapBottomNavBar --- app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt | 4 ++-- .../map/components/{MapBottomBar.kt => MapBottomNavBar.kt} | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) rename app/src/main/java/com/squirtles/musicroad/map/components/{MapBottomBar.kt => MapBottomNavBar.kt} (98%) diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt index 367cfe13..445c6bc4 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt @@ -28,7 +28,7 @@ import com.squirtles.musicroad.main.MainActivity import com.squirtles.musicroad.map.components.ClusterBottomSheet import com.squirtles.musicroad.map.components.InfoWindow import com.squirtles.musicroad.map.components.LoadingDialog -import com.squirtles.musicroad.map.components.MapBottomBar +import com.squirtles.musicroad.map.components.MapBottomNavBar import com.squirtles.musicroad.map.components.PickNotificationBanner import com.squirtles.musicroad.media.PlayerServiceViewModel @@ -123,7 +123,7 @@ fun MapScreen( VerticalSpacer(16) - MapBottomBar( + MapBottomNavBar( modifier = Modifier.padding(bottom = 16.dp), lastLocation = lastLocation, onFavoriteClick = { diff --git a/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt b/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomNavBar.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt rename to app/src/main/java/com/squirtles/musicroad/map/components/MapBottomNavBar.kt index fc830aa3..4ce12a32 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomBar.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomNavBar.kt @@ -31,7 +31,7 @@ import com.squirtles.musicroad.ui.theme.MusicRoadTheme import com.squirtles.musicroad.ui.theme.Primary @Composable -internal fun MapBottomBar( +internal fun MapBottomNavBar( modifier: Modifier = Modifier, lastLocation: Location?, onFavoriteClick: () -> Unit, @@ -117,7 +117,7 @@ private fun MapBottomNavigationItem( @Composable fun BottomNavigationLightPreview() { MusicRoadTheme { - MapBottomBar( + MapBottomNavBar( onFavoriteClick = {}, lastLocation = null, onCenterClick = {}, @@ -130,7 +130,7 @@ fun BottomNavigationLightPreview() { @Composable fun BottomNavigationDarkPreview() { MusicRoadTheme { - MapBottomBar( + MapBottomNavBar( onFavoriteClick = {}, lastLocation = null, onCenterClick = {}, From b4e220f3b740dc170c792949777fa6e4fc58e074 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sat, 25 Jan 2025 21:37:54 +0900 Subject: [PATCH 19/46] [refactor] encode --- .../squirtles/musicroad/navigation/SearchRoute.kt | 13 ++++++++++++- .../musicroad/search/navigation/SearchNavigation.kt | 13 ++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt index f4a6bc6f..1765ecea 100644 --- a/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt +++ b/app/src/main/java/com/squirtles/musicroad/navigation/SearchRoute.kt @@ -1,10 +1,21 @@ package com.squirtles.musicroad.navigation +import androidx.lifecycle.SavedStateHandle +import androidx.navigation.toRoute import com.squirtles.domain.model.Song +import com.squirtles.musicroad.utils.serializableType import kotlinx.serialization.Serializable +import kotlin.reflect.typeOf @Serializable sealed interface SearchRoute : Route { @Serializable - data class Create(val song: Song) : SearchRoute + data class Create(val song: Song) : SearchRoute { + companion object { + val typeMap = mapOf(typeOf() to serializableType()) + + fun from(savedStateHandle: SavedStateHandle) = + savedStateHandle.toRoute(typeMap) + } + } } diff --git a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt index e3e2bb4d..2b1e9f59 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt @@ -11,14 +11,21 @@ import com.squirtles.musicroad.navigation.MainRoute import com.squirtles.musicroad.navigation.SearchRoute import com.squirtles.musicroad.search.SearchMusicScreen import com.squirtles.musicroad.utils.serializableType +import java.net.URLEncoder +import java.nio.charset.StandardCharsets import kotlin.reflect.typeOf fun NavController.navigateSearch(navOptions: NavOptions? = null) { navigate(MainRoute.Search, navOptions) } -fun NavController.navigateCreate(song: Song, navOptions: NavOptions? = null) { - navigate(SearchRoute.Create(song), navOptions) +fun NavController.navigateCreate(song: Song, navOptions: NavOptions? = null) { + val encodedSong = song.copy( + previewUrl = "", + externalUrl = "", + imageUrl = URLEncoder.encode(song.imageUrl, StandardCharsets.UTF_8.toString()) + ) + navigate(SearchRoute.Create(encodedSong), navOptions) } fun NavGraphBuilder.searchNavGraph( @@ -33,7 +40,7 @@ fun NavGraphBuilder.searchNavGraph( ) } composable( - typeMap = mapOf(typeOf() to serializableType()) + typeMap = SearchRoute.Create.typeMap ) { backStackEntry -> val song = backStackEntry.toRoute().song From dbfea3424a0269d3626bcb9adbe11dec58ed5cca Mon Sep 17 00:00:00 2001 From: miller198 Date: Sat, 25 Jan 2025 22:31:04 +0900 Subject: [PATCH 20/46] =?UTF-8?q?[fix]=20illegalArgumentsException=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/search/navigation/SearchNavigation.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt index 2b1e9f59..07b702ed 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt @@ -1,5 +1,6 @@ package com.squirtles.musicroad.search.navigation +import android.util.Log import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions @@ -10,10 +11,8 @@ import com.squirtles.musicroad.create.CreatePickScreen import com.squirtles.musicroad.navigation.MainRoute import com.squirtles.musicroad.navigation.SearchRoute import com.squirtles.musicroad.search.SearchMusicScreen -import com.squirtles.musicroad.utils.serializableType import java.net.URLEncoder import java.nio.charset.StandardCharsets -import kotlin.reflect.typeOf fun NavController.navigateSearch(navOptions: NavOptions? = null) { navigate(MainRoute.Search, navOptions) @@ -23,8 +22,12 @@ fun NavController.navigateCreate(song: Song, navOptions: NavOptions? = null) { val encodedSong = song.copy( previewUrl = "", externalUrl = "", + genreNames = emptyList(), imageUrl = URLEncoder.encode(song.imageUrl, StandardCharsets.UTF_8.toString()) ) + + Log.d("SearchNavigation", "original: $song") + Log.d("SearchNavigation", "encoded: $encodedSong") navigate(SearchRoute.Create(encodedSong), navOptions) } @@ -44,6 +47,8 @@ fun NavGraphBuilder.searchNavGraph( ) { backStackEntry -> val song = backStackEntry.toRoute().song + Log.d("SearchNavigation", "received: $song") + CreatePickScreen( song = song, onBackClick = onBackClick, From 13d40b9cde422b5460ff61effa523426793ff28e Mon Sep 17 00:00:00 2001 From: miller198 Date: Sat, 25 Jan 2025 22:42:59 +0900 Subject: [PATCH 21/46] =?UTF-8?q?[style]=20log=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/search/navigation/SearchNavigation.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt index 07b702ed..15eb445a 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt @@ -1,6 +1,5 @@ package com.squirtles.musicroad.search.navigation -import android.util.Log import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions @@ -25,9 +24,6 @@ fun NavController.navigateCreate(song: Song, navOptions: NavOptions? = null) { genreNames = emptyList(), imageUrl = URLEncoder.encode(song.imageUrl, StandardCharsets.UTF_8.toString()) ) - - Log.d("SearchNavigation", "original: $song") - Log.d("SearchNavigation", "encoded: $encodedSong") navigate(SearchRoute.Create(encodedSong), navOptions) } @@ -47,8 +43,6 @@ fun NavGraphBuilder.searchNavGraph( ) { backStackEntry -> val song = backStackEntry.toRoute().song - Log.d("SearchNavigation", "received: $song") - CreatePickScreen( song = song, onBackClick = onBackClick, From 35ad24359c80c09a0df5a703c538724a822c3332 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sat, 25 Jan 2025 23:54:52 +0900 Subject: [PATCH 22/46] =?UTF-8?q?[refactor]=20saveStateHandle=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9,=20=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/create/CreatePickViewModel.kt | 123 ++----- .../musicroad/create/SearchMusicScreen.kt | 340 ------------------ .../musicroad/search/SearchMusicScreen.kt | 1 - .../musicroad/search/SearchViewModel.kt | 9 - .../search/navigation/SearchNavigation.kt | 6 +- 5 files changed, 41 insertions(+), 438 deletions(-) delete mode 100644 app/src/main/java/com/squirtles/musicroad/create/SearchMusicScreen.kt diff --git a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt index 7cb55587..1a039a68 100644 --- a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt @@ -2,34 +2,33 @@ package com.squirtles.musicroad.create import android.location.Location import android.util.Log +import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import androidx.paging.PagingData -import androidx.paging.cachedIn +import androidx.navigation.toRoute import com.squirtles.domain.model.Creator import com.squirtles.domain.model.LocationPoint import com.squirtles.domain.model.Pick import com.squirtles.domain.model.Song import com.squirtles.domain.usecase.location.GetLastLocationUseCase -import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.music.FetchMusicVideoUseCase import com.squirtles.domain.usecase.music.FetchSongsUseCase import com.squirtles.domain.usecase.mypick.CreatePickUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase +import com.squirtles.musicroad.navigation.SearchRoute import com.squirtles.musicroad.utils.throttleFirst import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.launch import javax.inject.Inject @OptIn(FlowPreview::class) @HiltViewModel class CreatePickViewModel @Inject constructor( + savedStateHandle: SavedStateHandle, getLastLocationUseCase: GetLastLocationUseCase, private val fetchSongsUseCase: FetchSongsUseCase, private val fetchMusicVideoUseCase: FetchMusicVideoUseCase, @@ -37,22 +36,8 @@ class CreatePickViewModel @Inject constructor( private val getCurrentUserUseCase: GetCurrentUserUseCase ) : ViewModel() { - // SearchMusicScreen - private val _searchUiState = MutableStateFlow(SearchUiState.HotResult) - val searchUiState = _searchUiState.asStateFlow() - - private val _searchResult = MutableStateFlow>(PagingData.empty()) - val searchResult = _searchResult.asStateFlow() - - private var _selectedSong: Song? = null - val selectedSong get() = _selectedSong - - private val _searchText = MutableStateFlow("") - val searchText = _searchText.asStateFlow() - - private var searchJob: Job? = null + private val song = savedStateHandle.toRoute(SearchRoute.Create.typeMap).song - // CreatePickScreen private val _createPickUiState = MutableStateFlow>(CreateUiState.Default) val createPickUiState = _createPickUiState.asStateFlow() @@ -70,42 +55,16 @@ class CreatePickViewModel @Inject constructor( } } - viewModelScope.launch { - _searchText - .debounce(300) - .collect { searchKeyword -> - searchJob?.cancel() - if (searchKeyword.isNotBlank()) { - searchJob = launch { searchSongs(searchKeyword) } - } else { - _searchUiState.emit(SearchUiState.HotResult) - } - } - } - // 등록 버튼 클릭 후 3초 이내의 클릭은 무시하고 픽 생성하기 viewModelScope.launch { createPickClick .throttleFirst(3000) .collect { - createPick() + createPick(song) } } } - private suspend fun searchSongs(searchKeyword: String) { - fetchSongsUseCase(searchKeyword) - .cachedIn(viewModelScope) - .collectLatest { - _searchResult.emit(it) - _searchUiState.emit(SearchUiState.SearchResult) - } - } - - fun onSongItemClick(song: Song) { - _selectedSong = song - } - fun onCommentChange(text: String) { _comment.value = text } @@ -114,51 +73,45 @@ class CreatePickViewModel @Inject constructor( _comment.value = "" } - fun onSearchTextChange(text: String) { - _searchText.value = text - } - fun onCreatePickClick() { viewModelScope.launch { createPickClick.emit(Unit) } } - private fun createPick() { - _selectedSong?.let { song -> - viewModelScope.launch { - if (lastLocation == null) { - /* TODO: DEFAULT 인 경우 -> LocalDataSource 위치 데이터 못 불러옴 */ - return@launch - } - - val musicVideo = fetchMusicVideoUseCase(song) + private fun createPick(song: Song) { + viewModelScope.launch { + if (lastLocation == null) { + /* TODO: DEFAULT 인 경우 -> LocalDataSource 위치 데이터 못 불러옴 */ + return@launch + } - /* 등록 결과 - pick ID 담긴 Result */ - val user = getCurrentUserUseCase() - val createResult = createPickUseCase( - Pick( - id = "", - song = song, - comment = _comment.value, - createdAt = "", - createdBy = Creator( - userId = user.userId, - userName = user.userName - ), - location = LocationPoint(lastLocation!!.latitude, lastLocation!!.longitude), - musicVideoUrl = musicVideo?.previewUrl ?: "", - musicVideoThumbnailUrl = musicVideo?.thumbnailUrl ?: "" - ) + val musicVideo = fetchMusicVideoUseCase(song) + + /* 등록 결과 - pick ID 담긴 Result */ + val user = getCurrentUserUseCase() + val createResult = createPickUseCase( + Pick( + id = "", + song = song, + comment = _comment.value, + createdAt = "", + createdBy = Creator( + userId = user.userId, + userName = user.userName + ), + location = LocationPoint(lastLocation!!.latitude, lastLocation!!.longitude), + musicVideoUrl = musicVideo?.previewUrl ?: "", + musicVideoThumbnailUrl = musicVideo?.thumbnailUrl ?: "" ) - - createResult.onSuccess { pickId -> - _createPickUiState.emit(CreateUiState.Success(pickId)) - }.onFailure { - /* TODO: Firestore 등록 실패처리 */ - _createPickUiState.emit(CreateUiState.Error) - Log.d("CreatePickViewModel", createResult.exceptionOrNull()?.message.toString()) - } + ) + + createResult.onSuccess { pickId -> + _createPickUiState.emit(CreateUiState.Success(pickId)) + }.onFailure { + /* TODO: Firestore 등록 실패처리 */ + _createPickUiState.emit(CreateUiState.Error) + Log.d("CreatePickViewModel", createResult.exceptionOrNull()?.message.toString()) } } } diff --git a/app/src/main/java/com/squirtles/musicroad/create/SearchMusicScreen.kt b/app/src/main/java/com/squirtles/musicroad/create/SearchMusicScreen.kt deleted file mode 100644 index 076be54a..00000000 --- a/app/src/main/java/com/squirtles/musicroad/create/SearchMusicScreen.kt +++ /dev/null @@ -1,340 +0,0 @@ -package com.squirtles.musicroad.create - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.navigationBars -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.statusBars -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.LinearProgressIndicator -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.material3.TextFieldDefaults -import androidx.compose.material3.ripple -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.focus.FocusManager -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.paging.LoadState -import androidx.paging.compose.LazyPagingItems -import androidx.paging.compose.collectAsLazyPagingItems -import com.squirtles.domain.model.Song -import com.squirtles.musicroad.R -import com.squirtles.musicroad.common.AlbumImage -import com.squirtles.musicroad.common.Constants.COLOR_STOPS -import com.squirtles.musicroad.common.Constants.REQUEST_IMAGE_SIZE_DEFAULT -import com.squirtles.musicroad.common.HorizontalSpacer -import com.squirtles.musicroad.common.VerticalSpacer -import com.squirtles.musicroad.ui.theme.Gray -import com.squirtles.musicroad.ui.theme.White - -@Composable -fun SearchMusicScreen( - createPickViewModel: CreatePickViewModel, - onBackClick: () -> Boolean, - onItemClick: () -> Unit, -) { - val focusManager = LocalFocusManager.current - val searchText by createPickViewModel.searchText.collectAsStateWithLifecycle() - val searchUiState by createPickViewModel.searchUiState.collectAsStateWithLifecycle() - val searchResult = createPickViewModel.searchResult.collectAsLazyPagingItems() - - Scaffold( - contentWindowInsets = WindowInsets.navigationBars, - topBar = { - Box( - modifier = Modifier - .fillMaxWidth() - .padding(WindowInsets.statusBars.asPaddingValues()) - .padding(top = 16.dp) - ) { - SearchTopBar( - keyword = searchText, - onValueChange = createPickViewModel::onSearchTextChange, - onBackClick = onBackClick, - focusManager = focusManager - ) - } - }, - ) { innerPadding -> - - Box( - modifier = Modifier - .fillMaxSize() - .background(Brush.verticalGradient(colorStops = COLOR_STOPS)) - .padding(innerPadding) - .addFocusCleaner(focusManager) - ) { - if (searchResult.loadState.refresh is LoadState.Loading || - searchResult.loadState.append is LoadState.Loading - ) { - LinearProgressIndicator( - modifier = Modifier - .fillMaxWidth() - .padding(top = 10.dp), - trackColor = Gray - ) - } - - // 검색 결과 - when (searchUiState) { - is SearchUiState.HotResult -> { - // TODO HOT 리스트 - } - - is SearchUiState.SearchResult -> { - SearchResult( - searchResult = searchResult, - onItemClick = { song -> - createPickViewModel.onSongItemClick(song) - focusManager.clearFocus() - onItemClick() - } - ) - } - } - } - } -} - -@Composable -private fun SearchTopBar( - keyword: String, - onValueChange: (String) -> Unit, - onBackClick: () -> Boolean, - focusManager: FocusManager -) { - - Row( - modifier = Modifier - .fillMaxWidth() - .height(SearchBarHeight) - .padding(end = DefaultPadding), - verticalAlignment = Alignment.CenterVertically - ) { - IconButton( - onClick = { - onBackClick() - }, - modifier = Modifier.padding(start = 4.dp) - ) { - Icon( - imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(id = R.string.top_app_bar_back_description), - tint = White - ) - } - HorizontalSpacer(8) - - OutlinedTextField( - value = keyword, - onValueChange = onValueChange, - modifier = Modifier.weight(1f), - placeholder = { - Text(stringResource(id = R.string.search)) - }, - // 키보드 완료버튼 -> Search로 변경, 누르면 Search 동작 실행 - keyboardOptions = KeyboardOptions( - keyboardType = KeyboardType.Text, - imeAction = ImeAction.Search - ), - keyboardActions = KeyboardActions( - onSearch = { - focusManager.clearFocus() - } - ), - singleLine = true, - shape = CircleShape, - colors = TextFieldDefaults.colors( - focusedTextColor = White, - unfocusedTextColor = White, - focusedContainerColor = Color.Transparent, - unfocusedContainerColor = Color.Transparent, - cursorColor = White, - focusedIndicatorColor = White, - unfocusedIndicatorColor = White, - focusedPlaceholderColor = Gray, - unfocusedPlaceholderColor = White - ) - ) - } -} - -@Composable -private fun SearchResult( - searchResult: LazyPagingItems, - onItemClick: (Song) -> Unit -) { - Column( - modifier = Modifier.fillMaxSize() - ) { - VerticalSpacer(20) - - TextWithColorAndStyle( - text = stringResource(id = R.string.result), - textColor = White, - textStyle = MaterialTheme.typography.titleLarge, - modifier = Modifier.padding(start = DefaultPadding) - ) - VerticalSpacer(20) - - LazyColumn(modifier = Modifier.padding(bottom = DefaultPadding)) { - items(searchResult.itemCount) { index -> - searchResult[index]?.let { - SongItem(it) { - onItemClick(it) - } - } - } - } - - if (searchResult.loadState.refresh is LoadState.NotLoading) { - if (searchResult.itemCount == 0) { - Text( - text = stringResource(id = R.string.search_music_empty_description), - modifier = Modifier.padding(horizontal = DefaultPadding), - color = White - ) - } - } else if (searchResult.loadState.refresh is LoadState.Error) { - Text( - text = stringResource(id = R.string.search_music_error_description), - modifier = Modifier.padding(horizontal = DefaultPadding), - color = White - ) - } - } -} - -@Composable -private fun SongItem( - song: Song, - onItemClick: () -> Unit, -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = ripple(color = White), - ) { - onItemClick() - } - .padding(horizontal = DefaultPadding, vertical = ItemSpacing / 2), - verticalAlignment = Alignment.CenterVertically - ) { - AlbumImage( - imageUrl = song.getImageUrlWithSize(REQUEST_IMAGE_SIZE_DEFAULT), - modifier = Modifier - .size(ImageSize) - .clip(RoundedCornerShape(16.dp)) - ) - - HorizontalSpacer(16) - Column { - TextWithColorAndStyle( - text = song.songName, - textColor = White, - textStyle = MaterialTheme.typography.bodyLarge - ) - TextWithColorAndStyle( - text = song.artistName, - textColor = Gray, - textStyle = MaterialTheme.typography.bodyMedium - ) - TextWithColorAndStyle( - text = song.albumName, - textColor = Gray, - textStyle = MaterialTheme.typography.bodyMedium - ) - } - } -} - -@Composable -fun TextWithColorAndStyle( - text: String, - textColor: Color, - textStyle: TextStyle, - modifier: Modifier = Modifier -) { - Text( - text = text, - modifier = modifier, - color = textColor, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = textStyle - ) -} - -fun Modifier.addFocusCleaner(focusManager: FocusManager, doOnClear: () -> Unit = {}): Modifier { - return this.pointerInput(Unit) { - detectTapGestures( - onTap = { - doOnClear() - focusManager.clearFocus() - } - ) - } -} - -@Preview -@Composable -fun SongItemPreview() { - val song = Song( - id = "1", - songName = "Ditto", - artistName = "String", - albumName = "Ditto", - imageUrl = "https://i.scdn.co/image/ab67616d0000b2733d98a0ae7c78a3a9babaf8af", - genreNames = listOf(), - bgColor = android.graphics.Color.RED, - externalUrl = "", - previewUrl = "", - ) - SongItem(song) { - - } -} - -private val SearchBarHeight = 56.dp -private val DefaultPadding = 16.dp -private val ItemSpacing = 24.dp -private val ImageSize = 56.dp diff --git a/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt b/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt index 220ddc3b..8002bceb 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt @@ -124,7 +124,6 @@ fun SearchMusicScreen( SearchResult( searchResult = searchResult, onItemClick = { song -> - searchViewModel.onSongItemClick(song) focusManager.clearFocus() onItemClick(song) } diff --git a/app/src/main/java/com/squirtles/musicroad/search/SearchViewModel.kt b/app/src/main/java/com/squirtles/musicroad/search/SearchViewModel.kt index b67a4a93..5e3a7905 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/SearchViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/SearchViewModel.kt @@ -23,16 +23,12 @@ class SearchViewModel @Inject constructor( private val fetchSongsUseCase: FetchSongsUseCase, ) : ViewModel() { - // SearchMusicScreen private val _searchUiState = MutableStateFlow(SearchUiState.HotResult) val searchUiState = _searchUiState.asStateFlow() private val _searchResult = MutableStateFlow>(PagingData.empty()) val searchResult = _searchResult.asStateFlow() - private var _selectedSong: Song? = null - val selectedSong get() = _selectedSong - private val _searchText = MutableStateFlow("") val searchText = _searchText.asStateFlow() @@ -62,12 +58,7 @@ class SearchViewModel @Inject constructor( } } - fun onSongItemClick(song: Song) { - _selectedSong = song - } - fun onSearchTextChange(text: String) { _searchText.value = text } - } diff --git a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt index 15eb445a..b46e2049 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/navigation/SearchNavigation.kt @@ -19,9 +19,9 @@ fun NavController.navigateSearch(navOptions: NavOptions? = null) { fun NavController.navigateCreate(song: Song, navOptions: NavOptions? = null) { val encodedSong = song.copy( - previewUrl = "", - externalUrl = "", - genreNames = emptyList(), + previewUrl = URLEncoder.encode(song.previewUrl, StandardCharsets.UTF_8.toString()), + externalUrl = URLEncoder.encode(song.externalUrl, StandardCharsets.UTF_8.toString()), + genreNames = song.genreNames.map { URLEncoder.encode(it, StandardCharsets.UTF_8.toString()) }, imageUrl = URLEncoder.encode(song.imageUrl, StandardCharsets.UTF_8.toString()) ) navigate(SearchRoute.Create(encodedSong), navOptions) From fcd0dd8a0a857987bdfe4c5145aa4329fe91dc87 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 26 Jan 2025 00:38:01 +0900 Subject: [PATCH 23/46] =?UTF-8?q?[refactor]=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../squirtles/musicroad/main/MainActivity.kt | 5 +- .../main/navigations/Destinations.kt | 31 ---- .../main/navigations/MainNavGraph.kt | 148 ------------------ .../main/navigations/MainNavigationActions.kt | 50 ------ 4 files changed, 1 insertion(+), 233 deletions(-) delete mode 100644 app/src/main/java/com/squirtles/musicroad/main/navigations/Destinations.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigationActions.kt diff --git a/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt b/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt index f2ace62c..fd34e943 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/MainActivity.kt @@ -28,7 +28,6 @@ import com.squirtles.musicroad.R import com.squirtles.musicroad.main.navigation.MainNavHost import com.squirtles.musicroad.main.navigation.MainNavigator import com.squirtles.musicroad.main.navigation.rememberMainNavigator -import com.squirtles.musicroad.main.navigations.MainNavigationActions import com.squirtles.musicroad.ui.theme.MusicRoadTheme import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.TimeoutCancellationException @@ -151,9 +150,7 @@ class MainActivity : AppCompatActivity() { MusicRoadTheme { val navController = rememberNavController() - val navigationActions = remember(navController) { - MainNavigationActions(navController) - } + MainNavHost( navigator = navigator, ) diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/Destinations.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/Destinations.kt deleted file mode 100644 index 718bdf65..00000000 --- a/app/src/main/java/com/squirtles/musicroad/main/navigations/Destinations.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.squirtles.musicroad.main.navigations - -object MainDestinations { - const val MAIN_ROUTE = "main" -} - -object CreatePickDestinations { - const val CREATE_ROUTE = "create" - const val SEARCH_MUSIC_ROUTE = "search_music" - const val CREATE_PICK_ROUTE = "create_pick" -} - -object ProfileDestination { - private const val PROFILE_ROUTE = "profile" - - private const val FAVORITE_PICKS_ROUTE = "favorite_picks" - private const val MY_PICKS_ROUTE = "my_picks" - - const val SETTING_PROFILE_ROUTE = "setting/profile" - const val SETTING_NOTIFICATION_ROUTE = "setting/notification" - - fun profile(userId: String) = "$PROFILE_ROUTE/$userId" - fun favoritePicks(userId: String) = "$FAVORITE_PICKS_ROUTE/$userId" - fun myPicks(userId: String) = "$MY_PICKS_ROUTE/$userId" -} - -object PickInfoDestinations { - private const val PICK_DETAIL_ROUTE = "pick_detail" - - fun pickDetail(pickId: String) = "$PICK_DETAIL_ROUTE/$pickId" -} diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt deleted file mode 100644 index 21cc5eac..00000000 --- a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavGraph.kt +++ /dev/null @@ -1,148 +0,0 @@ -package com.squirtles.musicroad.main.navigations - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.navigation.NavHostController -import androidx.navigation.NavType -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import androidx.navigation.compose.navigation -import androidx.navigation.navArgument -import com.squirtles.musicroad.create.CreatePickViewModel -import com.squirtles.musicroad.create.SearchMusicScreen -import com.squirtles.musicroad.favorite.FavoriteScreen -import com.squirtles.musicroad.map.MapScreen -import com.squirtles.musicroad.map.MapViewModel -import com.squirtles.musicroad.media.PlayerServiceViewModel -import com.squirtles.musicroad.mypick.MyPickScreen -import com.squirtles.musicroad.pick.PickDetailScreen -import com.squirtles.musicroad.profile.screen.ProfileScreen -import com.squirtles.musicroad.profile.screen.SettingNotificationScreen -import com.squirtles.musicroad.profile.screen.SettingProfileScreen - -@Composable -fun MainNavGraph( - modifier: Modifier = Modifier, - mapViewModel: MapViewModel = hiltViewModel(), - playerServiceViewModel: PlayerServiceViewModel = hiltViewModel(), - navController: NavHostController, - navigationActions: MainNavigationActions, -) { - NavHost( - navController = navController, - startDestination = MainDestinations.MAIN_ROUTE, - modifier = modifier - ) { - composable(MainDestinations.MAIN_ROUTE) { - MapScreen( - mapViewModel = mapViewModel, - playerServiceViewModel = playerServiceViewModel, - onFavoriteClick = { userId -> navigationActions.navigateToFavoritePicks(userId) }, - onCenterClick = navigationActions.navigateToSearch, - onProfileClick = { userId -> navigationActions.navigateToProfile(userId) }, - onPickSummaryClick = { pickId -> navigationActions.navigateToPickDetail(pickId) }, - ) - } - - composable( - route = ProfileDestination.favoritePicks("{userId}"), - arguments = listOf(navArgument("userId") { type = NavType.StringType }) - ) { backStackEntry -> - val userId = backStackEntry.arguments?.getString("userId") ?: "" - - FavoriteScreen( - userId = userId, - onBackClick = { navController.navigateUp() }, - onItemClick = { pickId -> navigationActions.navigateToPickDetail(pickId) } - ) - } - - composable( - route = ProfileDestination.myPicks("{userId}"), - arguments = listOf(navArgument("userId") { type = NavType.StringType }) - ) { backStackEntry -> - val userId = backStackEntry.arguments?.getString("userId") ?: "" - - MyPickScreen( - userId = userId, - onBackClick = { navController.navigateUp() }, - onItemClick = { pickId -> navigationActions.navigateToPickDetail(pickId) } - ) - } - - composable( - route = ProfileDestination.profile("{userId}"), - arguments = listOf(navArgument("userId") { type = NavType.StringType }) - ) { backStackEntry -> - val userId = backStackEntry.arguments?.getString("userId") ?: "" - - ProfileScreen( - userId = userId, - onBackClick = { navController.navigateUp() }, - onBackToMapClick = navigationActions.navigateToMain, - onFavoritePicksClick = { navigationActions.navigateToFavoritePicks(it) }, - onMyPicksClick = { navigationActions.navigateToMyPicks(it) }, - onSettingProfileClick = { navController.navigate(ProfileDestination.SETTING_PROFILE_ROUTE) }, - onSettingNotificationClick = { navController.navigate(ProfileDestination.SETTING_NOTIFICATION_ROUTE) }, - ) - } - - composable(ProfileDestination.SETTING_PROFILE_ROUTE) { - SettingProfileScreen(onBackClick = { navController.navigateUp() }) - } - - composable(ProfileDestination.SETTING_NOTIFICATION_ROUTE) { - SettingNotificationScreen(onBackClick = { navController.navigateUp() }) - } - - navigation( - startDestination = CreatePickDestinations.SEARCH_MUSIC_ROUTE, - route = CreatePickDestinations.CREATE_ROUTE - ) { - composable(CreatePickDestinations.SEARCH_MUSIC_ROUTE) { - val parentEntry = remember(it) { - navController.getBackStackEntry(CreatePickDestinations.CREATE_ROUTE) - } - SearchMusicScreen( - createPickViewModel = hiltViewModel(parentEntry), - onBackClick = { navController.navigateUp() }, - onItemClick = navigationActions.navigateToCreate - ) - } - - composable(CreatePickDestinations.CREATE_PICK_ROUTE) { - val parentEntry = remember(it) { - navController.getBackStackEntry(CreatePickDestinations.CREATE_ROUTE) - } -// CreatePickScreen( -// createPickViewModel = hiltViewModel(parentEntry), -// onBackClick = { navController.navigateUp() }, -// onCreateClick = { pickId -> navigationActions.navigateToPickDetail(pickId) } -// ) - } - } - - composable( - route = PickInfoDestinations.pickDetail("{pickId}"), - arguments = listOf(navArgument("pickId") { type = NavType.StringType }) - ) { backStackEntry -> - val pickId = backStackEntry.arguments?.getString("pickId") ?: "" - - PickDetailScreen( - pickId = pickId, - playerServiceViewModel = playerServiceViewModel, - onProfileClick = { userId -> navigationActions.navigateToProfile(userId) }, - onBackClick = { // 픽 등록에서 정보 화면으로 간 것이라면 뒤로 가기 시 메인으로, 아니라면 이전 화면으로 - if (navController.previousBackStackEntry?.destination?.route == CreatePickDestinations.CREATE_PICK_ROUTE) { - navigationActions.navigateToMain() - } else { - navController.navigateUp() - } - }, - onDeleted = { mapViewModel.resetClickedMarkerState(it) }, - ) - } - } -} diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigationActions.kt b/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigationActions.kt deleted file mode 100644 index 9af92604..00000000 --- a/app/src/main/java/com/squirtles/musicroad/main/navigations/MainNavigationActions.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.squirtles.musicroad.main.navigations - -import androidx.navigation.NavHostController - -class MainNavigationActions(navController: NavHostController) { - val navigateToMain: () -> Unit = { - navController.navigate(MainDestinations.MAIN_ROUTE) { - popUpTo(route = MainDestinations.MAIN_ROUTE) { - inclusive = true - } - launchSingleTop = true - } - } - - val navigateToFavoritePicks: (String) -> Unit = { userId -> - navController.navigate(ProfileDestination.favoritePicks(userId)) { - launchSingleTop = true - } - } - - val navigateToMyPicks: (String) -> Unit = { userId -> - navController.navigate(ProfileDestination.myPicks(userId)) { - launchSingleTop = true - } - } - - val navigateToProfile: (String) -> Unit = { userId -> - navController.navigate(ProfileDestination.profile(userId)) { - launchSingleTop = true - } - } - - val navigateToSearch: () -> Unit = { - navController.navigate(CreatePickDestinations.SEARCH_MUSIC_ROUTE) { - launchSingleTop = true - } - } - - val navigateToCreate: () -> Unit = { - navController.navigate(CreatePickDestinations.CREATE_PICK_ROUTE) { - launchSingleTop = true - } - } - - val navigateToPickDetail: (String) -> Unit = { pickId -> - navController.navigate(PickInfoDestinations.pickDetail(pickId)) { - launchSingleTop = true - } - } -} From 81a683ee967d1584b0100eb60e3264c525138470 Mon Sep 17 00:00:00 2001 From: miller198 Date: Mon, 27 Jan 2025 17:49:19 +0900 Subject: [PATCH 24/46] =?UTF-8?q?[refactor]=20Song=20=EC=88=9C=EC=88=98=20?= =?UTF-8?q?=EC=BD=94=ED=8B=80=EB=A6=B0=20=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 안드로이드 라이브러리 의존성 삭제 --- .../musicroad/common/picklist/PickListItem.kt | 2 +- .../com/squirtles/musicroad/create/CreatePickScreen.kt | 2 +- .../musicroad/detail/components/CircleAlbumCover.kt | 2 +- .../musicroad/map/components/ClusterBottomSheet.kt | 2 +- .../musicroad/map/components/InfoWindowCard.kt | 2 +- .../musicroad/map/marker/LeafMarkerIconView.kt | 2 +- .../java/com/squirtles/musicroad/picklist/PickItem.kt | 2 +- .../squirtles/musicroad/search/SearchMusicScreen.kt | 2 +- .../src/main/java/com/squirtles/domain/model/Song.kt | 10 ++++------ 9 files changed, 12 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt index 6920dd2d..aa9c98db 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt @@ -55,7 +55,7 @@ fun PickListItem( verticalAlignment = Alignment.CenterVertically ) { AlbumImage( - imageUrl = song.getImageUrlWithSize(Constants.REQUEST_IMAGE_SIZE_DEFAULT), + imageUrl = song.getImageUrlWithSize(Constants.REQUEST_IMAGE_SIZE_DEFAULT.width, Constants.REQUEST_IMAGE_SIZE_DEFAULT.height), modifier = Modifier .size(64.dp) .clip(RoundedCornerShape(8.dp)) diff --git a/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt b/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt index aa4e3709..ede83043 100644 --- a/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt @@ -219,7 +219,7 @@ private fun CreatePickContent( ) AlbumImage( - imageUrl = song.getImageUrlWithSize(RequestImageSize), + imageUrl = song.getImageUrlWithSize(RequestImageSize.width, RequestImageSize.height), modifier = Modifier .fillMaxWidth() .padding(horizontal = 30.dp) diff --git a/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt index f6e315a6..bef7119a 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt @@ -57,7 +57,7 @@ internal fun CircleAlbumCover( ) AsyncImage( - model = song.getImageUrlWithSize(Size(400, 400)), + model = song.getImageUrlWithSize(400, 400), contentDescription = song.albumName + stringResource(id = R.string.pick_album_description), modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/java/com/squirtles/musicroad/map/components/ClusterBottomSheet.kt b/app/src/main/java/com/squirtles/musicroad/map/components/ClusterBottomSheet.kt index 29598e19..3a12b9f0 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/components/ClusterBottomSheet.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/components/ClusterBottomSheet.kt @@ -109,7 +109,7 @@ fun BottomSheetItem( verticalAlignment = Alignment.CenterVertically ) { AlbumImage( - imageUrl = song.getImageUrlWithSize(REQUEST_IMAGE_SIZE_DEFAULT), + imageUrl = song.getImageUrlWithSize(REQUEST_IMAGE_SIZE_DEFAULT.width, REQUEST_IMAGE_SIZE_DEFAULT.height), modifier = Modifier .size(45.dp) .clip(RoundedCornerShape(4.dp)) diff --git a/app/src/main/java/com/squirtles/musicroad/map/components/InfoWindowCard.kt b/app/src/main/java/com/squirtles/musicroad/map/components/InfoWindowCard.kt index e5a0c6ad..3d08c2f4 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/components/InfoWindowCard.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/components/InfoWindowCard.kt @@ -58,7 +58,7 @@ fun InfoWindow( horizontalArrangement = Arrangement.spacedBy(16.dp) ) { AlbumImage( - imageUrl = pick.song.getImageUrlWithSize(RequestImageSize), + imageUrl = pick.song.getImageUrlWithSize(RequestImageSize.width, RequestImageSize.height), modifier = Modifier .size(90.dp) .clip(RoundedCornerShape(4.dp)) diff --git a/app/src/main/java/com/squirtles/musicroad/map/marker/LeafMarkerIconView.kt b/app/src/main/java/com/squirtles/musicroad/map/marker/LeafMarkerIconView.kt index 4d17346d..159f19a0 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/marker/LeafMarkerIconView.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/marker/LeafMarkerIconView.kt @@ -72,7 +72,7 @@ class LeafMarkerIconView( fun setLeafMarkerIcon(pick: Pick, onImageLoaded: () -> Unit) { val song = pick.song - loadImage(song.getImageUrlWithSize(REQUEST_IMAGE_SIZE_DEFAULT)) { + loadImage(song.getImageUrlWithSize(REQUEST_IMAGE_SIZE_DEFAULT.width, REQUEST_IMAGE_SIZE_DEFAULT.height)) { onImageLoaded() } } diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/PickItem.kt b/app/src/main/java/com/squirtles/musicroad/picklist/PickItem.kt index 0713411d..0b72b08c 100644 --- a/app/src/main/java/com/squirtles/musicroad/picklist/PickItem.kt +++ b/app/src/main/java/com/squirtles/musicroad/picklist/PickItem.kt @@ -66,7 +66,7 @@ internal fun PickItem( verticalAlignment = Alignment.CenterVertically ) { AlbumImage( - imageUrl = song.getImageUrlWithSize(Constants.REQUEST_IMAGE_SIZE_DEFAULT), + imageUrl = song.getImageUrlWithSize(Constants.REQUEST_IMAGE_SIZE_DEFAULT.width, Constants.REQUEST_IMAGE_SIZE_DEFAULT.height), modifier = Modifier .size(64.dp) .clip(RoundedCornerShape(8.dp)) diff --git a/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt b/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt index 8002bceb..d76a66eb 100644 --- a/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/search/SearchMusicScreen.kt @@ -261,7 +261,7 @@ private fun SongItem( verticalAlignment = Alignment.CenterVertically ) { AlbumImage( - imageUrl = song.getImageUrlWithSize(REQUEST_IMAGE_SIZE_DEFAULT), + imageUrl = song.getImageUrlWithSize(REQUEST_IMAGE_SIZE_DEFAULT.width, REQUEST_IMAGE_SIZE_DEFAULT.height), modifier = Modifier .size(ImageSize) .clip(RoundedCornerShape(16.dp)) diff --git a/domain/src/main/java/com/squirtles/domain/model/Song.kt b/domain/src/main/java/com/squirtles/domain/model/Song.kt index af13b4e2..b80007df 100644 --- a/domain/src/main/java/com/squirtles/domain/model/Song.kt +++ b/domain/src/main/java/com/squirtles/domain/model/Song.kt @@ -1,7 +1,5 @@ package com.squirtles.domain.model -import android.util.Size -import androidx.annotation.ColorInt import kotlinx.serialization.Serializable /** @@ -15,13 +13,13 @@ data class Song( val albumName: String, val imageUrl: String, val genreNames: List, - @ColorInt val bgColor: Int, + val bgColor: Int, val externalUrl: String, val previewUrl: String, ) { - fun getImageUrlWithSize(size: Size): String? { + fun getImageUrlWithSize(width: Int, height: Int): String? { return if (imageUrl.isEmpty()) null - else imageUrl.replace("{w}", size.width.toString()) - .replace("{h}", size.height.toString()) + else imageUrl.replace("{w}", width.toString()) + .replace("{h}", height.toString()) } } From fe9ca548ed52ed3db3fa50cb5dad1cea600133f4 Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 30 Jan 2025 23:03:12 +0900 Subject: [PATCH 25/46] =?UTF-8?q?[refactor]=20usecase=20=EC=B6=94=EC=83=81?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 공통 뷰모델에서 사용 위함 --- .../domain/usecase/favorite/DeleteFavoriteUseCase.kt | 7 ++++--- .../usecase/favorite/FetchFavoritePicksUseCase.kt | 7 ++++--- .../domain/usecase/mypick/DeletePickUseCase.kt | 7 ++++--- .../domain/usecase/mypick/FetchMyPicksUseCase.kt | 7 ++++--- .../usecase/order/GetFavoriteListOrderUseCase.kt | 7 ++++--- .../domain/usecase/order/GetMyPickListOrderUseCase.kt | 7 ++++--- .../usecase/order/SaveFavoriteListOrderUseCase.kt | 9 +++++---- .../domain/usecase/order/SaveMyPickListOrderUseCase.kt | 8 ++++---- .../usecase/picklist/DeletePickListUseCaseTemplate.kt | 9 +++++++++ .../usecase/picklist/FetchPickListUseCaseTemplate.kt | 10 ++++++++++ .../picklist/GetPickListOrderUseCaseTemplate.kt | 10 ++++++++++ .../picklist/SavePickListOrderUseCaseTemplate.kt | 10 ++++++++++ 12 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseTemplate.kt create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseTemplate.kt create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseTemplate.kt create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseTemplate.kt diff --git a/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt index 9cd9a63c..d9b18b0c 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt @@ -1,11 +1,12 @@ package com.squirtles.domain.usecase.favorite import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseTemplate import javax.inject.Inject class DeleteFavoriteUseCase @Inject constructor( - private val firebaseRepository: FirebaseRepository -) { - suspend operator fun invoke(pickId: String, userId: String) = + firebaseRepository: FirebaseRepository +) : DeletePickListUseCaseTemplate(firebaseRepository) { + override suspend operator fun invoke(pickId: String, userId: String) = firebaseRepository.deleteFavorite(pickId, userId) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt index 9d9a7a89..3d49e132 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt @@ -1,10 +1,11 @@ package com.squirtles.domain.usecase.favorite import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseTemplate import javax.inject.Inject class FetchFavoritePicksUseCase @Inject constructor( - private val firebaseRepository: FirebaseRepository -) { - suspend operator fun invoke(userId: String) = firebaseRepository.fetchFavoritePicks(userId) + firebaseRepository: FirebaseRepository +) : FetchPickListUseCaseTemplate(firebaseRepository) { + override suspend operator fun invoke(userId: String) = firebaseRepository.fetchFavoritePicks(userId) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt index 5f087b0d..b26047c2 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt @@ -1,11 +1,12 @@ package com.squirtles.domain.usecase.mypick import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseTemplate import javax.inject.Inject class DeletePickUseCase @Inject constructor( - private val firebaseRepository: FirebaseRepository -) { - suspend operator fun invoke(pickId: String, userId: String): Result = + firebaseRepository: FirebaseRepository +) : DeletePickListUseCaseTemplate(firebaseRepository) { + override suspend operator fun invoke(pickId: String, userId: String): Result = firebaseRepository.deletePick(pickId, userId) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt index 7993d3e3..cc0b1d63 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt @@ -1,11 +1,12 @@ package com.squirtles.domain.usecase.mypick import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseTemplate import javax.inject.Inject class FetchMyPicksUseCase @Inject constructor( - private val firebaseRepository: FirebaseRepository -) { - suspend operator fun invoke(userId: String) = + firebaseRepository: FirebaseRepository +) : FetchPickListUseCaseTemplate(firebaseRepository) { + override suspend operator fun invoke(userId: String) = firebaseRepository.fetchMyPicks(userId) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt index 0e18bb53..62c247f1 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt @@ -1,10 +1,11 @@ package com.squirtles.domain.usecase.order import com.squirtles.domain.local.LocalRepository +import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseTemplate import javax.inject.Inject class GetFavoriteListOrderUseCase @Inject constructor( - private val localRepository: LocalRepository -) { - operator fun invoke() = localRepository.favoriteListOrder + localRepository: LocalRepository +) : GetPickListOrderUseCaseTemplate(localRepository) { + override suspend operator fun invoke() = localRepository.favoriteListOrder } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt index d24a3001..bd371656 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt @@ -1,10 +1,11 @@ package com.squirtles.domain.usecase.order import com.squirtles.domain.local.LocalRepository +import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseTemplate import javax.inject.Inject class GetMyPickListOrderUseCase @Inject constructor( - private val localRepository: LocalRepository -) { - operator fun invoke() = localRepository.myListOrder + localRepository: LocalRepository +) : GetPickListOrderUseCaseTemplate(localRepository) { + override suspend operator fun invoke() = localRepository.myListOrder } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt index 05cf6613..dfa6f727 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt @@ -1,11 +1,12 @@ package com.squirtles.domain.usecase.order -import com.squirtles.domain.model.Order import com.squirtles.domain.local.LocalRepository +import com.squirtles.domain.model.Order +import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseTemplate import javax.inject.Inject class SaveFavoriteListOrderUseCase @Inject constructor( - private val localRepository: LocalRepository -) { - suspend operator fun invoke(order: Order) = localRepository.saveFavoriteListOrder(order) + localRepository: LocalRepository +) : SavePickListOrderUseCaseTemplate(localRepository) { + override suspend operator fun invoke(order: Order) = localRepository.saveFavoriteListOrder(order) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt index 712104f4..35d57022 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt @@ -2,10 +2,10 @@ package com.squirtles.domain.usecase.order import com.squirtles.domain.local.LocalRepository import com.squirtles.domain.model.Order +import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseTemplate import javax.inject.Inject -class SaveMyPickListOrderUseCase @Inject constructor( - private val localRepository: LocalRepository -) { - suspend operator fun invoke(order: Order) = localRepository.saveMyListOrder(order) +class SaveMyPickListOrderUseCase @Inject constructor(localRepository: LocalRepository) : + SavePickListOrderUseCaseTemplate(localRepository) { + override suspend operator fun invoke(order: Order) = localRepository.saveMyListOrder(order) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseTemplate.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseTemplate.kt new file mode 100644 index 00000000..f8461753 --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseTemplate.kt @@ -0,0 +1,9 @@ +package com.squirtles.domain.usecase.picklist + +import com.squirtles.domain.firebase.FirebaseRepository + +abstract class DeletePickListUseCaseTemplate( + val firebaseRepository: FirebaseRepository +) { + abstract suspend operator fun invoke(pickId: String, userId: String): Result +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseTemplate.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseTemplate.kt new file mode 100644 index 00000000..665abed3 --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseTemplate.kt @@ -0,0 +1,10 @@ +package com.squirtles.domain.usecase.picklist + +import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.model.Pick + +abstract class FetchPickListUseCaseTemplate( + val firebaseRepository: FirebaseRepository +) { + abstract suspend operator fun invoke(userId: String): Result> +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseTemplate.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseTemplate.kt new file mode 100644 index 00000000..3338258f --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseTemplate.kt @@ -0,0 +1,10 @@ +package com.squirtles.domain.usecase.picklist + +import com.squirtles.domain.local.LocalRepository +import com.squirtles.domain.model.Order + +abstract class GetPickListOrderUseCaseTemplate( + val localRepository: LocalRepository +) { + abstract suspend operator fun invoke(): Order +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseTemplate.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseTemplate.kt new file mode 100644 index 00000000..aaf45784 --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseTemplate.kt @@ -0,0 +1,10 @@ +package com.squirtles.domain.usecase.picklist + +import com.squirtles.domain.local.LocalRepository +import com.squirtles.domain.model.Order + +abstract class SavePickListOrderUseCaseTemplate( + val localRepository: LocalRepository +) { + abstract suspend operator fun invoke(order: Order) +} From b744e93a59b7de6aedc199d4c86afe48da577772 Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 30 Jan 2025 23:04:36 +0900 Subject: [PATCH 26/46] =?UTF-8?q?[refactor]=20PickList=20=EA=B3=B5?= =?UTF-8?q?=ED=86=B5=20=EB=B7=B0=EB=AA=A8=EB=8D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/picklist/PickListViewModel.kt | 104 ++++++++++++++++++ .../favorite/FavoriteListViewModel.kt | 55 ++------- .../musicroad/mypick/MyPickListViewModel.kt | 55 ++------- 3 files changed, 128 insertions(+), 86 deletions(-) create mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt new file mode 100644 index 00000000..7be9467b --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt @@ -0,0 +1,104 @@ +package com.squirtles.musicroad.common.picklist + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.squirtles.domain.model.Order +import com.squirtles.domain.model.Pick +import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseTemplate +import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseTemplate +import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseTemplate +import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseTemplate +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch + +abstract class PickListViewModel( + val fetchPickListUseCase: FetchPickListUseCaseTemplate, + val getPickListOrderUseCase: GetPickListOrderUseCaseTemplate, + val savePickListOrderUseCase: SavePickListOrderUseCaseTemplate, + val deletePickListUseCase: DeletePickListUseCaseTemplate +) : ViewModel() { + + private var pickList: List? = null + + private val _pickListUiState = MutableStateFlow(PickListUiState.Loading) + val pickListUiState = _pickListUiState.asStateFlow() + + private val _selectedPicksId = MutableStateFlow>(emptySet()) + val selectedPicksId = _selectedPicksId.asStateFlow() + + fun fetchPickList(userId: String) { + viewModelScope.launch { + fetchPickListUseCase(userId) + .onSuccess { picks -> + pickList = picks + sortPickList(getPickListOrderUseCase()) + } + .onFailure { + _pickListUiState.emit(PickListUiState.Error) + } + } + } + + private fun sortPickList(order: Order) { + pickList?.let { pickList -> + val sortedList = when (order) { + Order.LATEST -> pickList + + Order.OLDEST -> pickList.reversed() + + Order.FAVORITE_DESC -> + pickList.sortedByDescending { it.favoriteCount } + } + + _pickListUiState.value = PickListUiState.Success( + pickList = sortedList, + order = order + ) + } + } + + fun setListOrder(order: Order) { + viewModelScope.launch { + savePickListOrderUseCase(order) + sortPickList(order) + } + } + + fun toggleSelectedPick(pickId: String) { + val curSelectedPicksId = _selectedPicksId.value + _selectedPicksId.value = + if (curSelectedPicksId.contains(pickId)) curSelectedPicksId - pickId else curSelectedPicksId + pickId + } + + fun selectAllPicks() { + pickList?.let { pickList -> + _selectedPicksId.value = pickList.map { it.id }.toSet() + } + } + + fun deselectAllPicks() { + _selectedPicksId.value = emptySet() + } + + fun deleteSelectedPicks(userId: String) { + viewModelScope.launch { + _pickListUiState.value = PickListUiState.Loading + + val deleteJobList = _selectedPicksId.value.map { pickId -> + async { deletePickListUseCase(pickId, userId) } + }.awaitAll() + + deselectAllPicks() + if (deleteJobList.all { it.isSuccess }) { + fetchPickList(userId) + } else { + _pickListUiState.value = PickListUiState.Error + Log.e("PickListViewModel", "[픽 목록] 다중 삭제 오류") + } + } + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt index d424abc4..f7f7321c 100644 --- a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt @@ -1,53 +1,22 @@ package com.squirtles.musicroad.favorite -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.squirtles.domain.model.Order -import com.squirtles.domain.model.Pick +import com.squirtles.domain.usecase.favorite.DeleteFavoriteUseCase import com.squirtles.domain.usecase.favorite.FetchFavoritePicksUseCase import com.squirtles.domain.usecase.order.GetFavoriteListOrderUseCase import com.squirtles.domain.usecase.order.SaveFavoriteListOrderUseCase -import com.squirtles.musicroad.common.picklist.PickListUiState -import com.squirtles.musicroad.common.picklist.setOrderedList +import com.squirtles.musicroad.common.picklist.PickListViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class FavoriteListViewModel @Inject constructor( - private val fetchFavoritePicksUseCase: FetchFavoritePicksUseCase, - private val getFavoriteListOrderUseCase: GetFavoriteListOrderUseCase, - private val saveFavoriteListOrderUseCase: SaveFavoriteListOrderUseCase, -) : ViewModel() { - - private var favoriteList: List = emptyList() - - private val _pickListUiState = MutableStateFlow(PickListUiState.Loading) - val pickListUiState = _pickListUiState.asStateFlow() - - fun fetchFavoritePicks(userId: String) { - viewModelScope.launch { - fetchFavoritePicksUseCase(userId) - .onSuccess { favoritePicks -> - favoriteList = favoritePicks - setList(getFavoriteListOrderUseCase()) - } - .onFailure { - _pickListUiState.emit(PickListUiState.Error) - } - } - } - - fun setListOrder(order: Order) { - viewModelScope.launch { - saveFavoriteListOrderUseCase(order) - setList(order) - } - } - - private fun setList(order: Order) { - _pickListUiState.value = favoriteList.setOrderedList(order) - } -} + fetchFavoritePicksUseCase: FetchFavoritePicksUseCase, + getFavoriteListOrderUseCase: GetFavoriteListOrderUseCase, + saveFavoriteListOrderUseCase: SaveFavoriteListOrderUseCase, + deleteFavoriteUseCase: DeleteFavoriteUseCase +) : PickListViewModel( + fetchFavoritePicksUseCase, + getFavoriteListOrderUseCase, + saveFavoriteListOrderUseCase, + deleteFavoriteUseCase +) diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt index 49048741..e6d5db99 100644 --- a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt @@ -1,53 +1,22 @@ package com.squirtles.musicroad.mypick -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.squirtles.domain.model.Order -import com.squirtles.domain.model.Pick +import com.squirtles.domain.usecase.mypick.DeletePickUseCase import com.squirtles.domain.usecase.mypick.FetchMyPicksUseCase import com.squirtles.domain.usecase.order.GetMyPickListOrderUseCase import com.squirtles.domain.usecase.order.SaveMyPickListOrderUseCase -import com.squirtles.musicroad.common.picklist.PickListUiState -import com.squirtles.musicroad.common.picklist.setOrderedList +import com.squirtles.musicroad.common.picklist.PickListViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class MyPickListViewModel @Inject constructor( - private val fetchMyPicksUseCase: FetchMyPicksUseCase, - private val getMyPickListOrderUseCase: GetMyPickListOrderUseCase, - private val saveMyPickListOrderUseCase: SaveMyPickListOrderUseCase, -) : ViewModel() { - - private var myPickList: List = emptyList() - - private val _pickListUiState = MutableStateFlow(PickListUiState.Loading) - val pickListUiState = _pickListUiState.asStateFlow() - - fun fetchMyPicks(userId: String) { - viewModelScope.launch { - fetchMyPicksUseCase(userId) - .onSuccess { myPicks -> - myPickList = myPicks - setList(getMyPickListOrderUseCase()) - } - .onFailure { - _pickListUiState.emit(PickListUiState.Error) - } - } - } - - fun setListOrder(order: Order) { - viewModelScope.launch { - saveMyPickListOrderUseCase(order) - setList(order) - } - } - - private fun setList(order: Order) { - _pickListUiState.value = myPickList.setOrderedList(order) - } -} + fetchMyPicksUseCase: FetchMyPicksUseCase, + getMyPickListOrderUseCase: GetMyPickListOrderUseCase, + saveMyPickListOrderUseCase: SaveMyPickListOrderUseCase, + deletePickUseCase: DeletePickUseCase, +) : PickListViewModel( + fetchMyPicksUseCase, + getMyPickListOrderUseCase, + saveMyPickListOrderUseCase, + deletePickUseCase +) From 3fec5d48dc8bc99b71794a027cdc5c770971947b Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 30 Jan 2025 23:05:18 +0900 Subject: [PATCH 27/46] =?UTF-8?q?[chore]=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EB=B0=8F=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../picklist/DeleteSelectedPickDialog.kt | 2 +- .../{ => common}/picklist/EditModeAction.kt | 2 +- .../picklist/EditModeBottomButton.kt | 2 +- .../{ => common}/picklist/PickItem.kt | 7 +- .../musicroad/picklist/OrderBottomSheet.kt | 135 -------- .../musicroad/picklist/PickListScreen.kt | 307 ------------------ .../musicroad/picklist/PickListType.kt | 5 - .../musicroad/picklist/PickListUiState.kt | 10 - .../musicroad/picklist/PickListViewModel.kt | 143 -------- 9 files changed, 8 insertions(+), 605 deletions(-) rename app/src/main/java/com/squirtles/musicroad/{ => common}/picklist/DeleteSelectedPickDialog.kt (96%) rename app/src/main/java/com/squirtles/musicroad/{ => common}/picklist/EditModeAction.kt (97%) rename app/src/main/java/com/squirtles/musicroad/{ => common}/picklist/EditModeBottomButton.kt (98%) rename app/src/main/java/com/squirtles/musicroad/{ => common}/picklist/PickItem.kt (95%) delete mode 100644 app/src/main/java/com/squirtles/musicroad/picklist/OrderBottomSheet.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/picklist/PickListScreen.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/picklist/PickListType.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/picklist/PickListUiState.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/DeleteSelectedPickDialog.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/DeleteSelectedPickDialog.kt similarity index 96% rename from app/src/main/java/com/squirtles/musicroad/picklist/DeleteSelectedPickDialog.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/DeleteSelectedPickDialog.kt index e694494d..701ea0a3 100644 --- a/app/src/main/java/com/squirtles/musicroad/picklist/DeleteSelectedPickDialog.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/DeleteSelectedPickDialog.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.picklist +package com.squirtles.musicroad.common.picklist import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/EditModeAction.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeAction.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/picklist/EditModeAction.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeAction.kt index aa8c750d..48a73ee0 100644 --- a/app/src/main/java/com/squirtles/musicroad/picklist/EditModeAction.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeAction.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.picklist +package com.squirtles.musicroad.common.picklist import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/EditModeBottomButton.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeBottomButton.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/picklist/EditModeBottomButton.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeBottomButton.kt index 8c635b5b..b28049ed 100644 --- a/app/src/main/java/com/squirtles/musicroad/picklist/EditModeBottomButton.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeBottomButton.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.picklist +package com.squirtles.musicroad.common.picklist import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/PickItem.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickItem.kt similarity index 95% rename from app/src/main/java/com/squirtles/musicroad/picklist/PickItem.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/PickItem.kt index 0b72b08c..3c56fd8a 100644 --- a/app/src/main/java/com/squirtles/musicroad/picklist/PickItem.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickItem.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.picklist +package com.squirtles.musicroad.common.picklist import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -66,7 +66,10 @@ internal fun PickItem( verticalAlignment = Alignment.CenterVertically ) { AlbumImage( - imageUrl = song.getImageUrlWithSize(Constants.REQUEST_IMAGE_SIZE_DEFAULT.width, Constants.REQUEST_IMAGE_SIZE_DEFAULT.height), + imageUrl = song.getImageUrlWithSize( + Constants.REQUEST_IMAGE_SIZE_DEFAULT.width, + Constants.REQUEST_IMAGE_SIZE_DEFAULT.height + ), modifier = Modifier .size(64.dp) .clip(RoundedCornerShape(8.dp)) diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/OrderBottomSheet.kt b/app/src/main/java/com/squirtles/musicroad/picklist/OrderBottomSheet.kt deleted file mode 100644 index 70170130..00000000 --- a/app/src/main/java/com/squirtles/musicroad/picklist/OrderBottomSheet.kt +++ /dev/null @@ -1,135 +0,0 @@ -package com.squirtles.musicroad.picklist - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.displayCutoutPadding -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Check -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.ModalBottomSheet -import androidx.compose.material3.Text -import androidx.compose.material3.rememberModalBottomSheetState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import com.squirtles.domain.model.Order -import com.squirtles.musicroad.R -import com.squirtles.musicroad.common.Constants.DEFAULT_PADDING -import com.squirtles.musicroad.ui.theme.Dark -import com.squirtles.musicroad.ui.theme.Primary -import com.squirtles.musicroad.ui.theme.White -import kotlinx.coroutines.launch - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun OrderBottomSheet( - isFavoritePicks: Boolean, - currentOrder: Order, - onDismissRequest: () -> Unit, - onOrderClick: (Order) -> Unit, -) { - val sheetState = rememberModalBottomSheetState() - val scope = rememberCoroutineScope() - val orderList = listOf( - stringResource(if (isFavoritePicks) R.string.latest_favorite_order else R.string.latest_create_order) to Order.LATEST, - stringResource(if (isFavoritePicks) R.string.oldest_favorite_order else R.string.oldest_create_order) to Order.OLDEST, - stringResource(R.string.favorite_count_desc) to Order.FAVORITE_DESC, - ) - - ModalBottomSheet( - onDismissRequest = onDismissRequest, - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - .displayCutoutPadding() - .navigationBarsPadding(), - sheetState = sheetState, - containerColor = Dark, - scrimColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.32f), - ) { - Column( - modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally - ) { - orderList.forEach { (orderText, order) -> - BottomSheetMenu( - text = orderText, - isSelected = currentOrder == order, - ) { - scope - .launch { - if (currentOrder != order) { - onOrderClick(order) - } - sheetState.hide() - } - .invokeOnCompletion { - if (!sheetState.isVisible) { - onDismissRequest() - } - } - } - } - - HorizontalDivider(color = White) - BottomSheetMenu( - text = stringResource(R.string.close_button_text), - textAlign = TextAlign.Center, - ) { - scope - .launch { sheetState.hide() } - .invokeOnCompletion { - if (!sheetState.isVisible) { - onDismissRequest() - } - } - } - } - } -} - -@Composable -private fun BottomSheetMenu( - text: String, - textAlign: TextAlign = TextAlign.Start, - isSelected: Boolean = false, - onClick: () -> Unit, -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable { onClick() } - .padding(DEFAULT_PADDING), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = text, - modifier = Modifier.weight(1f), - color = if (isSelected) Primary else White, - fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal, - textAlign = textAlign, - ) - - if (isSelected) { - Icon( - imageVector = Icons.Default.Check, - contentDescription = stringResource(R.string.selected_icon_description), - tint = Primary - ) - } - } -} diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/PickListScreen.kt b/app/src/main/java/com/squirtles/musicroad/picklist/PickListScreen.kt deleted file mode 100644 index bae362f6..00000000 --- a/app/src/main/java/com/squirtles/musicroad/picklist/PickListScreen.kt +++ /dev/null @@ -1,307 +0,0 @@ -package com.squirtles.musicroad.picklist - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.displayCutoutPadding -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.wear.compose.material.CircularProgressIndicator -import com.squirtles.domain.model.Order -import com.squirtles.domain.model.Pick -import com.squirtles.musicroad.R -import com.squirtles.musicroad.common.Constants.COLOR_STOPS -import com.squirtles.musicroad.common.Constants.DEFAULT_PADDING -import com.squirtles.musicroad.common.CountText -import com.squirtles.musicroad.common.DefaultTopAppBar -import com.squirtles.musicroad.common.VerticalSpacer -import com.squirtles.musicroad.ui.theme.Primary -import com.squirtles.musicroad.ui.theme.White - -@Composable -fun PickListScreen( - userId: String, - pickListType: PickListType, - onBackClick: () -> Unit, - onItemClick: (String) -> Unit, - pickListViewModel: PickListViewModel = hiltViewModel() -) { - val isLandscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE - val uiState by pickListViewModel.pickListUiState.collectAsStateWithLifecycle() - val selectedPicksId by pickListViewModel.selectedPicksId.collectAsStateWithLifecycle() - - var isEditMode by rememberSaveable { mutableStateOf(false) } - var showOrderBottomSheet by rememberSaveable { mutableStateOf(false) } - var isDeletePickDialogVisible by rememberSaveable { mutableStateOf(false) } - - val deactivateEditMode = remember { - { - isEditMode = false - pickListViewModel.deselectAllPicks() - } - } - val showDeletePickDialog = remember { - { - isDeletePickDialogVisible = true - } - } - - LaunchedEffect(Unit) { - when (pickListType) { - PickListType.FAVORITE -> pickListViewModel.fetchFavoritePicks(userId) - PickListType.CREATED -> pickListViewModel.fetchMyPicks(userId) - } - } - - Scaffold( - topBar = { - DefaultTopAppBar( - title = stringResource( - when (pickListType) { - PickListType.FAVORITE -> R.string.favorite_picks_top_app_bar_title - PickListType.CREATED -> R.string.my_picks_top_app_bar_title - } - ), - onBackClick = onBackClick, - actions = { - EditModeAction( - isEditMode = isEditMode, - enabled = uiState is PickListUiState.Success, - isSelectedEmpty = selectedPicksId.isEmpty(), - activateEditMode = { isEditMode = true }, - selectAllPicks = { pickListViewModel.selectAllPicks() }, - deselectAllPicks = { pickListViewModel.deselectAllPicks() }, - ) - } - ) - }, - ) { innerPadding -> - Box( - modifier = Modifier - .fillMaxSize() - .background(Brush.verticalGradient(colorStops = COLOR_STOPS)) - .padding(innerPadding) - .then(if (isLandscape) Modifier.displayCutoutPadding() else Modifier) - ) { - when (uiState) { - PickListUiState.Loading -> { - CircularProgressIndicator( - modifier = Modifier - .size(36.dp) - .align(Alignment.Center), - indicatorColor = Primary - ) - } - - is PickListUiState.Success -> { - val pickList = (uiState as PickListUiState.Success).pickList - val order = (uiState as PickListUiState.Success).order - - Column( - modifier = Modifier.fillMaxSize() - ) { - PickList( - modifier = Modifier - .fillMaxWidth() - .weight(1f), - isEditMode = isEditMode, - pickListType = pickListType, - pickList = pickList, - selectedPicksId = selectedPicksId, - order = order, - onOrderClick = { showOrderBottomSheet = true }, - onItemClick = onItemClick, - onEditModeItemClick = { pickListViewModel.toggleSelectedPick(it) }, - ) - - if (isEditMode) { - EditModeBottomButton( - enabled = selectedPicksId.isNotEmpty(), - deactivateEditMode = deactivateEditMode, - showDeletePickDialog = showDeletePickDialog, - ) - } - } - } - - PickListUiState.Error -> { - Text( - text = stringResource(R.string.error_loading_pick_list), - modifier = Modifier.align(Alignment.Center), - color = White, - style = MaterialTheme.typography.bodyLarge - ) - // TODO: 다시하기 버튼 같은 거 만들어서 요청 다시 하게 할 수 있도록 만드는 것도 고려해보기 - } - } - } - } - - if (showOrderBottomSheet) { - OrderBottomSheet( - isFavoritePicks = pickListType == PickListType.FAVORITE, - currentOrder = (uiState as PickListUiState.Success).order, - onDismissRequest = { showOrderBottomSheet = false }, - onOrderClick = { order -> - pickListViewModel.setListOrder(pickListType, order) - }, - ) - } - - if (isDeletePickDialogVisible) { - DeleteSelectedPickDialog( - selectedPickCount = selectedPicksId.size, - pickListType = pickListType, - onDismissRequest = { isDeletePickDialogVisible = false }, - onDeletePickClick = { - isEditMode = false - isDeletePickDialogVisible = false - pickListViewModel.deleteSelectedPicks(pickListType) - }, - ) - } -} - -@Composable -private fun PickList( - modifier: Modifier, - isEditMode: Boolean, - pickListType: PickListType, - pickList: List, - selectedPicksId: Set, - order: Order, - onOrderClick: () -> Unit, - onItemClick: (String) -> Unit, - onEditModeItemClick: (String) -> Unit, -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = DEFAULT_PADDING), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - CountText( - totalCount = if (isEditMode) selectedPicksId.size else pickList.size, - countLabel = stringResource( - if (isEditMode) R.string.selected_count_text else R.string.total_count_text - ), - defaultColor = White, - ) - - Box( - modifier = Modifier - .wrapContentSize() - .clip(CircleShape) - .clickable { onOrderClick() } - ) { - Text( - text = getOrderString( - pickListType = pickListType, - order = order - ), - modifier = Modifier.padding( - horizontal = DEFAULT_PADDING / 2, - vertical = DEFAULT_PADDING / 4 - ), - color = White, - style = MaterialTheme.typography.bodyMedium - ) - } - } - - VerticalSpacer(8) - - if (pickList.isEmpty()) { - Box( - modifier = modifier, - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource( - when (pickListType) { - PickListType.FAVORITE -> R.string.favorite_picks_empty - PickListType.CREATED -> R.string.my_picks_empty - } - ), - color = White, - style = MaterialTheme.typography.titleMedium - ) - } - } else { - LazyColumn( - modifier = modifier - ) { - items( - items = pickList, - key = { it.id } - ) { pick -> - PickItem( - isEditMode = isEditMode, - isSelected = selectedPicksId.contains(pick.id), - song = pick.song, - createdByOthers = pickListType == PickListType.FAVORITE, - createUserName = pick.createdBy.userName, - favoriteCount = pick.favoriteCount, - comment = pick.comment, - createdAt = pick.createdAt, - onItemClick = { - if (isEditMode) onEditModeItemClick(pick.id) else onItemClick(pick.id) - } - ) - } - } - } -} - -@Composable -private fun getOrderString(pickListType: PickListType, order: Order): String { - return "${ - stringResource( - when (order) { - Order.LATEST -> - when (pickListType) { - PickListType.FAVORITE -> R.string.latest_favorite_order - PickListType.CREATED -> R.string.latest_create_order - } - - Order.OLDEST -> - when (pickListType) { - PickListType.FAVORITE -> R.string.oldest_favorite_order - PickListType.CREATED -> R.string.oldest_create_order - } - - Order.FAVORITE_DESC -> R.string.favorite_count_desc - } - ) - } ▼" -} diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/PickListType.kt b/app/src/main/java/com/squirtles/musicroad/picklist/PickListType.kt deleted file mode 100644 index 0aeda502..00000000 --- a/app/src/main/java/com/squirtles/musicroad/picklist/PickListType.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.squirtles.musicroad.picklist - -enum class PickListType { - FAVORITE, CREATED -} diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/PickListUiState.kt b/app/src/main/java/com/squirtles/musicroad/picklist/PickListUiState.kt deleted file mode 100644 index 3961e0ef..00000000 --- a/app/src/main/java/com/squirtles/musicroad/picklist/PickListUiState.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.squirtles.musicroad.picklist - -import com.squirtles.domain.model.Order -import com.squirtles.domain.model.Pick - -sealed class PickListUiState { - data object Loading : PickListUiState() - data class Success(val pickList: List, val order: Order) : PickListUiState() - data object Error : PickListUiState() -} diff --git a/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt deleted file mode 100644 index 0c068513..00000000 --- a/app/src/main/java/com/squirtles/musicroad/picklist/PickListViewModel.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.squirtles.musicroad.picklist - -import android.util.Log -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.squirtles.domain.model.Order -import com.squirtles.domain.model.Pick -import com.squirtles.domain.usecase.favorite.DeleteFavoriteUseCase -import com.squirtles.domain.usecase.favorite.FetchFavoritePicksUseCase -import com.squirtles.domain.usecase.mypick.DeletePickUseCase -import com.squirtles.domain.usecase.mypick.FetchMyPicksUseCase -import com.squirtles.domain.usecase.order.GetFavoriteListOrderUseCase -import com.squirtles.domain.usecase.order.GetMyPickListOrderUseCase -import com.squirtles.domain.usecase.order.SaveFavoriteListOrderUseCase -import com.squirtles.domain.usecase.order.SaveMyPickListOrderUseCase -import com.squirtles.domain.usecase.user.GetCurrentUserUseCase -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch -import javax.inject.Inject - -@HiltViewModel -class PickListViewModel @Inject constructor( - private val fetchFavoritePicksUseCase: FetchFavoritePicksUseCase, - private val fetchMyPicksUseCase: FetchMyPicksUseCase, - private val getCurrentUserUseCase: GetCurrentUserUseCase, - private val getFavoriteListOrderUseCase: GetFavoriteListOrderUseCase, - private val getMyPickListOrderUseCase: GetMyPickListOrderUseCase, - private val saveFavoriteListOrderUseCase: SaveFavoriteListOrderUseCase, - private val saveMyPickListOrderUseCase: SaveMyPickListOrderUseCase, - private val deleteFavoriteUseCase: DeleteFavoriteUseCase, - private val deletePickUseCase: DeletePickUseCase, -) : ViewModel() { - - private var defaultList: List? = null - - private val _pickListUiState = MutableStateFlow(PickListUiState.Loading) - val pickListUiState = _pickListUiState.asStateFlow() - - private val _selectedPicksId = MutableStateFlow>(emptySet()) - val selectedPicksId = _selectedPicksId.asStateFlow() - - fun fetchFavoritePicks(userId: String) { - viewModelScope.launch { - fetchFavoritePicksUseCase(userId) - .onSuccess { favoritePicks -> - defaultList = favoritePicks - setList(getFavoriteListOrderUseCase()) - } - .onFailure { - _pickListUiState.emit(PickListUiState.Error) - } - } - } - - fun fetchMyPicks(userId: String) { - viewModelScope.launch { - fetchMyPicksUseCase(userId) - .onSuccess { myPicks -> - defaultList = myPicks - setList(getMyPickListOrderUseCase()) - } - .onFailure { - _pickListUiState.emit(PickListUiState.Error) - } - } - } - - fun setListOrder(type: PickListType, order: Order) { - viewModelScope.launch { - when (type) { - PickListType.FAVORITE -> saveFavoriteListOrderUseCase(order) - PickListType.CREATED -> saveMyPickListOrderUseCase(order) - } - setList(order) - } - } - - fun toggleSelectedPick(pickId: String) { - val curSelectedPicksId = _selectedPicksId.value - _selectedPicksId.value = - if (curSelectedPicksId.contains(pickId)) curSelectedPicksId - pickId else curSelectedPicksId + pickId - } - - fun selectAllPicks() { - defaultList?.let { pickList -> - _selectedPicksId.value = pickList.map { it.id }.toSet() - } - } - - fun deselectAllPicks() { - _selectedPicksId.value = emptySet() - } - - fun deleteSelectedPicks(type: PickListType) { - viewModelScope.launch { - _pickListUiState.value = PickListUiState.Loading - - val userId = getUserId() - val deleteJobList = _selectedPicksId.value.map { pickId -> - when (type) { - PickListType.FAVORITE -> async { deleteFavoriteUseCase(pickId, userId) } - PickListType.CREATED -> async { deletePickUseCase(pickId, userId) } - } - } - val deleteJobResults = deleteJobList.awaitAll() - - deselectAllPicks() - if (deleteJobResults.all { it.isSuccess }) { - when (type) { - PickListType.FAVORITE -> fetchFavoritePicks(userId) - PickListType.CREATED -> fetchMyPicks(userId) - } - } else { - _pickListUiState.value = PickListUiState.Error - Log.e("PickListViewModel", "[픽 목록] 다중 삭제 오류") - } - } - } - - private fun setList(order: Order) { - defaultList?.let { pickList -> - val sortedList = when (order) { - Order.LATEST -> pickList - - Order.OLDEST -> pickList.reversed() - - Order.FAVORITE_DESC -> - pickList.sortedByDescending { it.favoriteCount } - } - - _pickListUiState.value = PickListUiState.Success( - pickList = sortedList, - order = order - ) - } - } - - private fun getUserId() = getCurrentUserUseCase().userId -} From f600271a82744d552fe86ab9768bb8bc075747c8 Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 30 Jan 2025 23:05:42 +0900 Subject: [PATCH 28/46] =?UTF-8?q?[refactor]=20=EB=88=84=EB=9D=BD=20?= =?UTF-8?q?=ED=8E=B8=EC=A7=91=20=EA=B8=B0=EB=8A=A5=20=EC=9E=AC=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/picklist/PickListContents.kt | 238 ++++++++++++------ .../musicroad/favorite/FavoriteScreen.kt | 9 +- .../musicroad/mypick/MyPickScreen.kt | 11 +- 3 files changed, 182 insertions(+), 76 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt index 973c4fbb..b32eb75e 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt @@ -20,6 +20,11 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -29,6 +34,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.wear.compose.material.CircularProgressIndicator import com.squirtles.domain.model.Order +import com.squirtles.domain.model.Pick import com.squirtles.musicroad.R import com.squirtles.musicroad.common.Constants.COLOR_STOPS import com.squirtles.musicroad.common.Constants.DEFAULT_PADDING @@ -40,16 +46,37 @@ import com.squirtles.musicroad.ui.theme.White @Composable fun PickListContents( + userId: String, showOrderBottomSheet: Boolean, + selectedPicksId: Set, pickListType: PickListType, uiState: PickListUiState, onBackClick: () -> Unit, onItemClick: (String) -> Unit, setListOrder: (Order) -> Unit, - setOrderBottomSheetVisibility: (Boolean) -> Unit + setOrderBottomSheetVisibility: (Boolean) -> Unit, + selectAllPicks: () -> Unit, + deselectAllPicks: () -> Unit, + toggleSelectedPick: (String) -> Unit, + deleteSelectedPicks: (String) -> Unit ) { val isLandscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE + var isEditMode by rememberSaveable { mutableStateOf(false) } + var isDeletePickDialogVisible by rememberSaveable { mutableStateOf(false) } + + val deactivateEditMode = remember { + { + isEditMode = false + deselectAllPicks() + } + } + val showDeletePickDialog = remember { + { + isDeletePickDialogVisible = true + } + } + Scaffold( topBar = { DefaultTopAppBar( @@ -59,7 +86,17 @@ fun PickListContents( PickListType.CREATED -> R.string.my_picks_top_app_bar_title } ), - onBackClick = onBackClick + onBackClick = onBackClick, + actions = { + EditModeAction( + isEditMode = isEditMode, + enabled = uiState is PickListUiState.Success, + isSelectedEmpty = selectedPicksId.isEmpty(), + activateEditMode = { isEditMode = true }, + selectAllPicks = { selectAllPicks() }, + deselectAllPicks = { deselectAllPicks() }, + ) + } ) }, ) { innerPadding -> @@ -81,82 +118,34 @@ fun PickListContents( } is PickListUiState.Success -> { - val pickList = uiState.pickList - val order = uiState.order + val pickList = (uiState as PickListUiState.Success).pickList + val order = (uiState as PickListUiState.Success).order Column( modifier = Modifier.fillMaxSize() ) { - Row( + PickList( modifier = Modifier .fillMaxWidth() - .padding(horizontal = DEFAULT_PADDING), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically - ) { - CountText( - totalCount = pickList.size, - defaultColor = White, - ) + .weight(1f), + isEditMode = isEditMode, + pickListType = pickListType, + pickList = pickList, + selectedPicksId = selectedPicksId, + order = order, + onOrderClick = { + setOrderBottomSheetVisibility(true) + }, + onItemClick = onItemClick, + onEditModeItemClick = toggleSelectedPick, + ) - Box( - modifier = Modifier - .wrapContentSize() - .clip(CircleShape) - .clickable { setOrderBottomSheetVisibility(true) } - ) { - Text( - text = getOrderString( - pickListType = pickListType, - order = order - ), - modifier = Modifier.padding( - horizontal = DEFAULT_PADDING / 2, - vertical = DEFAULT_PADDING / 4 - ), - color = White, - style = MaterialTheme.typography.bodyMedium - ) - } - } - - VerticalSpacer(8) - - if (pickList.isEmpty()) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource( - when (pickListType) { - PickListType.FAVORITE -> R.string.favorite_picks_empty - PickListType.CREATED -> R.string.my_picks_empty - } - ), - color = White, - style = MaterialTheme.typography.titleMedium - ) - } - } else { - LazyColumn( - modifier = Modifier.weight(1f) - ) { - items( - items = pickList, - key = { it.id } - ) { pick -> - PickListItem( - song = pick.song, - isCreatedByOthers = pickListType == PickListType.FAVORITE, - createUserName = pick.createdBy.userName, - favoriteCount = pick.favoriteCount, - comment = pick.comment, - createdAt = pick.createdAt, - onItemClick = { onItemClick(pick.id) } - ) - } - } + if (isEditMode) { + EditModeBottomButton( + enabled = selectedPicksId.isNotEmpty(), + deactivateEditMode = deactivateEditMode, + showDeletePickDialog = showDeletePickDialog, + ) } } } @@ -179,13 +168,116 @@ fun PickListContents( isFavoritePicks = pickListType == PickListType.FAVORITE, currentOrder = (uiState as PickListUiState.Success).order, onDismissRequest = { setOrderBottomSheetVisibility(false) }, - onOrderClick = { order -> - setListOrder(order) + onOrderClick = setListOrder, + ) + } + + if (isDeletePickDialogVisible) { + DeleteSelectedPickDialog( + selectedPickCount = selectedPicksId.size, + pickListType = pickListType, + onDismissRequest = { isDeletePickDialogVisible = false }, + onDeletePickClick = { + isEditMode = false + isDeletePickDialogVisible = false + deleteSelectedPicks(userId) }, ) } } +@Composable +private fun PickList( + modifier: Modifier, + isEditMode: Boolean, + pickListType: PickListType, + pickList: List, + selectedPicksId: Set, + order: Order, + onOrderClick: () -> Unit, + onItemClick: (String) -> Unit, + onEditModeItemClick: (String) -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = DEFAULT_PADDING), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + CountText( + totalCount = if (isEditMode) selectedPicksId.size else pickList.size, + countLabel = stringResource( + if (isEditMode) R.string.selected_count_text else R.string.total_count_text + ), + defaultColor = White, + ) + + Box( + modifier = Modifier + .wrapContentSize() + .clip(CircleShape) + .clickable { onOrderClick() } + ) { + Text( + text = getOrderString( + pickListType = pickListType, + order = order + ), + modifier = Modifier.padding( + horizontal = DEFAULT_PADDING / 2, + vertical = DEFAULT_PADDING / 4 + ), + color = White, + style = MaterialTheme.typography.bodyMedium + ) + } + } + + VerticalSpacer(8) + + if (pickList.isEmpty()) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center + ) { + Text( + text = stringResource( + when (pickListType) { + PickListType.FAVORITE -> R.string.favorite_picks_empty + PickListType.CREATED -> R.string.my_picks_empty + } + ), + color = White, + style = MaterialTheme.typography.titleMedium + ) + } + } else { + LazyColumn( + modifier = modifier + ) { + items( + items = pickList, + key = { it.id } + ) { pick -> + PickItem( + isEditMode = isEditMode, + isSelected = selectedPicksId.contains(pick.id), + song = pick.song, + createdByOthers = pickListType == PickListType.FAVORITE, + createUserName = pick.createdBy.userName, + favoriteCount = pick.favoriteCount, + comment = pick.comment, + createdAt = pick.createdAt, + onItemClick = { + if (isEditMode) onEditModeItemClick(pick.id) else onItemClick(pick.id) + } + ) + } + } + } +} + @Composable private fun getOrderString(pickListType: PickListType, order: Order): String { return "${ diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt index 53b0b4d1..74bd5820 100644 --- a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt @@ -19,19 +19,26 @@ fun FavoriteScreen( favoriteListViewModel: FavoriteListViewModel = hiltViewModel() ) { val uiState by favoriteListViewModel.pickListUiState.collectAsStateWithLifecycle() + val selectedPicksId by favoriteListViewModel.selectedPicksId.collectAsStateWithLifecycle() var showOrderBottomSheet by rememberSaveable { mutableStateOf(false) } LaunchedEffect(Unit) { - favoriteListViewModel.fetchFavoritePicks(userId) + favoriteListViewModel.fetchPickList(userId) } PickListContents( + userId = userId, showOrderBottomSheet = showOrderBottomSheet, + selectedPicksId = selectedPicksId, pickListType = PickListType.FAVORITE, uiState = uiState, onBackClick = onBackClick, onItemClick = onItemClick, setListOrder = favoriteListViewModel::setListOrder, setOrderBottomSheetVisibility = { showOrderBottomSheet = it }, + selectAllPicks = favoriteListViewModel::selectAllPicks, + deselectAllPicks = favoriteListViewModel::deselectAllPicks, + toggleSelectedPick = favoriteListViewModel::toggleSelectedPick, + deleteSelectedPicks = favoriteListViewModel::deleteSelectedPicks ) } diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt index 45461e44..7efe9d33 100644 --- a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt @@ -19,19 +19,26 @@ fun MyPickScreen( myPickListViewModel: MyPickListViewModel = hiltViewModel() ) { val uiState by myPickListViewModel.pickListUiState.collectAsStateWithLifecycle() + val selectedPicksId by myPickListViewModel.selectedPicksId.collectAsStateWithLifecycle() var showOrderBottomSheet by rememberSaveable { mutableStateOf(false) } LaunchedEffect(Unit) { - myPickListViewModel.fetchMyPicks(userId) + myPickListViewModel.fetchPickList(userId) } PickListContents( + userId = userId, showOrderBottomSheet = showOrderBottomSheet, - pickListType = PickListType.FAVORITE, + selectedPicksId = selectedPicksId, + pickListType = PickListType.CREATED, uiState = uiState, onBackClick = onBackClick, onItemClick = onItemClick, setListOrder = myPickListViewModel::setListOrder, setOrderBottomSheetVisibility = { showOrderBottomSheet = it }, + selectAllPicks = myPickListViewModel::selectAllPicks, + deselectAllPicks = myPickListViewModel::deselectAllPicks, + toggleSelectedPick = myPickListViewModel::toggleSelectedPick, + deleteSelectedPicks = myPickListViewModel::deleteSelectedPicks ) } From 71e4d7625030c66eda5f2cf5782fbe6a2b4b5459 Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 30 Jan 2025 23:25:10 +0900 Subject: [PATCH 29/46] =?UTF-8?q?[refactor]=20=EC=9C=A0=EC=A0=80=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=ED=99=94=EB=A9=B4,=20route=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 화면 별 기능이 더 직관적으로 드러나도록 변경 --- .../musicroad/main/navigation/MainNavHost.kt | 10 ++-- .../main/navigation/MainNavigator.kt | 18 +++--- .../mypick/navigation/MyPickNavigation.kt | 8 +-- .../musicroad/navigation/MainRoute.kt | 2 +- .../musicroad/navigation/ProfileRoute.kt | 16 ----- .../musicroad/navigation/UserInfoRoute.kt | 16 +++++ .../profile/navigation/ProfileNavigation.kt | 59 ------------------- .../UserInfoViewModel.kt} | 6 +- .../components/MenuItem.kt | 2 +- .../components/UserInfoMenus.kt} | 4 +- .../userinfo/navigation/UserInfoNavigation.kt | 59 +++++++++++++++++++ .../screen/EditNotificationSettingScreen.kt} | 4 +- .../screen/EditProfileScreen.kt} | 12 ++-- .../screen/UserInfoScreen.kt} | 16 ++--- 14 files changed, 117 insertions(+), 115 deletions(-) delete mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt create mode 100644 app/src/main/java/com/squirtles/musicroad/navigation/UserInfoRoute.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt rename app/src/main/java/com/squirtles/musicroad/{profile/ProfileViewModel.kt => userinfo/UserInfoViewModel.kt} (95%) rename app/src/main/java/com/squirtles/musicroad/{profile => userinfo}/components/MenuItem.kt (86%) rename app/src/main/java/com/squirtles/musicroad/{profile/components/ProfileMenus.kt => userinfo/components/UserInfoMenus.kt} (97%) create mode 100644 app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt rename app/src/main/java/com/squirtles/musicroad/{profile/screen/SettingNotificationScreen.kt => userinfo/screen/EditNotificationSettingScreen.kt} (94%) rename app/src/main/java/com/squirtles/musicroad/{profile/screen/SettingProfileScreen.kt => userinfo/screen/EditProfileScreen.kt} (96%) rename app/src/main/java/com/squirtles/musicroad/{profile/screen/ProfileScreen.kt => userinfo/screen/UserInfoScreen.kt} (94%) diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt index ad632128..6c3fd480 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt @@ -9,8 +9,8 @@ import com.squirtles.musicroad.map.MapViewModel import com.squirtles.musicroad.map.navigation.mapNavGraph import com.squirtles.musicroad.media.PlayerServiceViewModel import com.squirtles.musicroad.mypick.navigation.myPickNavGraph -import com.squirtles.musicroad.profile.navigation.profileNavGraph import com.squirtles.musicroad.search.navigation.searchNavGraph +import com.squirtles.musicroad.userinfo.navigation.profileNavGraph @Composable internal fun MainNavHost( @@ -28,7 +28,7 @@ internal fun MainNavHost( playerServiceViewModel = playerServiceViewModel, onFavoriteClick = navigator::navigateFavorite, onCenterClick = navigator::navigateSearch, - onProfileClick = navigator::navigateProfile, + onProfileClick = navigator::navigateUserInfo, onPickSummaryClick = navigator::navigatePickDetail, onBackClick = navigator::navigateMap, onDeleted = mapViewModel::resetClickedMarkerState @@ -44,14 +44,14 @@ internal fun MainNavHost( onBackClick = navigator::popBackStackIfNotMap, onItemClick = navigator::navigatePickDetail ) - + profileNavGraph( onBackClick = navigator::popBackStackIfNotMap, onBackToMapClick = navigator::navigateMap, onFavoritePicksClick = navigator::navigateFavorite, onMyPicksClick = navigator::navigateMyPicks, - onSettingProfileClick = navigator::navigateSettingProfile, - onSettingNotificationClick = navigator::navigateSettingNotification, + onSettingProfileClick = navigator::navigateEditProfile, + onSettingNotificationClick = navigator::navigateEditNotificationSetting, ) myPickNavGraph( diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt index bf712ea6..7edc56d6 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt @@ -14,11 +14,11 @@ import com.squirtles.musicroad.map.navigation.navigateMap import com.squirtles.musicroad.map.navigation.navigatePickDetail import com.squirtles.musicroad.mypick.navigation.navigateMyPicks import com.squirtles.musicroad.navigation.Route -import com.squirtles.musicroad.profile.navigation.navigateProfile -import com.squirtles.musicroad.profile.navigation.navigateSettingNotification -import com.squirtles.musicroad.profile.navigation.navigateSettingProfile import com.squirtles.musicroad.search.navigation.navigateCreate import com.squirtles.musicroad.search.navigation.navigateSearch +import com.squirtles.musicroad.userinfo.navigation.navigateEditNotificationSetting +import com.squirtles.musicroad.userinfo.navigation.navigateEditProfile +import com.squirtles.musicroad.userinfo.navigation.navigateUserInfo internal class MainNavigator( val navController: NavHostController @@ -65,21 +65,21 @@ internal class MainNavigator( ) } - fun navigateProfile(userId: String) { - navController.navigateProfile( + fun navigateUserInfo(userId: String) { + navController.navigateUserInfo( userId = userId, navOptions = navOptions { launchSingleTop = true } ) } - fun navigateSettingProfile(){ - navController.navigateSettingProfile( + fun navigateEditProfile() { + navController.navigateEditProfile( navOptions = navOptions { launchSingleTop = true } ) } - fun navigateSettingNotification(){ - navController.navigateSettingNotification( + fun navigateEditNotificationSetting() { + navController.navigateEditNotificationSetting( navOptions = navOptions { launchSingleTop = true } ) } diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt b/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt index fee5742e..fe7fd666 100644 --- a/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt @@ -6,18 +6,18 @@ import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.toRoute import com.squirtles.musicroad.mypick.MyPickScreen -import com.squirtles.musicroad.navigation.ProfileRoute +import com.squirtles.musicroad.navigation.UserInfoRoute fun NavController.navigateMyPicks(userId: String, navOptions: NavOptions) { - navigate(ProfileRoute.MyPicks(userId), navOptions) + navigate(UserInfoRoute.MyPicks(userId), navOptions) } fun NavGraphBuilder.myPickNavGraph( onBackClick: () -> Unit, onItemClick: (String) -> Unit, ) { - composable { backStackEntry -> - val userId = backStackEntry.toRoute().userId + composable { backStackEntry -> + val userId = backStackEntry.toRoute().userId MyPickScreen( userId = userId, diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt index d7f03191..e5c948a1 100644 --- a/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt +++ b/app/src/main/java/com/squirtles/musicroad/navigation/MainRoute.kt @@ -11,5 +11,5 @@ sealed interface MainRoute : Route { data class Favorite(val userId: String) : MainRoute @Serializable - data class Profile(val userId: String) : MainRoute + data class UserInfo(val userId: String) : MainRoute } diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt deleted file mode 100644 index 8cdd03be..00000000 --- a/app/src/main/java/com/squirtles/musicroad/navigation/ProfileRoute.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.squirtles.musicroad.navigation - -import kotlinx.serialization.Serializable - -@Serializable -sealed interface ProfileRoute : Route { - @Serializable - data class MyPicks(val userId: String) : ProfileRoute - - @Serializable - data object Setting : ProfileRoute - - @Serializable - data object Notification : ProfileRoute -} - diff --git a/app/src/main/java/com/squirtles/musicroad/navigation/UserInfoRoute.kt b/app/src/main/java/com/squirtles/musicroad/navigation/UserInfoRoute.kt new file mode 100644 index 00000000..e455b807 --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/navigation/UserInfoRoute.kt @@ -0,0 +1,16 @@ +package com.squirtles.musicroad.navigation + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface UserInfoRoute : Route { + @Serializable + data class MyPicks(val userId: String) : UserInfoRoute + + @Serializable + data object EditProfile : UserInfoRoute + + @Serializable + data object EditNotification : UserInfoRoute +} + diff --git a/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt b/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt deleted file mode 100644 index 41f22e57..00000000 --- a/app/src/main/java/com/squirtles/musicroad/profile/navigation/ProfileNavigation.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.squirtles.musicroad.profile.navigation - -import androidx.navigation.NavController -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavOptions -import androidx.navigation.compose.composable -import androidx.navigation.toRoute -import com.squirtles.musicroad.navigation.MainRoute -import com.squirtles.musicroad.navigation.ProfileRoute -import com.squirtles.musicroad.profile.screen.ProfileScreen -import com.squirtles.musicroad.profile.screen.SettingNotificationScreen -import com.squirtles.musicroad.profile.screen.SettingProfileScreen - -fun NavController.navigateProfile(userId: String, navOptions: NavOptions? = null) { - navigate(MainRoute.Profile(userId), navOptions) -} - -fun NavController.navigateSettingProfile(navOptions: NavOptions? = null) { - navigate(ProfileRoute.Setting, navOptions) -} - -fun NavController.navigateSettingNotification(navOptions: NavOptions? = null) { - navigate(ProfileRoute.Notification, navOptions) -} - -fun NavGraphBuilder.profileNavGraph( - onBackClick: () -> Unit, - onBackToMapClick: () -> Unit, - onFavoritePicksClick: (String) -> Unit, - onMyPicksClick: (String) -> Unit, - onSettingProfileClick: () -> Unit, - onSettingNotificationClick: () -> Unit, -) { - composable { backStackEntry -> - val userId = backStackEntry.toRoute().userId - - ProfileScreen( - userId = userId, - onBackClick = onBackClick, - onBackToMapClick = onBackToMapClick, - onFavoritePicksClick = onFavoritePicksClick, - onMyPicksClick = onMyPicksClick, - onSettingProfileClick = onSettingProfileClick, - onSettingNotificationClick = onSettingNotificationClick, - ) - } - - composable { backStackEntry -> - SettingProfileScreen( - onBackClick = onBackClick, - ) - } - - composable { backStackEntry -> - SettingNotificationScreen( - onBackClick = onBackClick - ) - } -} diff --git a/app/src/main/java/com/squirtles/musicroad/profile/ProfileViewModel.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/UserInfoViewModel.kt similarity index 95% rename from app/src/main/java/com/squirtles/musicroad/profile/ProfileViewModel.kt rename to app/src/main/java/com/squirtles/musicroad/userinfo/UserInfoViewModel.kt index 376c6118..68df9776 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/UserInfoViewModel.kt @@ -1,11 +1,11 @@ -package com.squirtles.musicroad.profile +package com.squirtles.musicroad.userinfo import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.model.User -import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.user.FetchUserByIdUseCase import com.squirtles.domain.usecase.user.FetchUserUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.domain.usecase.user.UpdateUserNameUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableSharedFlow @@ -16,7 +16,7 @@ import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class ProfileViewModel @Inject constructor( +class UserInfoViewModel @Inject constructor( private val getCurrentUserUseCase: GetCurrentUserUseCase, private val fetchUserUseCase: FetchUserUseCase, private val fetchUserByIdUseCase: FetchUserByIdUseCase, diff --git a/app/src/main/java/com/squirtles/musicroad/profile/components/MenuItem.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/components/MenuItem.kt similarity index 86% rename from app/src/main/java/com/squirtles/musicroad/profile/components/MenuItem.kt rename to app/src/main/java/com/squirtles/musicroad/userinfo/components/MenuItem.kt index a883d509..ffa4050b 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/components/MenuItem.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/components/MenuItem.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.profile.components +package com.squirtles.musicroad.userinfo.components import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector diff --git a/app/src/main/java/com/squirtles/musicroad/profile/components/ProfileMenus.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/components/UserInfoMenus.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/profile/components/ProfileMenus.kt rename to app/src/main/java/com/squirtles/musicroad/userinfo/components/UserInfoMenus.kt index 7c145454..c8bb9e32 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/components/ProfileMenus.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/components/UserInfoMenus.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.profile.components +package com.squirtles.musicroad.userinfo.components import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -31,7 +31,7 @@ import com.squirtles.musicroad.ui.theme.Gray import com.squirtles.musicroad.ui.theme.White @Composable -internal fun ProfileMenus( +internal fun UserInfoMenus( title: String, titleTextColor: Color = White, titleTextStyle: TextStyle = MaterialTheme.typography.titleMedium, diff --git a/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt new file mode 100644 index 00000000..5380b69a --- /dev/null +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt @@ -0,0 +1,59 @@ +package com.squirtles.musicroad.userinfo.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import androidx.navigation.toRoute +import com.squirtles.musicroad.navigation.MainRoute +import com.squirtles.musicroad.navigation.UserInfoRoute +import com.squirtles.musicroad.userinfo.screen.EditNotificationSettingScreen +import com.squirtles.musicroad.userinfo.screen.EditProfileScreen +import com.squirtles.musicroad.userinfo.screen.UserInfoScreen + +fun NavController.navigateUserInfo(userId: String, navOptions: NavOptions? = null) { + navigate(MainRoute.UserInfo(userId), navOptions) +} + +fun NavController.navigateEditProfile(navOptions: NavOptions? = null) { + navigate(UserInfoRoute.EditProfile, navOptions) +} + +fun NavController.navigateEditNotificationSetting(navOptions: NavOptions? = null) { + navigate(UserInfoRoute.EditNotification, navOptions) +} + +fun NavGraphBuilder.profileNavGraph( + onBackClick: () -> Unit, + onBackToMapClick: () -> Unit, + onFavoritePicksClick: (String) -> Unit, + onMyPicksClick: (String) -> Unit, + onSettingProfileClick: () -> Unit, + onSettingNotificationClick: () -> Unit, +) { + composable { backStackEntry -> + val userId = backStackEntry.toRoute().userId + + UserInfoScreen( + userId = userId, + onBackClick = onBackClick, + onBackToMapClick = onBackToMapClick, + onFavoritePicksClick = onFavoritePicksClick, + onMyPicksClick = onMyPicksClick, + onSettingProfileClick = onSettingProfileClick, + onSettingNotificationClick = onSettingNotificationClick, + ) + } + + composable { backStackEntry -> + EditProfileScreen( + onBackClick = onBackClick, + ) + } + + composable { backStackEntry -> + EditNotificationSettingScreen( + onBackClick = onBackClick + ) + } +} diff --git a/app/src/main/java/com/squirtles/musicroad/profile/screen/SettingNotificationScreen.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditNotificationSettingScreen.kt similarity index 94% rename from app/src/main/java/com/squirtles/musicroad/profile/screen/SettingNotificationScreen.kt rename to app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditNotificationSettingScreen.kt index 5e2eeca5..fb3a55c3 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/screen/SettingNotificationScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditNotificationSettingScreen.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.profile.screen +package com.squirtles.musicroad.userinfo.screen import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box @@ -19,7 +19,7 @@ import com.squirtles.musicroad.common.DefaultTopAppBar import com.squirtles.musicroad.ui.theme.White @Composable -internal fun SettingNotificationScreen( +internal fun EditNotificationSettingScreen( onBackClick: () -> Unit ) { Scaffold( diff --git a/app/src/main/java/com/squirtles/musicroad/profile/screen/SettingProfileScreen.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditProfileScreen.kt similarity index 96% rename from app/src/main/java/com/squirtles/musicroad/profile/screen/SettingProfileScreen.kt rename to app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditProfileScreen.kt index a4d7d14d..50708f1c 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/screen/SettingProfileScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditProfileScreen.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.profile.screen +package com.squirtles.musicroad.userinfo.screen import android.content.Context import android.widget.Toast @@ -51,18 +51,18 @@ import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.flowWithLifecycle import com.squirtles.musicroad.R import com.squirtles.musicroad.common.Constants.COLOR_STOPS -import com.squirtles.musicroad.profile.ProfileViewModel import com.squirtles.musicroad.ui.theme.Black import com.squirtles.musicroad.ui.theme.Gray import com.squirtles.musicroad.ui.theme.MusicRoadTheme import com.squirtles.musicroad.ui.theme.White +import com.squirtles.musicroad.userinfo.UserInfoViewModel import kotlinx.coroutines.delay import java.util.regex.Pattern @Composable -internal fun SettingProfileScreen( +internal fun EditProfileScreen( onBackClick: () -> Unit, - profileViewModel: ProfileViewModel = hiltViewModel() + profileViewModel: UserInfoViewModel = hiltViewModel() ) { val context = LocalContext.current val lifecycleOwner = LocalLifecycleOwner.current @@ -184,7 +184,9 @@ private fun SettingProfileAppBar( private fun validateUserName(userName: String, context: Context) = when { userName.length < 2 -> context.getString(R.string.setting_profile_nickname_message_length_fail_min) userName.length > 10 -> context.getString(R.string.setting_profile_nickname_message_length_fail_max) - Pattern.matches(USERNAME_PATTERN, userName).not() -> context.getString(R.string.setting_profile_nickname_message_format_fail) + Pattern.matches(USERNAME_PATTERN, userName) + .not() -> context.getString(R.string.setting_profile_nickname_message_format_fail) + else -> "" } diff --git a/app/src/main/java/com/squirtles/musicroad/profile/screen/ProfileScreen.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt similarity index 94% rename from app/src/main/java/com/squirtles/musicroad/profile/screen/ProfileScreen.kt rename to app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt index b592a464..3a58550e 100644 --- a/app/src/main/java/com/squirtles/musicroad/profile/screen/ProfileScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.profile.screen +package com.squirtles.musicroad.userinfo.screen import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -40,14 +40,14 @@ import com.squirtles.musicroad.common.Constants.COLOR_STOPS import com.squirtles.musicroad.common.DefaultTopAppBar import com.squirtles.musicroad.common.HorizontalSpacer import com.squirtles.musicroad.common.VerticalSpacer -import com.squirtles.musicroad.profile.ProfileViewModel -import com.squirtles.musicroad.profile.components.MenuItem -import com.squirtles.musicroad.profile.components.ProfileMenus import com.squirtles.musicroad.ui.theme.Primary import com.squirtles.musicroad.ui.theme.White +import com.squirtles.musicroad.userinfo.UserInfoViewModel +import com.squirtles.musicroad.userinfo.components.MenuItem +import com.squirtles.musicroad.userinfo.components.UserInfoMenus @Composable -fun ProfileScreen( +fun UserInfoScreen( userId: String, onBackClick: () -> Unit, onBackToMapClick: () -> Unit, @@ -55,7 +55,7 @@ fun ProfileScreen( onMyPicksClick: (String) -> Unit, onSettingProfileClick: () -> Unit, onSettingNotificationClick: () -> Unit, - profileViewModel: ProfileViewModel = hiltViewModel() + profileViewModel: UserInfoViewModel = hiltViewModel() ) { val scrollState = rememberScrollState() val user by profileViewModel.profileUser.collectAsStateWithLifecycle() @@ -98,7 +98,7 @@ fun ProfileScreen( VerticalSpacer(40) - ProfileMenus( + UserInfoMenus( title = stringResource(R.string.user_info_pick_category_title), menus = listOf( MenuItem( @@ -117,7 +117,7 @@ fun ProfileScreen( ) if (userId == profileViewModel.currentUser.userId) { - ProfileMenus( + UserInfoMenus( title = stringResource(R.string.user_info_setting_category_title), menus = listOf( MenuItem( From d1964da263afb88549dda42249796373a6020055 Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 30 Jan 2025 23:39:42 +0900 Subject: [PATCH 30/46] =?UTF-8?q?[refactor]=20=EC=9C=A0=EC=A0=80=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=ED=99=94=EB=A9=B4,=20route=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 화면 별 기능이 더 직관적으로 드러나도록 변경 --- .../musicroad/detail/PickDetailScreen.kt | 22 ++++++++-------- .../detail/components/DetailPickTopAppBar.kt | 4 +-- .../musicroad/main/navigation/MainNavHost.kt | 10 +++---- .../com/squirtles/musicroad/map/MapScreen.kt | 6 ++--- .../map/components/MapBottomNavBar.kt | 10 +++---- .../musicroad/map/navigation/MapNavigation.kt | 6 ++--- .../musicroad/map/navigation/NavTab.kt | 2 +- .../userinfo/navigation/UserInfoNavigation.kt | 14 +++++----- .../userinfo/screen/EditProfileScreen.kt | 26 +++++++++---------- .../userinfo/screen/UserInfoScreen.kt | 16 ++++++------ 10 files changed, 58 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt index f059607b..fd615a8a 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt @@ -82,7 +82,7 @@ import kotlin.math.absoluteValue @Composable fun PickDetailScreen( pickId: String, - onProfileClick: (String) -> Unit, + onUserInfoClick: (String) -> Unit, onBackClick: () -> Unit, onDeleted: (Context) -> Unit, playerServiceViewModel: PlayerServiceViewModel, @@ -194,7 +194,7 @@ fun PickDetailScreen( ) { page -> when (page) { DETAIL_PICK_TAB -> { - DetailPick( + PickDetailContents( pick = pick, isCreatedBySelf = isCreatedBySelf, isFavorite = isFavorite, @@ -202,7 +202,7 @@ fun PickDetailScreen( userName = pick.createdBy.userName, favoriteCount = favoriteCount, isMusicVideoAvailable = isMusicVideoAvailable, - onProfileClick = onProfileClick, + onUserInfoClick = onUserInfoClick, playerServiceViewModel = playerServiceViewModel, onBackClick = { onBackClick() @@ -263,7 +263,7 @@ fun PickDetailScreen( } // Show default pick - DetailPick( + PickDetailContents( pick = DEFAULT_PICK, isCreatedBySelf = false, isFavorite = false, @@ -272,7 +272,7 @@ fun PickDetailScreen( favoriteCount = 0, isMusicVideoAvailable = false, playerServiceViewModel = playerServiceViewModel, - onProfileClick = onProfileClick, + onUserInfoClick = onUserInfoClick, onBackClick = onBackClick, onActionClick = { } ) @@ -327,7 +327,7 @@ fun PickDetailScreen( } @Composable -private fun DetailPick( +private fun PickDetailContents( pick: Pick, isCreatedBySelf: Boolean, isFavorite: Boolean, @@ -336,7 +336,7 @@ private fun DetailPick( favoriteCount: Int, isMusicVideoAvailable: Boolean, playerServiceViewModel: PlayerServiceViewModel, - onProfileClick: (String) -> Unit, + onUserInfoClick: (String) -> Unit, onBackClick: () -> Unit, onActionClick: () -> Unit ) { @@ -375,7 +375,7 @@ private fun DetailPick( userId = userId, userName = userName, onDynamicBackgroundColor = onDynamicBackgroundColor, - onProfileClick = onProfileClick, + onUserInfoClick = onUserInfoClick, onBackClick = { onBackClick() }, @@ -483,8 +483,8 @@ fun Context.showShortToast(message: String) { @Preview @Composable -private fun DetailPickPreview() { - DetailPick( +private fun PickDetailPreview() { + PickDetailContents( pick = DEFAULT_PICK, isCreatedBySelf = false, isFavorite = false, @@ -492,7 +492,7 @@ private fun DetailPickPreview() { userName = "짱구", favoriteCount = 0, isMusicVideoAvailable = true, - onProfileClick = {}, + onUserInfoClick = {}, playerServiceViewModel = hiltViewModel(), onBackClick = {}, onActionClick = {}, diff --git a/app/src/main/java/com/squirtles/musicroad/detail/components/DetailPickTopAppBar.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/DetailPickTopAppBar.kt index b2eabde3..67dbbb9a 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/components/DetailPickTopAppBar.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/DetailPickTopAppBar.kt @@ -32,7 +32,7 @@ fun DetailPickTopAppBar( userId: String, userName: String, onDynamicBackgroundColor: Color, - onProfileClick: (String) -> Unit, + onUserInfoClick: (String) -> Unit, onBackClick: () -> Unit, onActionClick: () -> Unit, ) { @@ -42,7 +42,7 @@ fun DetailPickTopAppBar( modifier = Modifier.clickable( interactionSource = remember { MutableInteractionSource() }, indication = null, - onClick = { onProfileClick(userId) } + onClick = { onUserInfoClick(userId) } ), verticalAlignment = Alignment.CenterVertically ) { diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt index 6c3fd480..5a29584e 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt @@ -10,7 +10,7 @@ import com.squirtles.musicroad.map.navigation.mapNavGraph import com.squirtles.musicroad.media.PlayerServiceViewModel import com.squirtles.musicroad.mypick.navigation.myPickNavGraph import com.squirtles.musicroad.search.navigation.searchNavGraph -import com.squirtles.musicroad.userinfo.navigation.profileNavGraph +import com.squirtles.musicroad.userinfo.navigation.userInfoNavGraph @Composable internal fun MainNavHost( @@ -28,7 +28,7 @@ internal fun MainNavHost( playerServiceViewModel = playerServiceViewModel, onFavoriteClick = navigator::navigateFavorite, onCenterClick = navigator::navigateSearch, - onProfileClick = navigator::navigateUserInfo, + onUserInfoClick = navigator::navigateUserInfo, onPickSummaryClick = navigator::navigatePickDetail, onBackClick = navigator::navigateMap, onDeleted = mapViewModel::resetClickedMarkerState @@ -45,13 +45,13 @@ internal fun MainNavHost( onItemClick = navigator::navigatePickDetail ) - profileNavGraph( + userInfoNavGraph( onBackClick = navigator::popBackStackIfNotMap, onBackToMapClick = navigator::navigateMap, onFavoritePicksClick = navigator::navigateFavorite, onMyPicksClick = navigator::navigateMyPicks, - onSettingProfileClick = navigator::navigateEditProfile, - onSettingNotificationClick = navigator::navigateEditNotificationSetting, + onEditProfileClick = navigator::navigateEditProfile, + onEditNotificationClick = navigator::navigateEditNotificationSetting, ) myPickNavGraph( diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt index 445c6bc4..796da9f8 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt @@ -38,7 +38,7 @@ fun MapScreen( playerServiceViewModel: PlayerServiceViewModel, onFavoriteClick: (String) -> Unit, onCenterClick: () -> Unit, - onProfileClick: (String) -> Unit, + onUserInfoClick: (String) -> Unit, onPickSummaryClick: (String) -> Unit, ) { val nearPicks by mapViewModel.nearPicks.collectAsStateWithLifecycle() @@ -133,8 +133,8 @@ fun MapScreen( onCenterClick() mapViewModel.saveCurLocationForced() }, - onProfileClick = { - onProfileClick(mapViewModel.getUserId()) + onUserInfoClick = { + onUserInfoClick(mapViewModel.getUserId()) } ) } diff --git a/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomNavBar.kt b/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomNavBar.kt index 4ce12a32..e50daaab 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomNavBar.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/components/MapBottomNavBar.kt @@ -36,7 +36,7 @@ internal fun MapBottomNavBar( lastLocation: Location?, onFavoriteClick: () -> Unit, onCenterClick: () -> Unit, - onProfileClick: () -> Unit, + onUserInfoClick: () -> Unit, ) { Box( modifier = modifier, @@ -66,10 +66,10 @@ internal fun MapBottomNavBar( .weight(1f) .fillMaxHeight() .padding(start = BottomNavigationSize.HORIZONTAL_PADDING.size.dp), - tab = NavTab.PROFILE, + tab = NavTab.MYPAGE, painter = null, tint = Primary, - onClick = onProfileClick + onClick = onUserInfoClick ) } @@ -121,7 +121,7 @@ fun BottomNavigationLightPreview() { onFavoriteClick = {}, lastLocation = null, onCenterClick = {}, - onProfileClick = {} + onUserInfoClick = {} ) } } @@ -134,7 +134,7 @@ fun BottomNavigationDarkPreview() { onFavoriteClick = {}, lastLocation = null, onCenterClick = {}, - onProfileClick = {} + onUserInfoClick = {} ) } } diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt index ac6a46a6..3d1836cc 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt @@ -26,7 +26,7 @@ fun NavGraphBuilder.mapNavGraph( playerServiceViewModel: PlayerServiceViewModel, onFavoriteClick: (String) -> Unit, onCenterClick: () -> Unit, - onProfileClick: (String) -> Unit, + onUserInfoClick: (String) -> Unit, onPickSummaryClick: (String) -> Unit, onBackClick: () -> Unit, onDeleted: (Context) -> Unit, @@ -37,7 +37,7 @@ fun NavGraphBuilder.mapNavGraph( playerServiceViewModel = playerServiceViewModel, onFavoriteClick = onFavoriteClick, onCenterClick = onCenterClick, - onProfileClick = onProfileClick, + onUserInfoClick = onUserInfoClick, onPickSummaryClick = onPickSummaryClick, ) } @@ -48,7 +48,7 @@ fun NavGraphBuilder.mapNavGraph( PickDetailScreen( pickId = pickId, playerServiceViewModel = playerServiceViewModel, - onProfileClick = onProfileClick, + onUserInfoClick = onUserInfoClick, onBackClick = onBackClick, onDeleted = onDeleted, ) diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt index 63721b07..d24b0c21 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/NavTab.kt @@ -20,7 +20,7 @@ internal enum class NavTab( iconSize = null, ), - PROFILE( + MYPAGE( contentDescription = R.string.map_navigation_setting_icon_description, icon = Icons.Outlined.AccountCircle, iconSize = null, diff --git a/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt index 5380b69a..70e38576 100644 --- a/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt @@ -23,13 +23,13 @@ fun NavController.navigateEditNotificationSetting(navOptions: NavOptions? = null navigate(UserInfoRoute.EditNotification, navOptions) } -fun NavGraphBuilder.profileNavGraph( +fun NavGraphBuilder.userInfoNavGraph( onBackClick: () -> Unit, onBackToMapClick: () -> Unit, onFavoritePicksClick: (String) -> Unit, onMyPicksClick: (String) -> Unit, - onSettingProfileClick: () -> Unit, - onSettingNotificationClick: () -> Unit, + onEditProfileClick: () -> Unit, + onEditNotificationClick: () -> Unit, ) { composable { backStackEntry -> val userId = backStackEntry.toRoute().userId @@ -40,18 +40,18 @@ fun NavGraphBuilder.profileNavGraph( onBackToMapClick = onBackToMapClick, onFavoritePicksClick = onFavoritePicksClick, onMyPicksClick = onMyPicksClick, - onSettingProfileClick = onSettingProfileClick, - onSettingNotificationClick = onSettingNotificationClick, + onEditProfileClick = onEditProfileClick, + onEditNotificationClick = onEditNotificationClick, ) } - composable { backStackEntry -> + composable { EditProfileScreen( onBackClick = onBackClick, ) } - composable { backStackEntry -> + composable { EditNotificationSettingScreen( onBackClick = onBackClick ) diff --git a/app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditProfileScreen.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditProfileScreen.kt index 50708f1c..31db8a72 100644 --- a/app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditProfileScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/EditProfileScreen.kt @@ -62,19 +62,19 @@ import java.util.regex.Pattern @Composable internal fun EditProfileScreen( onBackClick: () -> Unit, - profileViewModel: UserInfoViewModel = hiltViewModel() + userInfoViewModel: UserInfoViewModel = hiltViewModel() ) { val context = LocalContext.current val lifecycleOwner = LocalLifecycleOwner.current val focusManager = LocalFocusManager.current - val userName = remember { mutableStateOf(profileViewModel.currentUser.userName) } + val userName = remember { mutableStateOf(userInfoViewModel.currentUser.userName) } val nickNameErrorMessage = remember { mutableStateOf("") } var showCreateIndicator by rememberSaveable { mutableStateOf(false) } BackHandler(enabled = showCreateIndicator) { } LaunchedEffect(Unit) { - profileViewModel.updateSuccess + userInfoViewModel.updateSuccess .flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED) .collect { isSuccess -> focusManager.clearFocus() @@ -99,12 +99,12 @@ internal fun EditProfileScreen( Scaffold( topBar = { - SettingProfileAppBar( + EditProfileAppBar( confirmEnabled = nickNameErrorMessage.value.isEmpty() && - profileViewModel.currentUser.userName != userName.value, + userInfoViewModel.currentUser.userName != userName.value, onConfirmClick = { showCreateIndicator = true - profileViewModel.updateUsername(userName.value) + userInfoViewModel.updateUsername(userName.value) }, onBackClick = onBackClick ) @@ -116,7 +116,7 @@ internal fun EditProfileScreen( .background(Brush.verticalGradient(colorStops = COLOR_STOPS)) .padding(innerPadding) ) { - SettingProfileContent(userName, nickNameErrorMessage) + EditProfileContents(userName, nickNameErrorMessage) } } @@ -139,7 +139,7 @@ internal fun EditProfileScreen( @OptIn(ExperimentalMaterial3Api::class) @Composable -private fun SettingProfileAppBar( +private fun EditProfileAppBar( confirmEnabled: Boolean, onConfirmClick: () -> Unit, onBackClick: () -> Unit @@ -191,7 +191,7 @@ private fun validateUserName(userName: String, context: Context) = when { } @Composable -private fun SettingProfileContent( +private fun EditProfileContents( userName: MutableState, nickNameErrorMessage: MutableState ) { @@ -238,15 +238,15 @@ private const val USERNAME_PATTERN = "^[ㄱ-ㅎ|ㅏ-ㅣ가-힣a-zA-Z0-9]+$" @Preview @Composable -private fun SettingProfileAppBarPreview() { - SettingProfileAppBar(false, {}, {}) +private fun EditProfileAppBarPreview() { + EditProfileAppBar(false, {}, {}) } @Preview @Composable -private fun SettingProfileContentPreview() { +private fun EditProfileContentPreview() { MusicRoadTheme { - SettingProfileContent( + EditProfileContents( remember { mutableStateOf("짱구") }, remember { mutableStateOf("") } ) diff --git a/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt index 3a58550e..deb561f3 100644 --- a/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt @@ -53,15 +53,15 @@ fun UserInfoScreen( onBackToMapClick: () -> Unit, onFavoritePicksClick: (String) -> Unit, onMyPicksClick: (String) -> Unit, - onSettingProfileClick: () -> Unit, - onSettingNotificationClick: () -> Unit, - profileViewModel: UserInfoViewModel = hiltViewModel() + onEditProfileClick: () -> Unit, + onEditNotificationClick: () -> Unit, + userInfoViewModel: UserInfoViewModel = hiltViewModel() ) { val scrollState = rememberScrollState() - val user by profileViewModel.profileUser.collectAsStateWithLifecycle() + val user by userInfoViewModel.profileUser.collectAsStateWithLifecycle() LaunchedEffect(Unit) { - profileViewModel.getUserById(userId) + userInfoViewModel.getUserById(userId) } Scaffold( @@ -116,7 +116,7 @@ fun UserInfoScreen( ) ) - if (userId == profileViewModel.currentUser.userId) { + if (userId == userInfoViewModel.currentUser.userId) { UserInfoMenus( title = stringResource(R.string.user_info_setting_category_title), menus = listOf( @@ -124,13 +124,13 @@ fun UserInfoScreen( imageVector = Icons.Outlined.SwitchAccount, contentDescription = stringResource(R.string.user_info_setting_profile_menu_icon_description), menuTitle = stringResource(R.string.user_info_setting_profile_menu_title), - onMenuClick = onSettingProfileClick + onMenuClick = onEditProfileClick ), MenuItem( imageVector = Icons.Outlined.Notifications, contentDescription = stringResource(R.string.user_info_setting_notification_menu_icon_description), menuTitle = stringResource(R.string.user_info_setting_notification_menu_title), - onMenuClick = onSettingNotificationClick + onMenuClick = onEditNotificationClick ) ) ) From 55a6d62d5ca1f33bd26c565014eeea16cb44b34e Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 30 Jan 2025 23:45:41 +0900 Subject: [PATCH 31/46] =?UTF-8?q?[refactor]=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=A0=95=EC=A0=95,=20=ED=95=A8=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/squirtles/musicroad/detail/DetailViewModel.kt | 1 - .../java/com/squirtles/musicroad/detail/PickDetailScreen.kt | 5 +---- .../com/squirtles/musicroad/map/navigation/MapNavigation.kt | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt index 779175ff..247b19c1 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/DetailViewModel.kt @@ -14,7 +14,6 @@ import com.squirtles.domain.usecase.mypick.DeletePickUseCase import com.squirtles.domain.usecase.pick.FetchIsFavoriteUseCase import com.squirtles.domain.usecase.pick.FetchPickUseCase import com.squirtles.domain.usecase.user.GetCurrentUserUseCase -import com.squirtles.musicroad.pick.DETAIL_PICK_TAB import com.squirtles.musicroad.utils.throttleFirst import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.async diff --git a/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt index fd615a8a..1802e357 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/PickDetailScreen.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.pick +package com.squirtles.musicroad.detail import android.app.Activity import android.content.Context @@ -59,10 +59,7 @@ import com.squirtles.musicroad.common.DialogTextButton import com.squirtles.musicroad.common.HorizontalSpacer import com.squirtles.musicroad.common.MessageAlertDialog import com.squirtles.musicroad.common.VerticalSpacer -import com.squirtles.musicroad.detail.DetailViewModel import com.squirtles.musicroad.detail.DetailViewModel.Companion.DEFAULT_PICK -import com.squirtles.musicroad.detail.FavoriteAction -import com.squirtles.musicroad.detail.PickDetailUiState import com.squirtles.musicroad.detail.components.CircleAlbumCover import com.squirtles.musicroad.detail.components.CommentText import com.squirtles.musicroad.detail.components.DetailPickTopAppBar diff --git a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt index 3d1836cc..507103d6 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/navigation/MapNavigation.kt @@ -11,7 +11,7 @@ import com.squirtles.musicroad.map.MapViewModel import com.squirtles.musicroad.media.PlayerServiceViewModel import com.squirtles.musicroad.navigation.MapRoute import com.squirtles.musicroad.navigation.Route -import com.squirtles.musicroad.pick.PickDetailScreen +import com.squirtles.musicroad.detail.PickDetailScreen fun NavController.navigateMap(navOptions: NavOptions? = null) { navigate(Route.Map, navOptions) From 7f6e6f50b4fd8ab43acfd87ee5ac9592f588761c Mon Sep 17 00:00:00 2001 From: miller198 Date: Thu, 30 Jan 2025 23:46:37 +0900 Subject: [PATCH 32/46] =?UTF-8?q?[style]=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20import=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../squirtles/musicroad/detail/components/CircleAlbumCover.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt b/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt index bef7119a..ab5a4868 100644 --- a/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt +++ b/app/src/main/java/com/squirtles/musicroad/detail/components/CircleAlbumCover.kt @@ -1,6 +1,5 @@ package com.squirtles.musicroad.detail.components -import android.util.Size import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize From f52bd5393e1724d2e69d2fca48c301c8c9619d39 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 02:37:26 +0900 Subject: [PATCH 33/46] =?UTF-8?q?[chore]=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/common/picklist/Extension.kt | 17 --- .../musicroad/common/picklist/PickListItem.kt | 107 ------------------ 2 files changed, 124 deletions(-) delete mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/Extension.kt delete mode 100644 app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/Extension.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/Extension.kt deleted file mode 100644 index 53bac7f1..00000000 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/Extension.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.squirtles.musicroad.common.picklist - -import com.squirtles.domain.model.Order -import com.squirtles.domain.model.Pick - -fun List.setOrderedList(order: Order): PickListUiState.Success { - return PickListUiState.Success( - pickList = when (order) { - Order.LATEST -> this - - Order.OLDEST -> this.reversed() - - Order.FAVORITE_DESC -> this.sortedByDescending { it.favoriteCount } - }, - order = order - ) -} diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt deleted file mode 100644 index aa9c98db..00000000 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListItem.kt +++ /dev/null @@ -1,107 +0,0 @@ -package com.squirtles.musicroad.common.picklist - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.material3.ripple -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import com.squirtles.domain.model.Song -import com.squirtles.musicroad.common.AlbumImage -import com.squirtles.musicroad.common.CommentText -import com.squirtles.musicroad.common.Constants -import com.squirtles.musicroad.common.CreatedByOtherUserText -import com.squirtles.musicroad.common.FavoriteCountText -import com.squirtles.musicroad.common.HorizontalSpacer -import com.squirtles.musicroad.common.SongInfoText -import com.squirtles.musicroad.ui.theme.Gray -import com.squirtles.musicroad.ui.theme.White - -@Composable -fun PickListItem( - song: Song, - isCreatedByOthers: Boolean, - createUserName: String, - favoriteCount: Int, - comment: String, - createdAt: String, - onItemClick: () -> Unit, -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = ripple(color = White), - ) { onItemClick() } - .padding( - horizontal = Constants.DEFAULT_PADDING, - vertical = Constants.DEFAULT_PADDING / 2 - ), - horizontalArrangement = Arrangement.spacedBy(Constants.DEFAULT_PADDING), - verticalAlignment = Alignment.CenterVertically - ) { - AlbumImage( - imageUrl = song.getImageUrlWithSize(Constants.REQUEST_IMAGE_SIZE_DEFAULT.width, Constants.REQUEST_IMAGE_SIZE_DEFAULT.height), - modifier = Modifier - .size(64.dp) - .clip(RoundedCornerShape(8.dp)) - ) - - Column( - modifier = Modifier.weight(1f) - ) { - SongInfoText( - songInfo = "${song.songName} - ${song.artistName}", - color = White - ) - - Row( - verticalAlignment = Alignment.CenterVertically - ) { - if (isCreatedByOthers) { - CreatedByOtherUserText( - userName = createUserName, - modifier = Modifier.weight(weight = 1f, fill = false), - color = Gray - ) - } else { - Text( - text = createdAt, - modifier = Modifier.weight(weight = 1f, fill = false), - color = Gray, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = MaterialTheme.typography.bodyMedium, - ) - } - - HorizontalSpacer(8) - - FavoriteCountText( - favoriteCount = favoriteCount, - iconTint = Gray, - color = Gray - ) - } - - CommentText( - comment = comment, - color = Gray - ) - } - } -} From 649d16beb1c12e2c888c57d804ec805dd7c73132 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 02:37:45 +0900 Subject: [PATCH 34/46] =?UTF-8?q?[refactor]=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC,=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/picklist/PickListContents.kt | 5 +++++ .../common/picklist/PickListViewModel.kt | 21 +++++++++---------- .../DeleteSelectedPickDialog.kt | 3 ++- .../{ => components}/EditModeAction.kt | 2 +- .../{ => components}/EditModeBottomButton.kt | 2 +- .../{ => components}/OrderBottomSheet.kt | 2 +- .../picklist/{ => components}/PickItem.kt | 2 +- 7 files changed, 21 insertions(+), 16 deletions(-) rename app/src/main/java/com/squirtles/musicroad/common/picklist/{ => components}/DeleteSelectedPickDialog.kt (92%) rename app/src/main/java/com/squirtles/musicroad/common/picklist/{ => components}/EditModeAction.kt (96%) rename app/src/main/java/com/squirtles/musicroad/common/picklist/{ => components}/EditModeBottomButton.kt (97%) rename app/src/main/java/com/squirtles/musicroad/common/picklist/{ => components}/OrderBottomSheet.kt (98%) rename app/src/main/java/com/squirtles/musicroad/common/picklist/{ => components}/PickItem.kt (98%) diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt index b32eb75e..ff2aa1e3 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt @@ -41,6 +41,11 @@ import com.squirtles.musicroad.common.Constants.DEFAULT_PADDING import com.squirtles.musicroad.common.CountText import com.squirtles.musicroad.common.DefaultTopAppBar import com.squirtles.musicroad.common.VerticalSpacer +import com.squirtles.musicroad.common.picklist.components.DeleteSelectedPickDialog +import com.squirtles.musicroad.common.picklist.components.EditModeAction +import com.squirtles.musicroad.common.picklist.components.EditModeBottomButton +import com.squirtles.musicroad.common.picklist.components.OrderBottomSheet +import com.squirtles.musicroad.common.picklist.components.PickItem import com.squirtles.musicroad.ui.theme.Primary import com.squirtles.musicroad.ui.theme.White diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt index 7be9467b..2348f79f 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt @@ -44,18 +44,9 @@ abstract class PickListViewModel( } private fun sortPickList(order: Order) { - pickList?.let { pickList -> - val sortedList = when (order) { - Order.LATEST -> pickList - - Order.OLDEST -> pickList.reversed() - - Order.FAVORITE_DESC -> - pickList.sortedByDescending { it.favoriteCount } - } - + pickList?.let { _pickListUiState.value = PickListUiState.Success( - pickList = sortedList, + pickList = it.setOrderedList(order), order = order ) } @@ -101,4 +92,12 @@ abstract class PickListViewModel( } } } + + private fun List.setOrderedList(order: Order): List { + return when (order) { + Order.LATEST -> this + Order.OLDEST -> this.reversed() + Order.FAVORITE_DESC -> this.sortedByDescending { it.favoriteCount } + } + } } diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/DeleteSelectedPickDialog.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/DeleteSelectedPickDialog.kt similarity index 92% rename from app/src/main/java/com/squirtles/musicroad/common/picklist/DeleteSelectedPickDialog.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/components/DeleteSelectedPickDialog.kt index 701ea0a3..bd83d6b7 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/DeleteSelectedPickDialog.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/DeleteSelectedPickDialog.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.common.picklist +package com.squirtles.musicroad.common.picklist.components import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource @@ -7,6 +7,7 @@ import com.squirtles.musicroad.R import com.squirtles.musicroad.common.DialogTextButton import com.squirtles.musicroad.common.HorizontalSpacer import com.squirtles.musicroad.common.MessageAlertDialog +import com.squirtles.musicroad.common.picklist.PickListType import com.squirtles.musicroad.ui.theme.Primary @Composable diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeAction.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/EditModeAction.kt similarity index 96% rename from app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeAction.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/components/EditModeAction.kt index 48a73ee0..e904a8dd 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeAction.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/EditModeAction.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.common.picklist +package com.squirtles.musicroad.common.picklist.components import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeBottomButton.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/EditModeBottomButton.kt similarity index 97% rename from app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeBottomButton.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/components/EditModeBottomButton.kt index b28049ed..a8014244 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/EditModeBottomButton.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/EditModeBottomButton.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.common.picklist +package com.squirtles.musicroad.common.picklist.components import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/OrderBottomSheet.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/OrderBottomSheet.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/common/picklist/OrderBottomSheet.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/components/OrderBottomSheet.kt index e59868a0..401c0997 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/OrderBottomSheet.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/OrderBottomSheet.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.common.picklist +package com.squirtles.musicroad.common.picklist.components import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickItem.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/PickItem.kt similarity index 98% rename from app/src/main/java/com/squirtles/musicroad/common/picklist/PickItem.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/components/PickItem.kt index 3c56fd8a..54812bad 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickItem.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/components/PickItem.kt @@ -1,4 +1,4 @@ -package com.squirtles.musicroad.common.picklist +package com.squirtles.musicroad.common.picklist.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable From f44a3311478b52ddc22134ba355179b4e28004ff Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 02:49:09 +0900 Subject: [PATCH 35/46] =?UTF-8?q?[refactor]=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit null -> emptyList --- .../common/picklist/PickListContents.kt | 4 ++-- .../common/picklist/PickListViewModel.kt | 20 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt index ff2aa1e3..b142e656 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt @@ -123,8 +123,8 @@ fun PickListContents( } is PickListUiState.Success -> { - val pickList = (uiState as PickListUiState.Success).pickList - val order = (uiState as PickListUiState.Success).order + val pickList = uiState.pickList + val order = uiState.order Column( modifier = Modifier.fillMaxSize() diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt index 2348f79f..f4e2093e 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt @@ -22,7 +22,7 @@ abstract class PickListViewModel( val deletePickListUseCase: DeletePickListUseCaseTemplate ) : ViewModel() { - private var pickList: List? = null + private var pickList: List = emptyList() private val _pickListUiState = MutableStateFlow(PickListUiState.Loading) val pickListUiState = _pickListUiState.asStateFlow() @@ -44,12 +44,10 @@ abstract class PickListViewModel( } private fun sortPickList(order: Order) { - pickList?.let { - _pickListUiState.value = PickListUiState.Success( - pickList = it.setOrderedList(order), - order = order - ) - } + _pickListUiState.value = PickListUiState.Success( + pickList = pickList.setOrderedList(order), + order = order + ) } fun setListOrder(order: Order) { @@ -66,9 +64,7 @@ abstract class PickListViewModel( } fun selectAllPicks() { - pickList?.let { pickList -> - _selectedPicksId.value = pickList.map { it.id }.toSet() - } + _selectedPicksId.value = pickList.map { it.id }.toSet() } fun deselectAllPicks() { @@ -84,6 +80,7 @@ abstract class PickListViewModel( }.awaitAll() deselectAllPicks() + if (deleteJobList.all { it.isSuccess }) { fetchPickList(userId) } else { @@ -94,7 +91,8 @@ abstract class PickListViewModel( } private fun List.setOrderedList(order: Order): List { - return when (order) { + return if (pickList.isEmpty()) this + else when (order) { Order.LATEST -> this Order.OLDEST -> this.reversed() Order.FAVORITE_DESC -> this.sortedByDescending { it.favoriteCount } From 97b4349fb3e94cdd6f54212fe1435c727af65f66 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 02:53:41 +0900 Subject: [PATCH 36/46] =?UTF-8?q?[style]=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/squirtles/musicroad/create/CreatePickScreen.kt | 2 +- .../java/com/squirtles/musicroad/create/CreatePickViewModel.kt | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt b/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt index ede83043..21c7bbb6 100644 --- a/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/create/CreatePickScreen.kt @@ -72,7 +72,7 @@ fun CreatePickScreen( onCreateClick: (String) -> Unit, createPickViewModel: CreatePickViewModel = hiltViewModel(), ) { -// val song = createPickViewModel.selectedSong ?: DEFAULT_SONG + val comment = createPickViewModel.comment.collectAsStateWithLifecycle() val uiState by createPickViewModel.createPickUiState.collectAsStateWithLifecycle() var showCreateIndicator by rememberSaveable { mutableStateOf(false) } diff --git a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt index 1a039a68..b1a7cbdc 100644 --- a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt @@ -12,7 +12,6 @@ import com.squirtles.domain.model.Pick import com.squirtles.domain.model.Song import com.squirtles.domain.usecase.location.GetLastLocationUseCase import com.squirtles.domain.usecase.music.FetchMusicVideoUseCase -import com.squirtles.domain.usecase.music.FetchSongsUseCase import com.squirtles.domain.usecase.mypick.CreatePickUseCase import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.musicroad.navigation.SearchRoute @@ -30,7 +29,6 @@ import javax.inject.Inject class CreatePickViewModel @Inject constructor( savedStateHandle: SavedStateHandle, getLastLocationUseCase: GetLastLocationUseCase, - private val fetchSongsUseCase: FetchSongsUseCase, private val fetchMusicVideoUseCase: FetchMusicVideoUseCase, private val createPickUseCase: CreatePickUseCase, private val getCurrentUserUseCase: GetCurrentUserUseCase From 15c54f1e4c14d134acabd3d018aef6bc5bd4144e Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 02:54:28 +0900 Subject: [PATCH 37/46] =?UTF-8?q?[refactor]=20=EC=BB=B4=ED=8F=AC=EC=A6=88?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PickListContents -> PickListScreenContents LazyColumn 컨텐츠와의 혼동방지 --- .../{PickListContents.kt => PickListScreenContents.kt} | 2 +- .../java/com/squirtles/musicroad/favorite/FavoriteScreen.kt | 4 ++-- .../main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename app/src/main/java/com/squirtles/musicroad/common/picklist/{PickListContents.kt => PickListScreenContents.kt} (99%) diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreenContents.kt similarity index 99% rename from app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt rename to app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreenContents.kt index b142e656..0c320a70 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListContents.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListScreenContents.kt @@ -50,7 +50,7 @@ import com.squirtles.musicroad.ui.theme.Primary import com.squirtles.musicroad.ui.theme.White @Composable -fun PickListContents( +fun PickListScreenContents( userId: String, showOrderBottomSheet: Boolean, selectedPicksId: Set, diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt index 74bd5820..373fc87d 100644 --- a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt @@ -8,7 +8,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.squirtles.musicroad.common.picklist.PickListContents +import com.squirtles.musicroad.common.picklist.PickListScreenContents import com.squirtles.musicroad.common.picklist.PickListType @Composable @@ -26,7 +26,7 @@ fun FavoriteScreen( favoriteListViewModel.fetchPickList(userId) } - PickListContents( + PickListScreenContents( userId = userId, showOrderBottomSheet = showOrderBottomSheet, selectedPicksId = selectedPicksId, diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt index 7efe9d33..9d696091 100644 --- a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt @@ -8,7 +8,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.squirtles.musicroad.common.picklist.PickListContents +import com.squirtles.musicroad.common.picklist.PickListScreenContents import com.squirtles.musicroad.common.picklist.PickListType @Composable @@ -26,7 +26,7 @@ fun MyPickScreen( myPickListViewModel.fetchPickList(userId) } - PickListContents( + PickListScreenContents( userId = userId, showOrderBottomSheet = showOrderBottomSheet, selectedPicksId = selectedPicksId, From 5c9c66d7bea01fbc8cc1c076a88477137b843147 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 02:58:29 +0900 Subject: [PATCH 38/46] =?UTF-8?q?[fix]=20detail=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/squirtles/musicroad/main/navigation/MainNavHost.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt index 5a29584e..1d9227c3 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt @@ -30,7 +30,7 @@ internal fun MainNavHost( onCenterClick = navigator::navigateSearch, onUserInfoClick = navigator::navigateUserInfo, onPickSummaryClick = navigator::navigatePickDetail, - onBackClick = navigator::navigateMap, + onBackClick = navigator::popBackStackIfNotMap, onDeleted = mapViewModel::resetClickedMarkerState ) From c189da25dcecf9a4a16106ec97656dab5a8ac7d4 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 03:06:19 +0900 Subject: [PATCH 39/46] =?UTF-8?q?[refactor]=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD,=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=20=EB=AA=85=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/common/picklist/PickListViewModel.kt | 4 ++-- .../squirtles/musicroad/favorite/FavoriteListViewModel.kt | 8 ++++---- .../com/squirtles/musicroad/mypick/MyPickListViewModel.kt | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt index f4e2093e..129f4f5e 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt @@ -19,7 +19,7 @@ abstract class PickListViewModel( val fetchPickListUseCase: FetchPickListUseCaseTemplate, val getPickListOrderUseCase: GetPickListOrderUseCaseTemplate, val savePickListOrderUseCase: SavePickListOrderUseCaseTemplate, - val deletePickListUseCase: DeletePickListUseCaseTemplate + val removePickUseCase: DeletePickListUseCaseTemplate ) : ViewModel() { private var pickList: List = emptyList() @@ -76,7 +76,7 @@ abstract class PickListViewModel( _pickListUiState.value = PickListUiState.Loading val deleteJobList = _selectedPicksId.value.map { pickId -> - async { deletePickListUseCase(pickId, userId) } + async { removePickUseCase(pickId, userId) } }.awaitAll() deselectAllPicks() diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt index f7f7321c..7047c957 100644 --- a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt @@ -15,8 +15,8 @@ class FavoriteListViewModel @Inject constructor( saveFavoriteListOrderUseCase: SaveFavoriteListOrderUseCase, deleteFavoriteUseCase: DeleteFavoriteUseCase ) : PickListViewModel( - fetchFavoritePicksUseCase, - getFavoriteListOrderUseCase, - saveFavoriteListOrderUseCase, - deleteFavoriteUseCase + fetchPickListUseCase = fetchFavoritePicksUseCase, + getPickListOrderUseCase = getFavoriteListOrderUseCase, + savePickListOrderUseCase = saveFavoriteListOrderUseCase, + removePickUseCase = deleteFavoriteUseCase ) diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt index e6d5db99..dfc83ca4 100644 --- a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt @@ -15,8 +15,8 @@ class MyPickListViewModel @Inject constructor( saveMyPickListOrderUseCase: SaveMyPickListOrderUseCase, deletePickUseCase: DeletePickUseCase, ) : PickListViewModel( - fetchMyPicksUseCase, - getMyPickListOrderUseCase, - saveMyPickListOrderUseCase, - deletePickUseCase + fetchPickListUseCase = fetchMyPicksUseCase, + getPickListOrderUseCase = getMyPickListOrderUseCase, + savePickListOrderUseCase = saveMyPickListOrderUseCase, + removePickUseCase = deletePickUseCase ) From 33dea53109d1d5d2201157393ca6558faf35fd38 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 03:17:45 +0900 Subject: [PATCH 40/46] =?UTF-8?q?[refactor]=20=EB=82=B4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/main/navigation/MainNavHost.kt | 7 +---- .../main/navigation/MainNavigator.kt | 2 +- .../mypick/navigation/MyPickNavigation.kt | 28 ------------------- .../userinfo/navigation/UserInfoNavigation.kt | 16 +++++++++++ 4 files changed, 18 insertions(+), 35 deletions(-) delete mode 100644 app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt index 1d9227c3..c9c86a12 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt @@ -8,7 +8,6 @@ import com.squirtles.musicroad.favorite.navigation.favoriteNavGraph import com.squirtles.musicroad.map.MapViewModel import com.squirtles.musicroad.map.navigation.mapNavGraph import com.squirtles.musicroad.media.PlayerServiceViewModel -import com.squirtles.musicroad.mypick.navigation.myPickNavGraph import com.squirtles.musicroad.search.navigation.searchNavGraph import com.squirtles.musicroad.userinfo.navigation.userInfoNavGraph @@ -47,16 +46,12 @@ internal fun MainNavHost( userInfoNavGraph( onBackClick = navigator::popBackStackIfNotMap, + onItemClick = navigator::navigatePickDetail, onBackToMapClick = navigator::navigateMap, onFavoritePicksClick = navigator::navigateFavorite, onMyPicksClick = navigator::navigateMyPicks, onEditProfileClick = navigator::navigateEditProfile, onEditNotificationClick = navigator::navigateEditNotificationSetting, ) - - myPickNavGraph( - onBackClick = navigator::popBackStackIfNotMap, - onItemClick = navigator::navigatePickDetail - ) } } diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt index 7edc56d6..ab92842f 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt @@ -12,12 +12,12 @@ import com.squirtles.domain.model.Song import com.squirtles.musicroad.favorite.navigation.navigateFavorite import com.squirtles.musicroad.map.navigation.navigateMap import com.squirtles.musicroad.map.navigation.navigatePickDetail -import com.squirtles.musicroad.mypick.navigation.navigateMyPicks import com.squirtles.musicroad.navigation.Route import com.squirtles.musicroad.search.navigation.navigateCreate import com.squirtles.musicroad.search.navigation.navigateSearch import com.squirtles.musicroad.userinfo.navigation.navigateEditNotificationSetting import com.squirtles.musicroad.userinfo.navigation.navigateEditProfile +import com.squirtles.musicroad.userinfo.navigation.navigateMyPicks import com.squirtles.musicroad.userinfo.navigation.navigateUserInfo internal class MainNavigator( diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt b/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt deleted file mode 100644 index fe7fd666..00000000 --- a/app/src/main/java/com/squirtles/musicroad/mypick/navigation/MyPickNavigation.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.squirtles.musicroad.mypick.navigation - -import androidx.navigation.NavController -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavOptions -import androidx.navigation.compose.composable -import androidx.navigation.toRoute -import com.squirtles.musicroad.mypick.MyPickScreen -import com.squirtles.musicroad.navigation.UserInfoRoute - -fun NavController.navigateMyPicks(userId: String, navOptions: NavOptions) { - navigate(UserInfoRoute.MyPicks(userId), navOptions) -} - -fun NavGraphBuilder.myPickNavGraph( - onBackClick: () -> Unit, - onItemClick: (String) -> Unit, -) { - composable { backStackEntry -> - val userId = backStackEntry.toRoute().userId - - MyPickScreen( - userId = userId, - onBackClick = onBackClick, - onItemClick = onItemClick - ) - } -} diff --git a/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt index 70e38576..c87d6418 100644 --- a/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/navigation/UserInfoNavigation.kt @@ -5,6 +5,7 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.toRoute +import com.squirtles.musicroad.mypick.MyPickScreen import com.squirtles.musicroad.navigation.MainRoute import com.squirtles.musicroad.navigation.UserInfoRoute import com.squirtles.musicroad.userinfo.screen.EditNotificationSettingScreen @@ -23,8 +24,13 @@ fun NavController.navigateEditNotificationSetting(navOptions: NavOptions? = null navigate(UserInfoRoute.EditNotification, navOptions) } +fun NavController.navigateMyPicks(userId: String, navOptions: NavOptions) { + navigate(UserInfoRoute.MyPicks(userId), navOptions) +} + fun NavGraphBuilder.userInfoNavGraph( onBackClick: () -> Unit, + onItemClick: (String) -> Unit, onBackToMapClick: () -> Unit, onFavoritePicksClick: (String) -> Unit, onMyPicksClick: (String) -> Unit, @@ -56,4 +62,14 @@ fun NavGraphBuilder.userInfoNavGraph( onBackClick = onBackClick ) } + + composable { backStackEntry -> + val userId = backStackEntry.toRoute().userId + + MyPickScreen( + userId = userId, + onBackClick = onBackClick, + onItemClick = onItemClick + ) + } } From 21a0c1fba43d08c1ac8954b5baaa269b245dada9 Mon Sep 17 00:00:00 2001 From: miller198 Date: Fri, 31 Jan 2025 03:32:18 +0900 Subject: [PATCH 41/46] =?UTF-8?q?[refactor]=20detail=20=EB=92=A4=EB=A1=9C?= =?UTF-8?q?=EA=B0=80=EA=B8=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/squirtles/musicroad/main/navigation/MainNavHost.kt | 4 +++- .../squirtles/musicroad/main/navigation/MainNavigator.kt | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt index c9c86a12..f546f96b 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavHost.kt @@ -36,7 +36,9 @@ internal fun MainNavHost( searchNavGraph( onBackClick = navigator::popBackStackIfNotMap, onItemClick = navigator::navigateCreate, - onCreateClick = navigator::navigatePickDetail, + onCreateClick = { pickId -> + navigator.navigatePickDetail(pickId, true) + }, ) favoriteNavGraph( diff --git a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt index ab92842f..a29728fb 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/navigation/MainNavigator.kt @@ -49,10 +49,15 @@ internal class MainNavigator( ) } - fun navigatePickDetail(pickId: String) { + fun navigatePickDetail(pickId: String, navigateToMap: Boolean = false) { navController.navigatePickDetail( pickId = pickId, navOptions = navOptions { + if (navigateToMap) { + popUpTo(startDestination) { + inclusive = false + } + } launchSingleTop = true } ) From 6d4296fd79bf2b34a1d71345ccebc0a9188b464f Mon Sep 17 00:00:00 2001 From: miller198 Date: Sat, 1 Feb 2025 21:59:02 +0900 Subject: [PATCH 42/46] =?UTF-8?q?[refactor]=20abstract=20class=20->=20inte?= =?UTF-8?q?rface=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/picklist/PickListViewModel.kt | 16 ++++++++-------- .../usecase/favorite/DeleteFavoriteUseCase.kt | 6 +++--- .../favorite/FetchFavoritePicksUseCase.kt | 6 +++--- .../domain/usecase/mypick/DeletePickUseCase.kt | 6 +++--- .../domain/usecase/mypick/FetchMyPicksUseCase.kt | 6 +++--- .../usecase/order/GetFavoriteListOrderUseCase.kt | 6 +++--- .../usecase/order/GetMyPickListOrderUseCase.kt | 6 +++--- .../order/SaveFavoriteListOrderUseCase.kt | 6 +++--- .../usecase/order/SaveMyPickListOrderUseCase.kt | 7 ++++--- .../picklist/DeletePickListUseCaseInterface.kt | 5 +++++ .../picklist/DeletePickListUseCaseTemplate.kt | 9 --------- .../picklist/FetchPickListUseCaseInterface.kt | 7 +++++++ .../picklist/FetchPickListUseCaseTemplate.kt | 10 ---------- .../picklist/GetPickListOrderUseCaseInterface.kt | 7 +++++++ .../picklist/GetPickListOrderUseCaseTemplate.kt | 10 ---------- .../SavePickListOrderUseCaseInterface.kt | 7 +++++++ .../picklist/SavePickListOrderUseCaseTemplate.kt | 10 ---------- 17 files changed, 59 insertions(+), 71 deletions(-) create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseInterface.kt delete mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseTemplate.kt create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseInterface.kt delete mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseTemplate.kt create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseInterface.kt delete mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseTemplate.kt create mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseInterface.kt delete mode 100644 domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseTemplate.kt diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt index 129f4f5e..f2a552e1 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt @@ -5,10 +5,10 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.model.Order import com.squirtles.domain.model.Pick -import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseTemplate -import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseTemplate -import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseTemplate -import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseTemplate +import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseInterface +import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseInterface +import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseInterface +import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseInterface import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.flow.MutableStateFlow @@ -16,10 +16,10 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch abstract class PickListViewModel( - val fetchPickListUseCase: FetchPickListUseCaseTemplate, - val getPickListOrderUseCase: GetPickListOrderUseCaseTemplate, - val savePickListOrderUseCase: SavePickListOrderUseCaseTemplate, - val removePickUseCase: DeletePickListUseCaseTemplate + val fetchPickListUseCase: FetchPickListUseCaseInterface, + val getPickListOrderUseCase: GetPickListOrderUseCaseInterface, + val savePickListOrderUseCase: SavePickListOrderUseCaseInterface, + val removePickUseCase: DeletePickListUseCaseInterface ) : ViewModel() { private var pickList: List = emptyList() diff --git a/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt index d9b18b0c..e2a485f9 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/favorite/DeleteFavoriteUseCase.kt @@ -1,12 +1,12 @@ package com.squirtles.domain.usecase.favorite import com.squirtles.domain.firebase.FirebaseRepository -import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseTemplate +import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseInterface import javax.inject.Inject class DeleteFavoriteUseCase @Inject constructor( - firebaseRepository: FirebaseRepository -) : DeletePickListUseCaseTemplate(firebaseRepository) { + private val firebaseRepository: FirebaseRepository +) : DeletePickListUseCaseInterface { override suspend operator fun invoke(pickId: String, userId: String) = firebaseRepository.deleteFavorite(pickId, userId) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt index 3d49e132..ab3b8459 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/favorite/FetchFavoritePicksUseCase.kt @@ -1,11 +1,11 @@ package com.squirtles.domain.usecase.favorite import com.squirtles.domain.firebase.FirebaseRepository -import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseTemplate +import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseInterface import javax.inject.Inject class FetchFavoritePicksUseCase @Inject constructor( - firebaseRepository: FirebaseRepository -) : FetchPickListUseCaseTemplate(firebaseRepository) { + private val firebaseRepository: FirebaseRepository +) : FetchPickListUseCaseInterface { override suspend operator fun invoke(userId: String) = firebaseRepository.fetchFavoritePicks(userId) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt index b26047c2..98985e75 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/mypick/DeletePickUseCase.kt @@ -1,12 +1,12 @@ package com.squirtles.domain.usecase.mypick import com.squirtles.domain.firebase.FirebaseRepository -import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseTemplate +import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseInterface import javax.inject.Inject class DeletePickUseCase @Inject constructor( - firebaseRepository: FirebaseRepository -) : DeletePickListUseCaseTemplate(firebaseRepository) { + private val firebaseRepository: FirebaseRepository +) : DeletePickListUseCaseInterface { override suspend operator fun invoke(pickId: String, userId: String): Result = firebaseRepository.deletePick(pickId, userId) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt index cc0b1d63..4774ad82 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/mypick/FetchMyPicksUseCase.kt @@ -1,12 +1,12 @@ package com.squirtles.domain.usecase.mypick import com.squirtles.domain.firebase.FirebaseRepository -import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseTemplate +import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseInterface import javax.inject.Inject class FetchMyPicksUseCase @Inject constructor( - firebaseRepository: FirebaseRepository -) : FetchPickListUseCaseTemplate(firebaseRepository) { + private val firebaseRepository: FirebaseRepository +) : FetchPickListUseCaseInterface { override suspend operator fun invoke(userId: String) = firebaseRepository.fetchMyPicks(userId) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt index 62c247f1..98a20b6a 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/GetFavoriteListOrderUseCase.kt @@ -1,11 +1,11 @@ package com.squirtles.domain.usecase.order import com.squirtles.domain.local.LocalRepository -import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseTemplate +import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseInterface import javax.inject.Inject class GetFavoriteListOrderUseCase @Inject constructor( - localRepository: LocalRepository -) : GetPickListOrderUseCaseTemplate(localRepository) { + private val localRepository: LocalRepository +) : GetPickListOrderUseCaseInterface { override suspend operator fun invoke() = localRepository.favoriteListOrder } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt index bd371656..b41e7d66 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/GetMyPickListOrderUseCase.kt @@ -1,11 +1,11 @@ package com.squirtles.domain.usecase.order import com.squirtles.domain.local.LocalRepository -import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseTemplate +import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseInterface import javax.inject.Inject class GetMyPickListOrderUseCase @Inject constructor( - localRepository: LocalRepository -) : GetPickListOrderUseCaseTemplate(localRepository) { + private val localRepository: LocalRepository +) : GetPickListOrderUseCaseInterface { override suspend operator fun invoke() = localRepository.myListOrder } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt index dfa6f727..8b7ed05f 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveFavoriteListOrderUseCase.kt @@ -2,11 +2,11 @@ package com.squirtles.domain.usecase.order import com.squirtles.domain.local.LocalRepository import com.squirtles.domain.model.Order -import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseTemplate +import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseInterface import javax.inject.Inject class SaveFavoriteListOrderUseCase @Inject constructor( - localRepository: LocalRepository -) : SavePickListOrderUseCaseTemplate(localRepository) { + private val localRepository: LocalRepository +) : SavePickListOrderUseCaseInterface { override suspend operator fun invoke(order: Order) = localRepository.saveFavoriteListOrder(order) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt index 35d57022..0ca672d7 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/order/SaveMyPickListOrderUseCase.kt @@ -2,10 +2,11 @@ package com.squirtles.domain.usecase.order import com.squirtles.domain.local.LocalRepository import com.squirtles.domain.model.Order -import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseTemplate +import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseInterface import javax.inject.Inject -class SaveMyPickListOrderUseCase @Inject constructor(localRepository: LocalRepository) : - SavePickListOrderUseCaseTemplate(localRepository) { +class SaveMyPickListOrderUseCase @Inject constructor( + private val localRepository: LocalRepository +) : SavePickListOrderUseCaseInterface { override suspend operator fun invoke(order: Order) = localRepository.saveMyListOrder(order) } diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseInterface.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseInterface.kt new file mode 100644 index 00000000..3a7a58ed --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseInterface.kt @@ -0,0 +1,5 @@ +package com.squirtles.domain.usecase.picklist + +interface DeletePickListUseCaseInterface { + suspend operator fun invoke(pickId: String, userId: String): Result +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseTemplate.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseTemplate.kt deleted file mode 100644 index f8461753..00000000 --- a/domain/src/main/java/com/squirtles/domain/usecase/picklist/DeletePickListUseCaseTemplate.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.squirtles.domain.usecase.picklist - -import com.squirtles.domain.firebase.FirebaseRepository - -abstract class DeletePickListUseCaseTemplate( - val firebaseRepository: FirebaseRepository -) { - abstract suspend operator fun invoke(pickId: String, userId: String): Result -} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseInterface.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseInterface.kt new file mode 100644 index 00000000..5b61faf7 --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseInterface.kt @@ -0,0 +1,7 @@ +package com.squirtles.domain.usecase.picklist + +import com.squirtles.domain.model.Pick + +interface FetchPickListUseCaseInterface { + suspend operator fun invoke(userId: String): Result> +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseTemplate.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseTemplate.kt deleted file mode 100644 index 665abed3..00000000 --- a/domain/src/main/java/com/squirtles/domain/usecase/picklist/FetchPickListUseCaseTemplate.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.squirtles.domain.usecase.picklist - -import com.squirtles.domain.firebase.FirebaseRepository -import com.squirtles.domain.model.Pick - -abstract class FetchPickListUseCaseTemplate( - val firebaseRepository: FirebaseRepository -) { - abstract suspend operator fun invoke(userId: String): Result> -} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseInterface.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseInterface.kt new file mode 100644 index 00000000..ad98b854 --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseInterface.kt @@ -0,0 +1,7 @@ +package com.squirtles.domain.usecase.picklist + +import com.squirtles.domain.model.Order + +interface GetPickListOrderUseCaseInterface { + suspend operator fun invoke(): Order +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseTemplate.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseTemplate.kt deleted file mode 100644 index 3338258f..00000000 --- a/domain/src/main/java/com/squirtles/domain/usecase/picklist/GetPickListOrderUseCaseTemplate.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.squirtles.domain.usecase.picklist - -import com.squirtles.domain.local.LocalRepository -import com.squirtles.domain.model.Order - -abstract class GetPickListOrderUseCaseTemplate( - val localRepository: LocalRepository -) { - abstract suspend operator fun invoke(): Order -} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseInterface.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseInterface.kt new file mode 100644 index 00000000..eb04b50e --- /dev/null +++ b/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseInterface.kt @@ -0,0 +1,7 @@ +package com.squirtles.domain.usecase.picklist + +import com.squirtles.domain.model.Order + +interface SavePickListOrderUseCaseInterface { + suspend operator fun invoke(order: Order) +} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseTemplate.kt b/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseTemplate.kt deleted file mode 100644 index aaf45784..00000000 --- a/domain/src/main/java/com/squirtles/domain/usecase/picklist/SavePickListOrderUseCaseTemplate.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.squirtles.domain.usecase.picklist - -import com.squirtles.domain.local.LocalRepository -import com.squirtles.domain.model.Order - -abstract class SavePickListOrderUseCaseTemplate( - val localRepository: LocalRepository -) { - abstract suspend operator fun invoke(order: Order) -} From ea1c995067fdb660ad2747c3343e57a6007eaaf3 Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 9 Feb 2025 23:17:18 +0900 Subject: [PATCH 43/46] =?UTF-8?q?[refactor]=20merge=20=ED=9B=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../musicroad/common/MessageAlertDialog.kt | 17 ++++--- .../common/picklist/PickListViewModel.kt | 6 ++- .../musicroad/create/CreatePickViewModel.kt | 47 +++++++++---------- .../favorite/FavoriteListViewModel.kt | 7 ++- .../musicroad/favorite/FavoriteScreen.kt | 7 ++- .../squirtles/musicroad/main/LoadingState.kt | 2 +- .../squirtles/musicroad/main/MainViewModel.kt | 33 ++++--------- .../musicroad/mypick/MyPickListViewModel.kt | 5 +- .../musicroad/mypick/MyPickScreen.kt | 5 +- app/src/main/res/values/strings.xml | 7 +++ .../datasource/local/LocalDataSourceImpl.kt | 2 +- .../data/repository/LocalRepositoryImpl.kt | 5 +- .../squirtles/domain/local/LocalDataSource.kt | 2 +- .../squirtles/domain/local/LocalRepository.kt | 5 +- .../domain/usecase/user/ClearUserUseCase.kt | 2 +- .../usecase/user/CreateGoogleIdUserUseCase.kt | 6 +-- .../usecase/user/CreateNewUserUseCase.kt | 21 --------- .../domain/usecase/user/FetchUserUseCase.kt | 4 +- .../user/GetUserIdFromDataStoreUseCase.kt | 13 +---- 19 files changed, 83 insertions(+), 113 deletions(-) delete mode 100644 domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt diff --git a/app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt b/app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt index f902e027..b49c6a3c 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/MessageAlertDialog.kt @@ -31,9 +31,10 @@ import com.squirtles.musicroad.ui.theme.White @OptIn(ExperimentalMaterial3Api::class) @Composable internal fun MessageAlertDialog( - onDismissRequest: () -> Unit, title: String, body: String, + onDismissRequest: () -> Unit, + showBody: Boolean = true, buttons: @Composable RowScope.() -> Unit, ) { BasicAlertDialog( @@ -55,13 +56,15 @@ internal fun MessageAlertDialog( style = MaterialTheme.typography.bodyLarge ) - VerticalSpacer(8) + if (showBody) { + VerticalSpacer(8) - Text( - text = body, - color = Black, - style = MaterialTheme.typography.bodyLarge - ) + Text( + text = body, + color = Black, + style = MaterialTheme.typography.bodyLarge + ) + } VerticalSpacer(24) diff --git a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt index f2a552e1..76efe0d2 100644 --- a/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/common/picklist/PickListViewModel.kt @@ -9,6 +9,7 @@ import com.squirtles.domain.usecase.picklist.DeletePickListUseCaseInterface import com.squirtles.domain.usecase.picklist.FetchPickListUseCaseInterface import com.squirtles.domain.usecase.picklist.GetPickListOrderUseCaseInterface import com.squirtles.domain.usecase.picklist.SavePickListOrderUseCaseInterface +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.flow.MutableStateFlow @@ -19,7 +20,8 @@ abstract class PickListViewModel( val fetchPickListUseCase: FetchPickListUseCaseInterface, val getPickListOrderUseCase: GetPickListOrderUseCaseInterface, val savePickListOrderUseCase: SavePickListOrderUseCaseInterface, - val removePickUseCase: DeletePickListUseCaseInterface + val removePickUseCase: DeletePickListUseCaseInterface, + val getCurrentUserUseCase: GetCurrentUserUseCase ) : ViewModel() { private var pickList: List = emptyList() @@ -98,4 +100,6 @@ abstract class PickListViewModel( Order.FAVORITE_DESC -> this.sortedByDescending { it.favoriteCount } } } + + fun getUserId() = getCurrentUserUseCase()?.userId } diff --git a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt index eacfd3d0..1e985d17 100644 --- a/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/create/CreatePickViewModel.kt @@ -71,10 +71,6 @@ class CreatePickViewModel @Inject constructor( _comment.value = "" } - fun onSearchTextChange(text: String) { - _searchText.value = text - } - fun onCreatePickClick() { viewModelScope.launch { createPickClick.emit(Unit) @@ -91,29 +87,30 @@ class CreatePickViewModel @Inject constructor( val musicVideo = fetchMusicVideoUseCase(song) /* 등록 결과 - pick ID 담긴 Result */ - val user = getCurrentUserUseCase() - val createResult = createPickUseCase( - Pick( - id = "", - song = song, - comment = _comment.value, - createdAt = "", - createdBy = Creator( - userId = user.userId, - userName = user.userName - ), - location = LocationPoint(lastLocation!!.latitude, lastLocation!!.longitude), - musicVideoUrl = musicVideo?.previewUrl ?: "", - musicVideoThumbnailUrl = musicVideo?.thumbnailUrl ?: "" + getCurrentUserUseCase()?.let { user -> + val createResult = createPickUseCase( + Pick( + id = "", + song = song, + comment = _comment.value, + createdAt = "", + createdBy = Creator( + userId = user.userId, + userName = user.userName + ), + location = LocationPoint(lastLocation!!.latitude, lastLocation!!.longitude), + musicVideoUrl = musicVideo?.previewUrl ?: "", + musicVideoThumbnailUrl = musicVideo?.thumbnailUrl ?: "" + ) ) - ) - createResult.onSuccess { pickId -> - _createPickUiState.emit(CreateUiState.Success(pickId)) - }.onFailure { - /* TODO: Firestore 등록 실패처리 */ - _createPickUiState.emit(CreateUiState.Error) - Log.d("CreatePickViewModel", createResult.exceptionOrNull()?.message.toString()) + createResult.onSuccess { pickId -> + _createPickUiState.emit(CreateUiState.Success(pickId)) + }.onFailure { + /* TODO: Firestore 등록 실패처리 */ + _createPickUiState.emit(CreateUiState.Error) + Log.d("CreatePickViewModel", createResult.exceptionOrNull()?.message.toString()) + } } } } diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt index 7047c957..5a29bc8c 100644 --- a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteListViewModel.kt @@ -4,6 +4,7 @@ import com.squirtles.domain.usecase.favorite.DeleteFavoriteUseCase import com.squirtles.domain.usecase.favorite.FetchFavoritePicksUseCase import com.squirtles.domain.usecase.order.GetFavoriteListOrderUseCase import com.squirtles.domain.usecase.order.SaveFavoriteListOrderUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.musicroad.common.picklist.PickListViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -13,10 +14,12 @@ class FavoriteListViewModel @Inject constructor( fetchFavoritePicksUseCase: FetchFavoritePicksUseCase, getFavoriteListOrderUseCase: GetFavoriteListOrderUseCase, saveFavoriteListOrderUseCase: SaveFavoriteListOrderUseCase, - deleteFavoriteUseCase: DeleteFavoriteUseCase + deleteFavoriteUseCase: DeleteFavoriteUseCase, + getCurrentUserUseCase: GetCurrentUserUseCase ) : PickListViewModel( fetchPickListUseCase = fetchFavoritePicksUseCase, getPickListOrderUseCase = getFavoriteListOrderUseCase, savePickListOrderUseCase = saveFavoriteListOrderUseCase, - removePickUseCase = deleteFavoriteUseCase + removePickUseCase = deleteFavoriteUseCase, + getCurrentUserUseCase = getCurrentUserUseCase ) diff --git a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt index 373fc87d..d3668042 100644 --- a/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/favorite/FavoriteScreen.kt @@ -8,8 +8,8 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.squirtles.musicroad.common.picklist.PickListScreenContents import com.squirtles.musicroad.common.picklist.PickListType +import com.squirtles.musicroad.picklist.PickListScreenContents @Composable fun FavoriteScreen( @@ -39,6 +39,9 @@ fun FavoriteScreen( selectAllPicks = favoriteListViewModel::selectAllPicks, deselectAllPicks = favoriteListViewModel::deselectAllPicks, toggleSelectedPick = favoriteListViewModel::toggleSelectedPick, - deleteSelectedPicks = favoriteListViewModel::deleteSelectedPicks + deleteSelectedPicks = favoriteListViewModel::deleteSelectedPicks, + getUserId = { + favoriteListViewModel.getUserId().toString() + } ) } diff --git a/app/src/main/java/com/squirtles/musicroad/main/LoadingState.kt b/app/src/main/java/com/squirtles/musicroad/main/LoadingState.kt index 38beedea..11e27911 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/LoadingState.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/LoadingState.kt @@ -2,7 +2,7 @@ package com.squirtles.musicroad.main sealed class LoadingState { data object Loading : LoadingState() - data class Success(val userId: String) : LoadingState() + data class Success(val userId: String?) : LoadingState() data class NetworkError(val error: String) : LoadingState() data class CreatedUserError(val error: String) : LoadingState() data class UserNotFoundError(val error: String) : LoadingState() diff --git a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt index b38bd440..ad8de40b 100644 --- a/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/main/MainViewModel.kt @@ -3,7 +3,6 @@ package com.squirtles.musicroad.main import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.squirtles.domain.firebase.FirebaseException -import com.squirtles.domain.usecase.user.CreateNewUserUseCase import com.squirtles.domain.usecase.user.FetchUserUseCase import com.squirtles.domain.usecase.user.GetUserIdFromDataStoreUseCase import dagger.hilt.android.lifecycle.HiltViewModel @@ -16,7 +15,6 @@ import javax.inject.Inject class MainViewModel @Inject constructor( getUserIdFromDataStoreUseCase: GetUserIdFromDataStoreUseCase, private val fetchUserUseCase: FetchUserUseCase, - private val createNewUserUseCase: CreateNewUserUseCase ) : ViewModel() { private val _loadingState = MutableStateFlow(LoadingState.Loading) @@ -25,13 +23,16 @@ class MainViewModel @Inject constructor( private var _canRequestPermission = true val canRequestPermission get() = _canRequestPermission + private val _localUserId = getUserIdFromDataStoreUseCase() + init { viewModelScope.launch { - val userId = getUserIdFromDataStoreUseCase() - if (userId == null) { - _loadingState.emit(LoadingState.Success(null)) - } else { - fetchUser(userId) + _localUserId.collect { localUid -> + if (localUid == null) { // 비회원 상태 + _loadingState.emit(LoadingState.Success(null)) + } else { + fetchUser(localUid) + } } } } @@ -40,24 +41,6 @@ class MainViewModel @Inject constructor( _canRequestPermission = canRequest } - private suspend fun createUser() { - createNewUserUseCase() - .onSuccess { - _loadingState.emit(LoadingState.Success(it.userId)) - } - .onFailure { exception -> - when (exception) { - is FirebaseException.CreatedUserFailedException -> { - _loadingState.emit(LoadingState.CreatedUserError(exception.message)) - } - - else -> { - _loadingState.emit(LoadingState.NetworkError(exception.message.toString())) - } - } - } - } - private suspend fun fetchUser(userId: String) { fetchUserUseCase(userId) .onSuccess { diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt index dfc83ca4..ee627663 100644 --- a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickListViewModel.kt @@ -4,6 +4,7 @@ import com.squirtles.domain.usecase.mypick.DeletePickUseCase import com.squirtles.domain.usecase.mypick.FetchMyPicksUseCase import com.squirtles.domain.usecase.order.GetMyPickListOrderUseCase import com.squirtles.domain.usecase.order.SaveMyPickListOrderUseCase +import com.squirtles.domain.usecase.user.GetCurrentUserUseCase import com.squirtles.musicroad.common.picklist.PickListViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -14,9 +15,11 @@ class MyPickListViewModel @Inject constructor( getMyPickListOrderUseCase: GetMyPickListOrderUseCase, saveMyPickListOrderUseCase: SaveMyPickListOrderUseCase, deletePickUseCase: DeletePickUseCase, + getCurrentUserUseCase: GetCurrentUserUseCase ) : PickListViewModel( fetchPickListUseCase = fetchMyPicksUseCase, getPickListOrderUseCase = getMyPickListOrderUseCase, savePickListOrderUseCase = saveMyPickListOrderUseCase, - removePickUseCase = deletePickUseCase + removePickUseCase = deletePickUseCase, + getCurrentUserUseCase = getCurrentUserUseCase ) diff --git a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt index 9d696091..bfd69357 100644 --- a/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/mypick/MyPickScreen.kt @@ -8,8 +8,8 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.squirtles.musicroad.common.picklist.PickListScreenContents import com.squirtles.musicroad.common.picklist.PickListType +import com.squirtles.musicroad.picklist.PickListScreenContents @Composable fun MyPickScreen( @@ -39,6 +39,7 @@ fun MyPickScreen( selectAllPicks = myPickListViewModel::selectAllPicks, deselectAllPicks = myPickListViewModel::deselectAllPicks, toggleSelectedPick = myPickListViewModel::toggleSelectedPick, - deleteSelectedPicks = myPickListViewModel::deleteSelectedPicks + deleteSelectedPicks = myPickListViewModel::deleteSelectedPicks, + getUserId = { myPickListViewModel.getUserId().toString() }, ) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 56d42289..8ad85596 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -136,6 +136,13 @@ 담은 픽을 확인하기 위해\n로그인이 필요합니다 픽을 등록하기 위해\n로그인이 필요합니다 픽을 담기 위해\n로그인이 필요합니다 + 픽을 담기 위해\n로그인이 필요합니다 + 로그인이 필요합니다 취소 기기에 로그인된 구글 계정이 없습니다 + + + 로그아웃 하시겠습니까? + 취소 + 로그아웃 diff --git a/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt b/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt index fb81fb71..9c421ec1 100644 --- a/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt +++ b/data/src/main/java/com/squirtles/data/datasource/local/LocalDataSourceImpl.kt @@ -40,7 +40,7 @@ class LocalDataSourceImpl @Inject constructor( } } - override suspend fun writeUserIdDataStore(userId: String) { + override suspend fun saveUserIdDataStore(userId: String) { val dataStoreKey = stringPreferencesKey(USER_ID_KEY) context.dataStore.edit { preferences -> preferences[dataStoreKey] = userId diff --git a/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt b/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt index 96a0cb49..c698674f 100644 --- a/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt +++ b/data/src/main/java/com/squirtles/data/repository/LocalRepositoryImpl.kt @@ -15,14 +15,13 @@ class LocalRepositoryImpl @Inject constructor( override val lastLocation get() = localDataSource.lastLocation override val favoriteListOrder get() = localDataSource.favoriteListOrder override val myListOrder get() = localDataSource.myListOrder - override var userIdFromDataStore: String? = null override fun readUserIdDataStore(): Flow { return localDataSource.readUserIdDataStore() } - override suspend fun writeUserIdDataStore(userId: String) { - localDataSource.writeUserIdDataStore(userId) + override suspend fun saveUserIdDataStore(userId: String) { + localDataSource.saveUserIdDataStore(userId) } override suspend fun saveCurrentUser(user: User) { diff --git a/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt b/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt index 56134724..9999d3b3 100644 --- a/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt +++ b/domain/src/main/java/com/squirtles/domain/local/LocalDataSource.kt @@ -13,7 +13,7 @@ interface LocalDataSource { val myListOrder: Order fun readUserIdDataStore(): Flow - suspend fun writeUserIdDataStore(userId: String) + suspend fun saveUserIdDataStore(userId: String) suspend fun saveCurrentUser(user: User) suspend fun clearUser() suspend fun saveCurrentLocation(location: Location) diff --git a/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt b/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt index f41d6de2..fe3402ad 100644 --- a/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt +++ b/domain/src/main/java/com/squirtles/domain/local/LocalRepository.kt @@ -1,4 +1,4 @@ -package com.squirtles.domain.repository +package com.squirtles.domain.local import android.location.Location import com.squirtles.domain.model.Order @@ -7,14 +7,13 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow interface LocalRepository { - val userId: Flow // 기기에 저장된 userId val currentUser: User? val lastLocation: StateFlow val favoriteListOrder: Order // 픽 보관함 정렬 순서 val myListOrder: Order // 등록한 픽 정렬 순서 fun readUserIdDataStore(): Flow - suspend fun writeUserIdDataStore(userId: String) + suspend fun saveUserIdDataStore(userId: String) suspend fun saveCurrentUser(user: User) suspend fun clearUser(): Result suspend fun saveCurrentLocation(location: Location) diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/ClearUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/ClearUserUseCase.kt index 7f26781a..7f89fe9f 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/ClearUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/ClearUserUseCase.kt @@ -1,6 +1,6 @@ package com.squirtles.domain.usecase.user -import com.squirtles.domain.repository.LocalRepository +import com.squirtles.domain.local.LocalRepository import javax.inject.Inject class ClearUserUseCase @Inject constructor( diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/CreateGoogleIdUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/CreateGoogleIdUserUseCase.kt index f16f6e63..f0f1a9d0 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/CreateGoogleIdUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/CreateGoogleIdUserUseCase.kt @@ -1,8 +1,8 @@ package com.squirtles.domain.usecase.user +import com.squirtles.domain.firebase.FirebaseRepository +import com.squirtles.domain.local.LocalRepository import com.squirtles.domain.model.User -import com.squirtles.domain.repository.FirebaseRepository -import com.squirtles.domain.repository.LocalRepository import javax.inject.Inject class CreateGoogleIdUserUseCase @Inject constructor( @@ -17,7 +17,7 @@ class CreateGoogleIdUserUseCase @Inject constructor( val createdUser = firebaseRepository.createGoogleIdUser(userId, userName, userProfileImage) .onSuccess { user -> // 생성된 유저의 userId 저장 후 user 반환 - localRepository.saveUserId(user.userId) + localRepository.saveUserIdDataStore(user.userId) localRepository.saveCurrentUser(user) } return createdUser diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt deleted file mode 100644 index 65730f1b..00000000 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/CreateNewUserUseCase.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.squirtles.domain.usecase.user - -import com.squirtles.domain.model.User -import com.squirtles.domain.firebase.FirebaseRepository -import com.squirtles.domain.local.LocalRepository -import javax.inject.Inject - -class CreateNewUserUseCase @Inject constructor( - private val localRepository: LocalRepository, - private val firebaseRepository: FirebaseRepository -) { - - suspend operator fun invoke(): Result { - val createdUser = firebaseRepository.createUser() // Firebase에 유저 생성 - .onSuccess { user -> - localRepository.writeUserIdDataStore(user.userId) // 생성된 유저의 userId를 DataStore에 저장 후 user 반환 - localRepository.saveCurrentUser(user) // 생성된 유저를 LocalDataSource currentUser 에 저장 - } - return createdUser - } -} diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt index 271eacf1..c6e755d5 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/FetchUserUseCase.kt @@ -1,7 +1,7 @@ package com.squirtles.domain.usecase.user +import com.squirtles.domain.local.LocalRepository import com.squirtles.domain.model.User -import com.squirtles.domain.repository.LocalRepository import javax.inject.Inject class FetchUserUseCase @Inject constructor( @@ -11,7 +11,7 @@ class FetchUserUseCase @Inject constructor( suspend operator fun invoke(userId: String): Result { val user = fetchUserByIdUseCase(userId) // userId가 있으면 Firestore에서 유저 가져오기 .onSuccess { user -> - localRepository.saveUserId(user.userId) + localRepository.saveUserIdDataStore(user.userId) localRepository.saveCurrentUser(user) // Firestore에서 가져온 user를 LocalDataSource에 저장 } return user diff --git a/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt index e1dc8407..0cfe6fec 100644 --- a/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt +++ b/domain/src/main/java/com/squirtles/domain/usecase/user/GetUserIdFromDataStoreUseCase.kt @@ -1,21 +1,10 @@ package com.squirtles.domain.usecase.user -import android.util.Log import com.squirtles.domain.local.LocalRepository -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.first import javax.inject.Inject class GetUserIdFromDataStoreUseCase @Inject constructor( private val localRepository: LocalRepository ) { - suspend operator fun invoke() : String? { - return try { - val userId = localRepository.readUserIdDataStore().first() - if (userId.isNullOrBlank()) null else userId - } catch (e: Exception) { - Log.e("GetUserIdUseCase", "Error reading DataStore", e) - null - } - } + operator fun invoke() = localRepository.readUserIdDataStore() } From 6ba4090a5422349f722007ae171ff62f6334a08d Mon Sep 17 00:00:00 2001 From: miller198 Date: Sun, 9 Feb 2025 23:17:32 +0900 Subject: [PATCH 44/46] =?UTF-8?q?[refactor]=20=EC=9C=A0=EC=A0=80=EC=A0=95?= =?UTF-8?q?=EB=B3=B4,=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20=EB=8B=A4?= =?UTF-8?q?=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/squirtles/musicroad/map/MapScreen.kt | 13 ++++-- .../userinfo/screen/UserInfoScreen.kt | 42 +++++++++++++++++-- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt index c48d52bd..d4c322f8 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt @@ -44,7 +44,7 @@ fun MapScreen( playerServiceViewModel: PlayerServiceViewModel, onFavoriteClick: (String) -> Unit, onCenterClick: () -> Unit, - onUserInfoClick: (String?) -> Unit, + onUserInfoClick: (String) -> Unit, onPickSummaryClick: (String) -> Unit, accountViewModel: AccountViewModel = hiltViewModel() ) { @@ -141,7 +141,7 @@ fun MapScreen( mapViewModel.getUserId()?.let { userId -> onFavoriteClick(userId) } ?: run { - signInDialogDescription = getString(context, R.string.sign_in_dialog_title_favorite_picks) + signInDialogDescription = getString(context, R.string.sign_in_dialog) showSignInDialog = true } }, @@ -150,12 +150,17 @@ fun MapScreen( onCenterClick() mapViewModel.saveCurLocationForced() } ?: run { - signInDialogDescription = getString(context, R.string.sign_in_dialog_title_add_pick) + signInDialogDescription = getString(context, R.string.sign_in_dialog) showSignInDialog = true } }, onUserInfoClick = { - onUserInfoClick(mapViewModel.getUserId()) + mapViewModel.getUserId()?.let { + onUserInfoClick(it) + } ?: run { + signInDialogDescription = getString(context, R.string.sign_in_dialog) + showSignInDialog = true + } } ) } diff --git a/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt index 28f245ab..964ce0cf 100644 --- a/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt @@ -26,20 +26,22 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LocalLifecycleOwner -import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.flowWithLifecycle import coil3.compose.AsyncImage @@ -50,8 +52,10 @@ import com.squirtles.musicroad.account.AccountViewModel import com.squirtles.musicroad.account.GoogleId import com.squirtles.musicroad.common.Constants.COLOR_STOPS import com.squirtles.musicroad.common.DefaultTopAppBar +import com.squirtles.musicroad.common.DialogTextButton import com.squirtles.musicroad.common.GoogleSignInButton import com.squirtles.musicroad.common.HorizontalSpacer +import com.squirtles.musicroad.common.MessageAlertDialog import com.squirtles.musicroad.common.VerticalSpacer import com.squirtles.musicroad.ui.theme.Primary import com.squirtles.musicroad.ui.theme.White @@ -76,6 +80,8 @@ fun UserInfoScreen( val scrollState = rememberScrollState() val user by userInfoViewModel.profileUser.collectAsStateWithLifecycle() + var showLogOutDialog by remember { mutableStateOf(false) } + val onSignOutClick: () -> Unit = { GoogleId(context).signOut() accountViewModel.signOut() @@ -188,7 +194,7 @@ fun UserInfoScreen( imageVector = Icons.AutoMirrored.Outlined.Logout, contentDescription = stringResource(R.string.user_info_setting_sign_out_menu_icon_description), menuTitle = stringResource(R.string.user_info_setting_sign_out_menu_title), - onMenuClick = onSignOutClick + onMenuClick = { showLogOutDialog = true } ) ) ) @@ -220,6 +226,36 @@ fun UserInfoScreen( style = MaterialTheme.typography.bodyLarge ) } + + if (showLogOutDialog) { + MessageAlertDialog( + onDismissRequest = { + showLogOutDialog = false + }, + title = stringResource(R.string.sign_out_dialog_title), + body = "", + showBody = false + ) { + DialogTextButton( + onClick = { + showLogOutDialog = false + }, + text = stringResource(R.string.sign_out_dialog_dismiss) + ) + + HorizontalSpacer(8) + + DialogTextButton( + onClick = { + showLogOutDialog = false + onSignOutClick() + }, + text = stringResource(R.string.sign_out_dialog_confirm), + textColor = Primary, + fontWeight = FontWeight.Bold + ) + } + } } } } From b5ae9b8929de1c96c98f858e31b445383ab5105e Mon Sep 17 00:00:00 2001 From: miller198 Date: Tue, 11 Feb 2025 18:36:58 +0900 Subject: [PATCH 45/46] =?UTF-8?q?[refactor]=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt index d4c322f8..919a2313 100644 --- a/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/map/MapScreen.kt @@ -141,7 +141,7 @@ fun MapScreen( mapViewModel.getUserId()?.let { userId -> onFavoriteClick(userId) } ?: run { - signInDialogDescription = getString(context, R.string.sign_in_dialog) + signInDialogDescription = getString(context, R.string.sign_in_dialog_title_favorite_picks) showSignInDialog = true } }, @@ -150,7 +150,7 @@ fun MapScreen( onCenterClick() mapViewModel.saveCurLocationForced() } ?: run { - signInDialogDescription = getString(context, R.string.sign_in_dialog) + signInDialogDescription = getString(context, R.string.sign_in_dialog_title_add_pick) showSignInDialog = true } }, From 022d1d47904b42c01c827be07aba8f825d83cf5b Mon Sep 17 00:00:00 2001 From: miller198 Date: Tue, 11 Feb 2025 18:39:35 +0900 Subject: [PATCH 46/46] =?UTF-8?q?[refactor]=20=EC=9C=A0=EC=A0=80=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=ED=99=94=EB=A9=B4=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userinfo/screen/UserInfoScreen.kt | 223 ++++++++---------- 1 file changed, 102 insertions(+), 121 deletions(-) diff --git a/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt index 964ce0cf..a4edbce2 100644 --- a/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt +++ b/app/src/main/java/com/squirtles/musicroad/userinfo/screen/UserInfoScreen.kt @@ -4,7 +4,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentWidth @@ -53,7 +52,6 @@ import com.squirtles.musicroad.account.GoogleId import com.squirtles.musicroad.common.Constants.COLOR_STOPS import com.squirtles.musicroad.common.DefaultTopAppBar import com.squirtles.musicroad.common.DialogTextButton -import com.squirtles.musicroad.common.GoogleSignInButton import com.squirtles.musicroad.common.HorizontalSpacer import com.squirtles.musicroad.common.MessageAlertDialog import com.squirtles.musicroad.common.VerticalSpacer @@ -65,7 +63,7 @@ import com.squirtles.musicroad.userinfo.components.UserInfoMenus @Composable fun UserInfoScreen( - userId: String?, + userId: String, onBackClick: () -> Unit, onBackToMapClick: () -> Unit, onFavoritePicksClick: (String) -> Unit, @@ -115,146 +113,129 @@ fun UserInfoScreen( .background(Brush.verticalGradient(colorStops = COLOR_STOPS)) .padding(innerPadding), ) { - if (userId == null) { - GoogleSignInButton( - onClick = { - GoogleId(context).signIn( - onSuccess = { credential -> - accountViewModel.signIn(credential) - onBackToMapClick() - } - ) - }, + Column( + modifier = Modifier + .fillMaxSize() + .verticalScroll(scrollState) + .padding(bottom = 96.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + VerticalSpacer(16) + + AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data(user.userProfileImage) + .crossfade(true) + .build(), + contentDescription = stringResource(R.string.user_info_profile_image), modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp) - .align(Alignment.TopCenter) + .size(180.dp) + .clip(CircleShape), + placeholder = painterResource(R.drawable.img_user_default_profile), + error = painterResource(R.drawable.img_user_default_profile), + contentScale = ContentScale.Crop, ) - } else { - Column( - modifier = Modifier - .fillMaxSize() - .verticalScroll(scrollState) - .padding(bottom = 96.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - VerticalSpacer(16) - AsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(user.userProfileImage) - .crossfade(true) - .build(), - contentDescription = stringResource(R.string.user_info_profile_image), - modifier = Modifier - .size(180.dp) - .clip(CircleShape), - placeholder = painterResource(R.drawable.img_user_default_profile), - error = painterResource(R.drawable.img_user_default_profile), - contentScale = ContentScale.Crop, + VerticalSpacer(40) + + UserInfoMenus( + title = stringResource(R.string.user_info_pick_category_title), + menus = listOf( + MenuItem( + imageVector = Icons.Outlined.Archive, + contentDescription = stringResource(R.string.user_info_favorite_menu_icon_description), + menuTitle = stringResource(R.string.user_info_favorite_menu_title), + onMenuClick = { onFavoritePicksClick(userId) } + ), + MenuItem( + imageVector = Icons.Default.MusicNote, + contentDescription = stringResource(R.string.user_info_created_by_self_menu_icon_description), + menuTitle = stringResource(R.string.user_info_created_by_self_menu_title), + onMenuClick = { onMyPicksClick(userId) } + ) ) + ) - VerticalSpacer(40) - + if (userId == userInfoViewModel.currentUser?.userId) { UserInfoMenus( - title = stringResource(R.string.user_info_pick_category_title), + title = stringResource(R.string.user_info_setting_category_title), menus = listOf( MenuItem( - imageVector = Icons.Outlined.Archive, - contentDescription = stringResource(R.string.user_info_favorite_menu_icon_description), - menuTitle = stringResource(R.string.user_info_favorite_menu_title), - onMenuClick = { onFavoritePicksClick(userId) } + imageVector = Icons.Outlined.SwitchAccount, + contentDescription = stringResource(R.string.user_info_setting_profile_menu_icon_description), + menuTitle = stringResource(R.string.user_info_setting_profile_menu_title), + onMenuClick = onEditProfileClick + ), + MenuItem( + imageVector = Icons.Outlined.Notifications, + contentDescription = stringResource(R.string.user_info_setting_notification_menu_icon_description), + menuTitle = stringResource(R.string.user_info_setting_notification_menu_title), + onMenuClick = onEditNotificationClick ), MenuItem( - imageVector = Icons.Default.MusicNote, - contentDescription = stringResource(R.string.user_info_created_by_self_menu_icon_description), - menuTitle = stringResource(R.string.user_info_created_by_self_menu_title), - onMenuClick = { onMyPicksClick(userId) } + imageVector = Icons.AutoMirrored.Outlined.Logout, + contentDescription = stringResource(R.string.user_info_setting_sign_out_menu_icon_description), + menuTitle = stringResource(R.string.user_info_setting_sign_out_menu_title), + onMenuClick = { showLogOutDialog = true } ) ) ) - - if (userId == userInfoViewModel.currentUser?.userId) { - UserInfoMenus( - title = stringResource(R.string.user_info_setting_category_title), - menus = listOf( - MenuItem( - imageVector = Icons.Outlined.SwitchAccount, - contentDescription = stringResource(R.string.user_info_setting_profile_menu_icon_description), - menuTitle = stringResource(R.string.user_info_setting_profile_menu_title), - onMenuClick = onEditProfileClick - ), - MenuItem( - imageVector = Icons.Outlined.Notifications, - contentDescription = stringResource(R.string.user_info_setting_notification_menu_icon_description), - menuTitle = stringResource(R.string.user_info_setting_notification_menu_title), - onMenuClick = onEditNotificationClick - ), - MenuItem( - imageVector = Icons.AutoMirrored.Outlined.Logout, - contentDescription = stringResource(R.string.user_info_setting_sign_out_menu_icon_description), - menuTitle = stringResource(R.string.user_info_setting_sign_out_menu_title), - onMenuClick = { showLogOutDialog = true } - ) - ) - ) - } } + } - ExtendedFloatingActionButton( - onClick = onBackToMapClick, - modifier = Modifier - .wrapContentWidth() - .padding(horizontal = 8.dp) - .padding(bottom = 48.dp) - .align(Alignment.BottomCenter), - shape = CircleShape, - containerColor = Primary, - contentColor = White, - ) { - Icon( - imageVector = Icons.Outlined.Map, - contentDescription = stringResource(R.string.user_info_icon_map_description), - tint = White - ) + ExtendedFloatingActionButton( + onClick = onBackToMapClick, + modifier = Modifier + .wrapContentWidth() + .padding(horizontal = 8.dp) + .padding(bottom = 48.dp) + .align(Alignment.BottomCenter), + shape = CircleShape, + containerColor = Primary, + contentColor = White, + ) { + Icon( + imageVector = Icons.Outlined.Map, + contentDescription = stringResource(R.string.user_info_icon_map_description), + tint = White + ) - HorizontalSpacer(8) + HorizontalSpacer(8) - Text( - text = stringResource(R.string.user_info_back_to_map_button_text), - color = White, - style = MaterialTheme.typography.bodyLarge - ) - } + Text( + text = stringResource(R.string.user_info_back_to_map_button_text), + color = White, + style = MaterialTheme.typography.bodyLarge + ) + } - if (showLogOutDialog) { - MessageAlertDialog( - onDismissRequest = { + if (showLogOutDialog) { + MessageAlertDialog( + onDismissRequest = { + showLogOutDialog = false + }, + title = stringResource(R.string.sign_out_dialog_title), + body = "", + showBody = false + ) { + DialogTextButton( + onClick = { showLogOutDialog = false }, - title = stringResource(R.string.sign_out_dialog_title), - body = "", - showBody = false - ) { - DialogTextButton( - onClick = { - showLogOutDialog = false - }, - text = stringResource(R.string.sign_out_dialog_dismiss) - ) + text = stringResource(R.string.sign_out_dialog_dismiss) + ) - HorizontalSpacer(8) + HorizontalSpacer(8) - DialogTextButton( - onClick = { - showLogOutDialog = false - onSignOutClick() - }, - text = stringResource(R.string.sign_out_dialog_confirm), - textColor = Primary, - fontWeight = FontWeight.Bold - ) - } + DialogTextButton( + onClick = { + showLogOutDialog = false + onSignOutClick() + }, + text = stringResource(R.string.sign_out_dialog_confirm), + textColor = Primary, + fontWeight = FontWeight.Bold + ) } } }