diff --git a/android/app/src/main/java/com/goliath/emojihub/RootActivity.kt b/android/app/src/main/java/com/goliath/emojihub/RootActivity.kt index 6f700095..a2df9fe6 100644 --- a/android/app/src/main/java/com/goliath/emojihub/RootActivity.kt +++ b/android/app/src/main/java/com/goliath/emojihub/RootActivity.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -110,12 +111,18 @@ class RootActivity : ComponentActivity() { } composable(NavigationDestination.TransformVideo) { - val emojiViewModel = hiltViewModel() + val parentEntry = remember(it) { + navController.getBackStackEntry(NavigationDestination.MainPage) + } + val emojiViewModel = hiltViewModel(parentEntry) TransformVideoPage(emojiViewModel) } composable(NavigationDestination.PlayEmojiVideo) { - val emojiViewModel = hiltViewModel() + val parentEntry = remember(it) { + navController.getBackStackEntry(NavigationDestination.MainPage) + } + val emojiViewModel = hiltViewModel(parentEntry) PlayEmojiView(emojiViewModel) } @@ -126,4 +133,12 @@ class RootActivity : ComponentActivity() { } } } +} + +fun NavController.navigateAsOrigin(route: String) { + navigate(route) { + while (popBackStack()) { } + launchSingleTop = true + restoreState = true + } } \ No newline at end of file diff --git a/android/app/src/main/java/com/goliath/emojihub/data_sources/BottomNavigationController.kt b/android/app/src/main/java/com/goliath/emojihub/data_sources/BottomNavigationController.kt index d8ea772f..77ec7b80 100644 --- a/android/app/src/main/java/com/goliath/emojihub/data_sources/BottomNavigationController.kt +++ b/android/app/src/main/java/com/goliath/emojihub/data_sources/BottomNavigationController.kt @@ -1,7 +1,7 @@ package com.goliath.emojihub.data_sources -import androidx.compose.runtime.MutableState import androidx.compose.runtime.Stable +import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import com.goliath.emojihub.views.PageItem @@ -9,7 +9,7 @@ class BottomNavigationController { private val _bottomNavigationDestination = mutableStateOf(PageItem.Feed.screenRoute) @Stable - val currentDestination: MutableState = _bottomNavigationDestination + val currentDestination: State = _bottomNavigationDestination fun updateDestination(destination: PageItem) { _bottomNavigationDestination.value = destination.screenRoute diff --git a/android/app/src/main/java/com/goliath/emojihub/viewmodels/EmojiViewModel.kt b/android/app/src/main/java/com/goliath/emojihub/viewmodels/EmojiViewModel.kt index 6ac0a5c8..4c2d4096 100644 --- a/android/app/src/main/java/com/goliath/emojihub/viewmodels/EmojiViewModel.kt +++ b/android/app/src/main/java/com/goliath/emojihub/viewmodels/EmojiViewModel.kt @@ -16,6 +16,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File @@ -26,7 +27,7 @@ class EmojiViewModel @Inject constructor( private val emojiUseCase: EmojiUseCase ): ViewModel() { lateinit var videoUri: Uri - var currentEmoji: Emoji? = null + lateinit var currentEmoji: Emoji var bottomSheetContent by mutableStateOf(BottomSheetContent.EMPTY) private val _saveEmojiState = MutableStateFlow?>(null) @@ -38,6 +39,7 @@ class EmojiViewModel @Inject constructor( val emojiList = emojiUseCase.emojiList val myCreatedEmojiList = emojiUseCase.myCreatedEmojiList val mySavedEmojiList = emojiUseCase.mySavedEmojiList + companion object { private const val _topK = 3 } @@ -93,8 +95,8 @@ class EmojiViewModel @Inject constructor( fun unSaveEmoji(id: String) { viewModelScope.launch { - val result = emojiUseCase.unSaveEmoji(id) - _unSaveEmojiState.value = result + val result = emojiUseCase.unSaveEmoji(id) + _unSaveEmojiState.value = result } } } \ No newline at end of file diff --git a/android/app/src/main/java/com/goliath/emojihub/views/EmojiPage.kt b/android/app/src/main/java/com/goliath/emojihub/views/EmojiPage.kt index 2b2ac6db..39b6184c 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/EmojiPage.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/EmojiPage.kt @@ -62,8 +62,7 @@ fun EmojiPage( val emojiList = viewModel.emojiList.collectAsLazyPagingItems() - LaunchedEffect(Unit) - { + LaunchedEffect(Unit) { viewModel.fetchEmojiList() } @@ -79,9 +78,7 @@ fun EmojiPage( )) } else -> { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - permissionLauncher.launch(Manifest.permission.READ_MEDIA_VIDEO) - } + permissionLauncher.launch(Manifest.permission.READ_MEDIA_VIDEO) } } }) { diff --git a/android/app/src/main/java/com/goliath/emojihub/views/LoginPage.kt b/android/app/src/main/java/com/goliath/emojihub/views/LoginPage.kt index ef675dec..05b1b3ab 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/LoginPage.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/LoginPage.kt @@ -37,6 +37,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import com.goliath.emojihub.LocalNavController import com.goliath.emojihub.NavigationDestination import com.goliath.emojihub.R +import com.goliath.emojihub.navigateAsOrigin import com.goliath.emojihub.ui.theme.Color import com.goliath.emojihub.viewmodels.UserViewModel import com.goliath.emojihub.views.components.UnderlinedTextField @@ -133,7 +134,7 @@ fun LoginPage() { color = Color.DarkGray, style = TextStyle(textDecoration = TextDecoration.Underline), modifier = Modifier.clickable { - navController.navigate(NavigationDestination.MainPage) + navController.navigateAsOrigin(NavigationDestination.MainPage) } ) Spacer(modifier = Modifier.height(24.dp)) diff --git a/android/app/src/main/java/com/goliath/emojihub/views/MainPage.kt b/android/app/src/main/java/com/goliath/emojihub/views/MainPage.kt index c6cdd681..875ea166 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/MainPage.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/MainPage.kt @@ -31,9 +31,7 @@ fun MainPage() { pageItemList.forEach { pageItem -> BottomNavigationItem( selected = currentRoute == pageItem.screenRoute, - onClick = { - bottomNavigationController.updateDestination(pageItem) - }, + onClick = { bottomNavigationController.updateDestination(pageItem) }, icon = { Icon( painter = painterResource(id = pageItem.icon), diff --git a/android/app/src/main/java/com/goliath/emojihub/views/ProfilePage.kt b/android/app/src/main/java/com/goliath/emojihub/views/ProfilePage.kt index 5e473e12..56a743a5 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/ProfilePage.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/ProfilePage.kt @@ -29,6 +29,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.paging.compose.collectAsLazyPagingItems import com.goliath.emojihub.LocalNavController import com.goliath.emojihub.NavigationDestination +import com.goliath.emojihub.navigateAsOrigin import com.goliath.emojihub.ui.theme.Color import com.goliath.emojihub.ui.theme.Color.EmojiHubDetailLabel import com.goliath.emojihub.ui.theme.Color.White @@ -173,7 +174,10 @@ fun ProfilePage() { needsCancelButton = true, onDismissRequest = { showLogoutDialog = false }, dismiss = { showLogoutDialog = false }, - confirm = { userViewModel.logout() } + confirm = { + navController.navigateAsOrigin(NavigationDestination.Onboard) + userViewModel.logout() + } ) } @@ -186,7 +190,10 @@ fun ProfilePage() { needsCancelButton = true, onDismissRequest = { showSignOutDialog = false }, dismiss = { showSignOutDialog = false }, - confirm = { userViewModel.signOut() } + confirm = { + navController.navigateAsOrigin(NavigationDestination.Onboard) + userViewModel.signOut() + } ) } } diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/CustomBottomSheet.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/CustomBottomSheet.kt index 4adb5b38..ffc63c81 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/components/CustomBottomSheet.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/CustomBottomSheet.kt @@ -1,6 +1,5 @@ package com.goliath.emojihub.views.components -import android.util.Log import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -58,7 +57,6 @@ fun CustomBottomSheet ( val bottomSheetState = LocalBottomSheetController.current val coroutineScope = rememberCoroutineScope() val viewModel = hiltViewModel() - val navController = LocalNavController.current var selectedEmojiClass by remember { mutableStateOf("전체") } val emojisByClass = emojiList.groupBy { it.unicode } @@ -174,10 +172,11 @@ fun CustomBottomSheet ( BottomSheetContent.EMPTY -> {} BottomSheetContent.VIEW_REACTION -> { - items(if (selectedEmojiClass == "전체") emojiList else emojiList.filter { it.unicode == selectedEmojiClass }, key = { it.id }) { emoji -> + items( + if (selectedEmojiClass == "전체") emojiList + else emojiList.filter { it.unicode == selectedEmojiClass }, key = { it.id }) { emoji -> EmojiCell(emoji = emoji, displayMode = EmojiCellDisplay.VERTICAL) {selectedEmoji -> - viewModel.currentEmoji = selectedEmoji - navController.navigate(NavigationDestination.PlayEmojiVideo) //FIXME: make a new destination or fix PlayEmojiVideo's back stack to include BottomSheet + emojiCellClicked(selectedEmoji) } } } diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/EmptyProfile.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/EmptyProfile.kt index 4e057e39..5465dabd 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/components/EmptyProfile.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/EmptyProfile.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.goliath.emojihub.LocalNavController import com.goliath.emojihub.NavigationDestination +import com.goliath.emojihub.navigateAsOrigin import com.goliath.emojihub.ui.theme.Color @Composable @@ -54,7 +55,7 @@ fun EmptyProfile() { } Spacer(modifier = Modifier.weight(1f)) Button( - onClick = { navController.navigate(NavigationDestination.Onboard) }, + onClick = { navController.navigateAsOrigin(NavigationDestination.Onboard) }, modifier = Modifier.fillMaxWidth().height(44.dp), shape = RoundedCornerShape(50), colors = ButtonDefaults.buttonColors( diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/PlayEmojiView.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/PlayEmojiView.kt index 5327e414..472113ff 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/components/PlayEmojiView.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/PlayEmojiView.kt @@ -1,6 +1,5 @@ package com.goliath.emojihub.views.components -import android.util.Log import android.widget.Toast import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box @@ -20,9 +19,9 @@ import androidx.compose.material.icons.filled.FileDownloadOff import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -36,24 +35,25 @@ import androidx.compose.ui.viewinterop.AndroidView import androidx.media3.common.MediaItem import androidx.media3.common.Player import androidx.media3.exoplayer.ExoPlayer +import androidx.media3.ui.AspectRatioFrameLayout +import androidx.media3.ui.AspectRatioFrameLayout.ResizeMode import androidx.media3.ui.PlayerView import com.goliath.emojihub.LocalNavController import com.goliath.emojihub.extensions.toEmoji import com.goliath.emojihub.ui.theme.Color import com.goliath.emojihub.viewmodels.EmojiViewModel -import kotlinx.coroutines.launch +@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) @Composable fun PlayEmojiView( viewModel: EmojiViewModel ) { - // Play video val context = LocalContext.current val navController = LocalNavController.current - val currentEmoji = viewModel.currentEmoji!! + val currentEmoji = viewModel.currentEmoji - var savedCount by remember { mutableStateOf(currentEmoji.savedCount) } + var savedCount by remember { mutableIntStateOf(currentEmoji.savedCount) } var isSaved by remember { mutableStateOf(currentEmoji.isSaved) } var showUnSaveDialog by remember { mutableStateOf(false) } @@ -72,9 +72,7 @@ fun PlayEmojiView( } } - Box( - Modifier - .fillMaxSize() + Box(Modifier.fillMaxSize() .background( brush = Brush.verticalGradient(listOf(Color.Transparent, Color.Black)), shape = RectangleShape, @@ -85,6 +83,7 @@ fun PlayEmojiView( modifier = Modifier.fillMaxSize(), factory = { PlayerView(it).apply { + this.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL player = exoPlayer } } @@ -93,6 +92,7 @@ fun PlayEmojiView( TopNavigationBar( title = "@" + currentEmoji.createdBy, largeTitle = false, + needsElevation = false, navigate = { navController.popBackStack() } ) {} @@ -149,7 +149,6 @@ fun PlayEmojiView( fontSize = 28.sp, ) } - Spacer(modifier = Modifier.padding(bottom = 32.dp)) } } diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/TopNavigationBar.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/TopNavigationBar.kt index 63353cef..1b1a490e 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/components/TopNavigationBar.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/TopNavigationBar.kt @@ -28,13 +28,14 @@ fun TopNavigationBar( title: String = "", largeTitle: Boolean = true, shouldNavigate: Boolean = true, + needsElevation: Boolean = true, navigate: () -> Unit = {}, actions: @Composable () -> Unit = {}, ) { Surface( color = Color.Transparent, shape = RectangleShape, - elevation = 1.dp, + elevation = if (needsElevation) 1.dp else 0.dp, modifier = Modifier.height(64.dp), ) { Box(Modifier.padding(horizontal = 4.dp)) {