diff --git a/android/app/src/main/java/com/goliath/emojihub/NavigationDestination.kt b/android/app/src/main/java/com/goliath/emojihub/NavigationDestination.kt index 37769969..06d9058d 100644 --- a/android/app/src/main/java/com/goliath/emojihub/NavigationDestination.kt +++ b/android/app/src/main/java/com/goliath/emojihub/NavigationDestination.kt @@ -4,4 +4,8 @@ object NavigationDestination { const val TransformVideo = "transform_video" const val CreatePost = "create_post" const val PlayEmojiVideo = "play_emoji_video" + + const val MyPostList = "my_post_list" + const val MyEmojiList = "my_emoji_list" + const val MySavedEmojiList = "my_saved_emoji_list" } \ No newline at end of file diff --git a/android/app/src/main/java/com/goliath/emojihub/ui/theme/Color.kt b/android/app/src/main/java/com/goliath/emojihub/ui/theme/Color.kt index edf3f52a..2effd128 100644 --- a/android/app/src/main/java/com/goliath/emojihub/ui/theme/Color.kt +++ b/android/app/src/main/java/com/goliath/emojihub/ui/theme/Color.kt @@ -24,4 +24,5 @@ object Color { val EmojiHubRed = Color(0xFFD66464) val EmojiHubDividerColor = Color(0x0D000000) val EmojiHubGrayIcon = Color(0xFFD3D3D3) + val EmojiHubBorderColor = Color(0xFFEAEAEA) } \ No newline at end of file diff --git a/android/app/src/main/java/com/goliath/emojihub/views/BottomNavigationBar.kt b/android/app/src/main/java/com/goliath/emojihub/views/BottomNavigationBar.kt index 9050397d..0ce77c45 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/BottomNavigationBar.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/BottomNavigationBar.kt @@ -8,11 +8,12 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import com.goliath.emojihub.NavigationDestination import com.goliath.emojihub.R -import com.goliath.emojihub.models.createDummyEmoji -import com.goliath.emojihub.models.dummyPost import com.goliath.emojihub.viewmodels.EmojiViewModel import com.goliath.emojihub.viewmodels.PostViewModel +import com.goliath.emojihub.views.components.CreatedEmojiListView +import com.goliath.emojihub.views.components.CreatedPostListView import com.goliath.emojihub.views.components.PlayEmojiView +import com.goliath.emojihub.views.components.SavedEmojiListView @Composable fun BottomNavigationBar( @@ -54,6 +55,18 @@ fun BottomNavigationBar( val postViewModel = hiltViewModel(parentEntry) CreatePostPage(postViewModel) } + + composable(NavigationDestination.MyPostList) { + CreatedPostListView() + } + + composable(NavigationDestination.MyEmojiList) { + CreatedEmojiListView() + } + + composable(NavigationDestination.MySavedEmojiList) { + SavedEmojiListView() + } } } diff --git a/android/app/src/main/java/com/goliath/emojihub/views/FeedPage.kt b/android/app/src/main/java/com/goliath/emojihub/views/FeedPage.kt index 711f8d38..7d4991c5 100644 --- a/android/app/src/main/java/com/goliath/emojihub/views/FeedPage.kt +++ b/android/app/src/main/java/com/goliath/emojihub/views/FeedPage.kt @@ -15,13 +15,13 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ButtonDefaults +import androidx.compose.material.Divider import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.OutlinedButton import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add -import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet import androidx.compose.runtime.Composable 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 4a53b11b..ccea324f 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 @@ -5,9 +5,14 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Divider import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -23,104 +28,157 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel +import com.goliath.emojihub.LocalNavController +import com.goliath.emojihub.NavigationDestination +import com.goliath.emojihub.models.createDummyEmoji +import com.goliath.emojihub.models.dummyEmoji +import com.goliath.emojihub.models.dummyPost import com.goliath.emojihub.ui.theme.Color import com.goliath.emojihub.ui.theme.Color.EmojiHubDetailLabel import com.goliath.emojihub.ui.theme.Color.White +import com.goliath.emojihub.viewmodels.PostViewModel import com.goliath.emojihub.viewmodels.UserViewModel import com.goliath.emojihub.views.components.CustomDialog +import com.goliath.emojihub.views.components.EmojiCell import com.goliath.emojihub.views.components.EmptyProfile +import com.goliath.emojihub.views.components.PreviewPostCell import com.goliath.emojihub.views.components.ProfileMenuCell +import com.goliath.emojihub.views.components.ProfileMenuCellWithPreview import com.goliath.emojihub.views.components.TopNavigationBar @Composable fun ProfilePage( ) { + val navController = LocalNavController.current + val scrollState = rememberScrollState() + val userViewModel = hiltViewModel() + val postViewModel = hiltViewModel() + val currentUser = userViewModel.userState.collectAsState().value var showLogoutDialog by remember { mutableStateOf(false) } var showSignOutDialog by remember { mutableStateOf(false) } - Column(Modifier.background(White)) { - TopNavigationBar("Profile", shouldNavigate = false) - - Box( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - ) { - if (!currentUser?.accessToken.isNullOrEmpty()) { - Column( - modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.Start - ) { - Spacer(modifier = Modifier.height(8.dp)) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 24.dp), - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.Top - ) { - Text( - text = "Username", - fontSize = 12.sp, - color = EmojiHubDetailLabel - ) - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = "@" + currentUser?.name, - fontSize = 24.sp, - fontWeight = FontWeight.Bold + LazyColumn( + Modifier.background(White) + ) { + item { + TopNavigationBar("Profile", shouldNavigate = false) + + Box( + modifier = Modifier.fillMaxSize() + ) { + if (currentUser?.accessToken.isNullOrEmpty()) { + EmptyProfile() + } else { + Column(Modifier.padding(horizontal = 16.dp)) { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.Top + ) { + Spacer(modifier = Modifier.height(32.dp)) + + Text( + text = "Username", + fontSize = 12.sp, + color = EmojiHubDetailLabel + ) + + Spacer(modifier = Modifier.height(12.dp)) + + Text( + text = "@" + currentUser?.name, + fontSize = 24.sp, + fontWeight = FontWeight.Bold + ) + + Spacer(modifier = Modifier.height(34.dp)) + } + + Divider(color = Color.EmojiHubDividerColor, thickness = 1.dp) + Spacer(modifier = Modifier.height(16.dp)) + + ProfileMenuCellWithPreview( + label = "내가 작성한 포스트", + detailLabel = "count", + navigateToDestination = { navController.navigate(NavigationDestination.MyPostList) } + ) { + // TODO: should show my posts + items(listOf(dummyPost, dummyPost, dummyPost)) { + PreviewPostCell(post = it) + } + } + + Spacer(modifier = Modifier.height(24.dp)) + Divider(color = Color.EmojiHubDividerColor, thickness = 1.dp) + Spacer(modifier = Modifier.height(16.dp)) + + ProfileMenuCellWithPreview( + label = "내가 만든 이모지", + detailLabel = "더보기", + navigateToDestination = { navController.navigate(NavigationDestination.MyEmojiList) }, + content = { + // should show my emojis + } ) - } - Spacer(modifier = Modifier.height(10.dp)) - Divider(color = Color.EmojiHubDividerColor, thickness = 1.dp) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(32.dp)) - ProfileMenuCell(label = "내가 작성한 포스트", needsTrailingButton = true) {} - ProfileMenuCell(label = "내가 만든 이모지", needsTrailingButton = true) {} - ProfileMenuCell(label = "저장된 이모지", needsTrailingButton = true) {} + ProfileMenuCellWithPreview( + label = "저장된 이모지", + detailLabel = "더보기", + navigateToDestination = { navController.navigate(NavigationDestination.MySavedEmojiList) } + ) { + // TODO: should show saved emoji list + items(listOf( + dummyEmoji, dummyEmoji, + dummyEmoji, dummyEmoji) + ) { + EmojiCell(emoji = it, onSelected = {}) + } + } - Spacer(modifier = Modifier.height(8.dp)) - Divider(color = Color.EmojiHubDividerColor, thickness = 1.dp) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(32.dp)) + Divider(color = Color.EmojiHubDividerColor, thickness = 1.dp) + Spacer(modifier = Modifier.height(8.dp)) - ProfileMenuCell(label = "로그아웃") { - showLogoutDialog = true - } - ProfileMenuCell(label = "회원 탈퇴", isDestructive = true) { - showSignOutDialog = true + ProfileMenuCell(label = "로그아웃") { + showLogoutDialog = true + } + ProfileMenuCell(label = "회원 탈퇴", isDestructive = true) { + showSignOutDialog = true + } + + Spacer(modifier = Modifier.height(16.dp)) } - } - if (showLogoutDialog) { - CustomDialog( - title = "로그아웃", - body = "로그아웃하시겠습니까?", - needsCancelButton = true, - onDismissRequest = { showLogoutDialog = false }, - dismiss = { showLogoutDialog = false }, - confirm = { userViewModel.logout() } - ) - } + if (showLogoutDialog) { + CustomDialog( + title = "로그아웃", + body = "로그아웃하시겠습니까?", + needsCancelButton = true, + onDismissRequest = { showLogoutDialog = false }, + dismiss = { showLogoutDialog = false }, + confirm = { userViewModel.logout() } + ) + } - if (showSignOutDialog) { - CustomDialog( - title = "회원 탈퇴", - body = "계정을 삭제하시겠습니까?", - confirmText = "삭제", - isDestructive = true, - needsCancelButton = true, - onDismissRequest = { showSignOutDialog = false }, - dismiss = { showSignOutDialog = false }, - confirm = { userViewModel.signOut() } - ) + if (showSignOutDialog) { + CustomDialog( + title = "회원 탈퇴", + body = "계정을 삭제하시겠습니까?", + confirmText = "삭제", + isDestructive = true, + needsCancelButton = true, + onDismissRequest = { showSignOutDialog = false }, + dismiss = { showSignOutDialog = false }, + confirm = { userViewModel.signOut() } + ) + } } - } else { - EmptyProfile() } } } diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/CreatedEmojiListView.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/CreatedEmojiListView.kt new file mode 100644 index 00000000..4fbade49 --- /dev/null +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/CreatedEmojiListView.kt @@ -0,0 +1,21 @@ +package com.goliath.emojihub.views.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.goliath.emojihub.LocalNavController +import com.goliath.emojihub.ui.theme.Color + +@Composable +fun CreatedEmojiListView( + +) { + val navController = LocalNavController.current + + Column ( + Modifier.background(Color.White) + ) { + TopNavigationBar(navigate = { navController.popBackStack() }) + } +} \ No newline at end of file diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/CreatedPostListView.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/CreatedPostListView.kt new file mode 100644 index 00000000..59a0f116 --- /dev/null +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/CreatedPostListView.kt @@ -0,0 +1,21 @@ +package com.goliath.emojihub.views.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.goliath.emojihub.LocalNavController +import com.goliath.emojihub.ui.theme.Color + +@Composable +fun CreatedPostListView( + +) { + val navController = LocalNavController.current + + Column ( + Modifier.background(Color.White) + ) { + TopNavigationBar(navigate = { navController.popBackStack() }) + } +} \ No newline at end of file diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/PreviewPostCell.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/PreviewPostCell.kt new file mode 100644 index 00000000..d49773ab --- /dev/null +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/PreviewPostCell.kt @@ -0,0 +1,60 @@ +package com.goliath.emojihub.views.components + +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.goliath.emojihub.models.Post +import com.goliath.emojihub.ui.theme.Color.EmojiHubBorderColor +import com.goliath.emojihub.ui.theme.Color.EmojiHubDetailLabel + +@Composable +fun PreviewPostCell( + post: Post +) { + Column( + Modifier.width(240.dp) + .border(width = 1.dp, color = EmojiHubBorderColor, shape = RoundedCornerShape(8.dp)) + .padding(16.dp) + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + text = "@" + post.createdBy, + fontSize = 14.sp + ) + Spacer(Modifier.weight(1f)) + Text( + text = post.createdAt, + fontSize = 12.sp, + color = EmojiHubDetailLabel + ) + } + Spacer(Modifier.height(8.dp)) + Text( + text = post.content, + fontSize = 13.sp, + textAlign = TextAlign.Start, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.height(64.dp) + ) + Spacer(Modifier.height(8.dp)) + Text( + text = post.reaction.count().toString() + "개의 반응", + fontSize = 13.sp, + color = EmojiHubDetailLabel + ) + } +} \ No newline at end of file diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/ProfileMenuCellWithPreview.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/ProfileMenuCellWithPreview.kt new file mode 100644 index 00000000..f00d9dc3 --- /dev/null +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/ProfileMenuCellWithPreview.kt @@ -0,0 +1,72 @@ +package com.goliath.emojihub.views.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.NavigateNext +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.goliath.emojihub.models.dummyPost +import com.goliath.emojihub.ui.theme.Color + +@Composable +fun ProfileMenuCellWithPreview( + label: String, + detailLabel: String, + navigateToDestination: () -> Unit, + content: LazyListScope.() -> Unit +) { + val listState = rememberLazyListState() + + Column { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = label, + fontSize = 14.sp, + fontWeight = FontWeight.SemiBold + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + text = detailLabel, + fontSize = 14.sp, + fontWeight = FontWeight.SemiBold, + color = Color.EmojiHubGrayIcon + ) + IconButton(onClick = { navigateToDestination() }) { + Icon( + imageVector = Icons.Default.NavigateNext, + contentDescription = null, + modifier = Modifier.size(size = 24.dp), + tint = Color.EmojiHubGrayIcon + ) + } + } + Spacer(modifier = Modifier.height(10.dp)) + + LazyRow( + state = listState, + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { + content() + } + } +} \ No newline at end of file diff --git a/android/app/src/main/java/com/goliath/emojihub/views/components/SaveEmojiListView.kt b/android/app/src/main/java/com/goliath/emojihub/views/components/SaveEmojiListView.kt new file mode 100644 index 00000000..7907dc1c --- /dev/null +++ b/android/app/src/main/java/com/goliath/emojihub/views/components/SaveEmojiListView.kt @@ -0,0 +1,21 @@ +package com.goliath.emojihub.views.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.goliath.emojihub.LocalNavController +import com.goliath.emojihub.ui.theme.Color + +@Composable +fun SavedEmojiListView( + +) { + val navController = LocalNavController.current + + Column ( + Modifier.background(Color.White) + ) { + TopNavigationBar(navigate = { navController.popBackStack() }) + } +} \ No newline at end of file