From aa33ab46c9bba37625637bf9e92ed08687e553ef Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:48:18 +0900 Subject: [PATCH 01/65] =?UTF-8?q?feat=20::=20AI=20chatbot=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EA=B8=B0=EB=B3=B8=20=EA=B5=AC=EC=A1=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt new file mode 100644 index 000000000..bd6f799e1 --- /dev/null +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -0,0 +1,22 @@ +package team.aliens.dms.android.feature.dmsai.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import team.aliens.dms.android.core.designsystem.DmsTheme + +@Composable +fun DmsAiRoute() { + DmsAiScreen() +} + +@Composable +private fun DmsAiScreen() { + Box( + modifier = Modifier + .fillMaxSize() + .background(DmsTheme.colorScheme.background), + ) +} From 13f2071ebe4f6309e876fa8daebb68ebeb41da5e Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:49:22 +0900 Subject: [PATCH 02/65] =?UTF-8?q?feat=20::=20AI=20=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EB=AC=B8=EA=B5=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index bd6f799e1..f1d93a77c 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -1,10 +1,17 @@ -package team.aliens.dms.android.feature.dmsai.ui +package team.aliens.dms.android.feature.chatbot.ui import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.padding 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.unit.dp +import androidx.compose.material3.Text import team.aliens.dms.android.core.designsystem.DmsTheme @Composable @@ -14,9 +21,38 @@ fun DmsAiRoute() { @Composable private fun DmsAiScreen() { - Box( + Column( modifier = Modifier .fillMaxSize() - .background(DmsTheme.colorScheme.background), - ) + .background(DmsTheme.colorScheme.background) + .statusBarsPadding() + .padding(horizontal = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Top, + ) { + DmsAiHeader() + } +} + +@Composable +private fun DmsAiHeader() { + Column( + modifier = Modifier.padding(top = 120.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = "기숙사 생활,\n이제 바로 물어보세요", + color = DmsTheme.colorScheme.onBackground, + style = DmsTheme.typography.headline1, + textAlign = TextAlign.Center, + ) + + Text( + modifier = Modifier.padding(top = 24.dp), + text = "외출, 점호, 벌점, 세탁실 이용 등 기숙사 규정을 AI\n가 빠르고 정확하게 안내해 드립니다.", + color = DmsTheme.colorScheme.onSurfaceVariant, + style = DmsTheme.typography.body2, + textAlign = TextAlign.Center, + ) + } } From 22263bc1f1208214282b507293e1c469ee638e1e Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:50:28 +0900 Subject: [PATCH 03/65] =?UTF-8?q?feat=20::=20=20AI=20=EC=B6=94=EC=B2=9C=20?= =?UTF-8?q?=EC=A7=88=EB=AC=B8=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index f1d93a77c..9931e17d0 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -6,12 +6,15 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface +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.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.material3.Text import team.aliens.dms.android.core.designsystem.DmsTheme @Composable @@ -28,9 +31,9 @@ private fun DmsAiScreen() { .statusBarsPadding() .padding(horizontal = 24.dp), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Top, ) { DmsAiHeader() + SuggestionQuestions() } } @@ -56,3 +59,34 @@ private fun DmsAiHeader() { ) } } + +@Composable +private fun SuggestionQuestions() { + Column( + modifier = Modifier.padding(top = 72.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(18.dp), + ) { + SuggestionChip("외출 신청은 언제까지 해야 해?") + SuggestionChip("점호 시간 알려줘") + SuggestionChip("세탁실 이용 시간이 궁금해") + SuggestionChip("벌점 기준 알려줘") + } +} + +@Composable +private fun SuggestionChip(text: String) { + Surface( + modifier = Modifier.widthIn(min = 168.dp), + shape = RoundedCornerShape(12.dp), + color = DmsTheme.colorScheme.surfaceTint, + ) { + Text( + modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp), + text = text, + color = DmsTheme.colorScheme.onBackground, + style = DmsTheme.typography.body2, + textAlign = TextAlign.Center, + ) + } +} From 0e607187921d532b25ea8a296b6c6bfe9f3bf950 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:51:06 +0900 Subject: [PATCH 04/65] =?UTF-8?q?feat=20::=20AI=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=B0=BD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 70 +++++++++++++++++-- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 9931e17d0..84be586eb 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -2,17 +2,25 @@ package team.aliens.dms.android.feature.chatbot.ui import androidx.compose.foundation.background 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.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Surface 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.shadow import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import team.aliens.dms.android.core.designsystem.DmsTheme @@ -24,16 +32,28 @@ fun DmsAiRoute() { @Composable private fun DmsAiScreen() { - Column( + Box( modifier = Modifier .fillMaxSize() .background(DmsTheme.colorScheme.background) .statusBarsPadding() - .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally, + .navigationBarsPadding(), ) { - DmsAiHeader() - SuggestionQuestions() + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + DmsAiHeader() + SuggestionQuestions() + } + + DmsAiInputBar( + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(horizontal = 20.dp, vertical = 96.dp), + ) } } @@ -90,3 +110,41 @@ private fun SuggestionChip(text: String) { ) } } + +@Composable +private fun DmsAiInputBar(modifier: Modifier = Modifier) { + Surface( + modifier = modifier + .fillMaxWidth() + .shadow(14.dp, RoundedCornerShape(28.dp)), + shape = RoundedCornerShape(28.dp), + color = DmsTheme.colorScheme.surfaceTint, + ) { + Row( + modifier = Modifier.padding(start = 24.dp, top = 10.dp, end = 10.dp, bottom = 10.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = "DMS AI에게 질문해 보세요...", + color = DmsTheme.colorScheme.onSurfaceVariant, + style = DmsTheme.typography.body2, + ) + + Spacer(modifier = Modifier.weight(1f)) + + Surface( + modifier = Modifier.size(48.dp), + shape = CircleShape, + color = DmsTheme.colorScheme.secondary, + ) { + Box(contentAlignment = Alignment.Center) { + Text( + text = "↑", + color = DmsTheme.colorScheme.surfaceTint, + style = DmsTheme.typography.title2, + ) + } + } + } + } +} From f8c55fc1790da2ba858f3a6451fb65198254c0f6 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:53:46 +0900 Subject: [PATCH 05/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=ED=95=98=EB=8B=A8=20=EB=84=A4=EB=B9=84?= =?UTF-8?q?=EA=B2=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/component/ChatBotBottomNavigation.kt | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt new file mode 100644 index 000000000..f635e1119 --- /dev/null +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt @@ -0,0 +1,102 @@ +package team.aliens.dms.android.feature.chatbot.ui.component + +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.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import team.aliens.dms.android.core.designsystem.DmsTheme + +@Composable +internal fun ChatBotBottomNavigation( + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier.fillMaxWidth(), + shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp), + color = DmsTheme.colorScheme.surfaceTint, + ) { + Row( + modifier = Modifier.padding(horizontal = 32.dp, vertical = 16.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + ChatBotBottomNavigationItem( + icon = "⌂", + label = "홈", + selected = false, + ) + ChatBotBottomNavigationItem( + icon = "✓", + label = "신청", + selected = true, + ) + ChatBotBottomNavigationItem( + icon = "▱", + label = "챗봇", + selected = false, + ) + ChatBotBottomNavigationItem( + icon = "♙", + label = "마이페이지", + selected = false, + ) + } + } +} + +@Composable +private fun ChatBotBottomNavigationItem( + icon: String, + label: String, + selected: Boolean, +) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Surface( + modifier = Modifier.size(32.dp), + shape = CircleShape, + color = if (selected) { + DmsTheme.colorScheme.onBackground + } else { + DmsTheme.colorScheme.surfaceTint + }, + ) { + Box( + contentAlignment = Alignment.Center, + ) { + Text( + text = icon, + color = if (selected) { + DmsTheme.colorScheme.surfaceTint + } else { + DmsTheme.colorScheme.onSurfaceVariant + }, + style = DmsTheme.typography.body1, + ) + } + } + + Text( + modifier = Modifier.padding(top = 4.dp), + text = label, + color = if (selected) { + DmsTheme.colorScheme.onBackground + } else { + DmsTheme.colorScheme.onSurfaceVariant + }, + style = DmsTheme.typography.caption, + ) + } +} From 592efbb277f384af1f5971988d20b2ad0c8de422 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:56:48 +0900 Subject: [PATCH 06/65] =?UTF-8?q?refactor=20::=20=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=B0=BD=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatbot/ui/component/ChatBotInputBar.kt | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt new file mode 100644 index 000000000..1f6325a0d --- /dev/null +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -0,0 +1,65 @@ +package team.aliens.dms.android.feature.chatbot.ui.component + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface +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.shadow +import androidx.compose.ui.unit.dp +import team.aliens.dms.android.core.designsystem.DmsTheme + +@Composable +internal fun ChatBotInputBar( + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier + .fillMaxWidth() + .shadow(14.dp, RoundedCornerShape(28.dp)), + shape = RoundedCornerShape(28.dp), + color = DmsTheme.colorScheme.surfaceTint, + ) { + Row( + modifier = Modifier.padding( + start = 24.dp, + top = 10.dp, + end = 10.dp, + bottom = 10.dp, + ), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = "DMS AI에게 질문해 보세요...", + color = DmsTheme.colorScheme.onSurfaceVariant, + style = DmsTheme.typography.body2, + ) + + Spacer(modifier = Modifier.weight(1f)) + + Surface( + modifier = Modifier.size(48.dp), + shape = CircleShape, + color = DmsTheme.colorScheme.secondary, + ) { + Box( + contentAlignment = Alignment.Center, + ) { + Text( + text = "↑", + color = DmsTheme.colorScheme.surfaceTint, + style = DmsTheme.typography.title2, + ) + } + } + } + } +} From 284ab9aa4cf8355a0e2d805598f34e3285686919 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:57:05 +0900 Subject: [PATCH 07/65] =?UTF-8?q?refactor=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=B6=94=EC=B2=9C=20=EC=A7=88=EB=AC=B8=20=EC=B9=A9=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/component/ChatBotSuggestionChip.kt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt new file mode 100644 index 000000000..ac6afafa7 --- /dev/null +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt @@ -0,0 +1,32 @@ +package team.aliens.dms.android.feature.chatbot.ui.component + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import team.aliens.dms.android.core.designsystem.DmsTheme + +@Composable +internal fun ChatBotSuggestionChip( + text: String, + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier.widthIn(min = 168.dp), + shape = RoundedCornerShape(12.dp), + color = DmsTheme.colorScheme.surfaceTint, + ) { + Text( + modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp), + text = text, + color = DmsTheme.colorScheme.onBackground, + style = DmsTheme.typography.body2, + textAlign = TextAlign.Center, + ) + } +} From 3dd0cdf224fb412d128b0dfb2beb6e5da1e85790 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:57:56 +0900 Subject: [PATCH 08/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=83=81=ED=83=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/viewmodel/ChatBotState.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotState.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotState.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotState.kt new file mode 100644 index 000000000..2fc36fcab --- /dev/null +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotState.kt @@ -0,0 +1,14 @@ +package team.aliens.dms.android.feature.chatbot.viewmodel + +import androidx.compose.runtime.Immutable + +@Immutable +internal data class ChatBotState( + val input: String = "", + val suggestions: List = listOf( + "외출 신청은 언제까지 해야 해?", + "점호 시간 알려줘", + "세탁실 이용 시간이 궁금해", + "벌점 기준 알려줘", + ), +) From db88854368c42363ea42095ea02ed269d236fc33 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:58:05 +0900 Subject: [PATCH 09/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EB=B7=B0=EB=AA=A8=EB=8D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/viewmodel/ChatBotViewModel.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt new file mode 100644 index 000000000..ab9e84eb1 --- /dev/null +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt @@ -0,0 +1,11 @@ +package team.aliens.dms.android.feature.chatbot.viewmodel + +import androidx.lifecycle.ViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +internal class ChatBotViewModel : ViewModel() { + private val _state = MutableStateFlow(ChatBotState()) + val state: StateFlow = _state.asStateFlow() +} From cff9cffe93eff17850d0ed37c8ee410f887b7d9b Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:58:40 +0900 Subject: [PATCH 10/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=95=98=EB=8B=A8=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/component/ChatBotBottomNavigation.kt | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt index f635e1119..26e6c44ab 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt @@ -31,26 +31,10 @@ internal fun ChatBotBottomNavigation( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, ) { - ChatBotBottomNavigationItem( - icon = "⌂", - label = "홈", - selected = false, - ) - ChatBotBottomNavigationItem( - icon = "✓", - label = "신청", - selected = true, - ) - ChatBotBottomNavigationItem( - icon = "▱", - label = "챗봇", - selected = false, - ) - ChatBotBottomNavigationItem( - icon = "♙", - label = "마이페이지", - selected = false, - ) + ChatBotBottomNavigationItem("⌂", "홈", false) + ChatBotBottomNavigationItem("✓", "신청", false) + ChatBotBottomNavigationItem("▱", "챗봇", true) + ChatBotBottomNavigationItem("♙", "마이페이지", false) } } } @@ -61,9 +45,7 @@ private fun ChatBotBottomNavigationItem( label: String, selected: Boolean, ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { Surface( modifier = Modifier.size(32.dp), shape = CircleShape, @@ -73,9 +55,7 @@ private fun ChatBotBottomNavigationItem( DmsTheme.colorScheme.surfaceTint }, ) { - Box( - contentAlignment = Alignment.Center, - ) { + Box(contentAlignment = Alignment.Center) { Text( text = icon, color = if (selected) { From 30790f39e1088d60937085b618eeabe7f1c397ce Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 21:59:30 +0900 Subject: [PATCH 11/65] =?UTF-8?q?refactor=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 97 ++++--------------- 1 file changed, 20 insertions(+), 77 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 84be586eb..cecccd089 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -4,34 +4,28 @@ import androidx.compose.foundation.background 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.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding -import androidx.compose.foundation.layout.widthIn -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Surface 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.shadow import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import team.aliens.dms.android.core.designsystem.DmsTheme +import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotBottomNavigation +import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotInputBar +import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotSuggestionChip @Composable -fun DmsAiRoute() { - DmsAiScreen() +fun ChatBotRoute() { + ChatBotScreen() } @Composable -private fun DmsAiScreen() { +private fun ChatBotScreen() { Box( modifier = Modifier .fillMaxSize() @@ -45,20 +39,24 @@ private fun DmsAiScreen() { .padding(horizontal = 24.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - DmsAiHeader() - SuggestionQuestions() + ChatBotHeader() + ChatBotSuggestionQuestions() } - DmsAiInputBar( + ChatBotInputBar( modifier = Modifier .align(Alignment.BottomCenter) - .padding(horizontal = 20.dp, vertical = 96.dp), + .padding(horizontal = 20.dp, bottom = 96.dp), + ) + + ChatBotBottomNavigation( + modifier = Modifier.align(Alignment.BottomCenter), ) } } @Composable -private fun DmsAiHeader() { +private fun ChatBotHeader() { Column( modifier = Modifier.padding(top = 120.dp), horizontalAlignment = Alignment.CenterHorizontally, @@ -81,70 +79,15 @@ private fun DmsAiHeader() { } @Composable -private fun SuggestionQuestions() { +private fun ChatBotSuggestionQuestions() { Column( modifier = Modifier.padding(top = 72.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(18.dp), ) { - SuggestionChip("외출 신청은 언제까지 해야 해?") - SuggestionChip("점호 시간 알려줘") - SuggestionChip("세탁실 이용 시간이 궁금해") - SuggestionChip("벌점 기준 알려줘") - } -} - -@Composable -private fun SuggestionChip(text: String) { - Surface( - modifier = Modifier.widthIn(min = 168.dp), - shape = RoundedCornerShape(12.dp), - color = DmsTheme.colorScheme.surfaceTint, - ) { - Text( - modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp), - text = text, - color = DmsTheme.colorScheme.onBackground, - style = DmsTheme.typography.body2, - textAlign = TextAlign.Center, - ) - } -} - -@Composable -private fun DmsAiInputBar(modifier: Modifier = Modifier) { - Surface( - modifier = modifier - .fillMaxWidth() - .shadow(14.dp, RoundedCornerShape(28.dp)), - shape = RoundedCornerShape(28.dp), - color = DmsTheme.colorScheme.surfaceTint, - ) { - Row( - modifier = Modifier.padding(start = 24.dp, top = 10.dp, end = 10.dp, bottom = 10.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = "DMS AI에게 질문해 보세요...", - color = DmsTheme.colorScheme.onSurfaceVariant, - style = DmsTheme.typography.body2, - ) - - Spacer(modifier = Modifier.weight(1f)) - - Surface( - modifier = Modifier.size(48.dp), - shape = CircleShape, - color = DmsTheme.colorScheme.secondary, - ) { - Box(contentAlignment = Alignment.Center) { - Text( - text = "↑", - color = DmsTheme.colorScheme.surfaceTint, - style = DmsTheme.typography.title2, - ) - } - } - } + ChatBotSuggestionChip("외출 신청은 언제까지 해야 해?") + ChatBotSuggestionChip("점호 시간 알려줘") + ChatBotSuggestionChip("세탁실 이용 시간이 궁금해") + ChatBotSuggestionChip("벌점 기준 알려줘") } } From 86a0d14a61fa6e66905e924191dda90990040b73 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 22:00:22 +0900 Subject: [PATCH 12/65] =?UTF-8?q?fix=20::=20=EC=B1=97=EB=B4=87=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=B0=BD=20=ED=8C=A8=EB=94=A9=20=EC=98=A4=EB=A5=98=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 --- .../aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index cecccd089..e5679e3a7 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -46,7 +46,11 @@ private fun ChatBotScreen() { ChatBotInputBar( modifier = Modifier .align(Alignment.BottomCenter) - .padding(horizontal = 20.dp, bottom = 96.dp), + .padding( + start = 20.dp, + end = 20.dp, + bottom = 96.dp, + ), ) ChatBotBottomNavigation( From f9cc421f2b918e3e8ed7425f83330a57fee3c5bb Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 22:08:36 +0900 Subject: [PATCH 13/65] =?UTF-8?q?style=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=ED=94=84=EB=A6=AC=EB=B7=B0=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dms/android/feature/chatbot/ui/ChatBotScreen.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index e5679e3a7..49f1cf67a 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -49,7 +49,7 @@ private fun ChatBotScreen() { .padding( start = 20.dp, end = 20.dp, - bottom = 96.dp, + bottom = 92.dp, ), ) @@ -62,20 +62,20 @@ private fun ChatBotScreen() { @Composable private fun ChatBotHeader() { Column( - modifier = Modifier.padding(top = 120.dp), + modifier = Modifier.padding(top = 108.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { Text( text = "기숙사 생활,\n이제 바로 물어보세요", color = DmsTheme.colorScheme.onBackground, - style = DmsTheme.typography.headline1, + style = DmsTheme.typography.headline2, textAlign = TextAlign.Center, ) Text( - modifier = Modifier.padding(top = 24.dp), + modifier = Modifier.padding(top = 22.dp), text = "외출, 점호, 벌점, 세탁실 이용 등 기숙사 규정을 AI\n가 빠르고 정확하게 안내해 드립니다.", - color = DmsTheme.colorScheme.onSurfaceVariant, + color = DmsTheme.colorScheme.inverseOnSurface, style = DmsTheme.typography.body2, textAlign = TextAlign.Center, ) @@ -85,7 +85,7 @@ private fun ChatBotHeader() { @Composable private fun ChatBotSuggestionQuestions() { Column( - modifier = Modifier.padding(top = 72.dp), + modifier = Modifier.padding(top = 68.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(18.dp), ) { From b436f6accce1bffa96e67b207c26e1f32c5ea5da Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 22:12:39 +0900 Subject: [PATCH 14/65] =?UTF-8?q?style=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=88=20=ED=99=94=EB=A9=B4=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 61 +++++++++++++++++-- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 49f1cf67a..bf050b7ba 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -7,12 +7,17 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface 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.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import team.aliens.dms.android.core.designsystem.DmsTheme import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotBottomNavigation @@ -23,7 +28,6 @@ import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotSuggestionChi fun ChatBotRoute() { ChatBotScreen() } - @Composable private fun ChatBotScreen() { Box( @@ -39,6 +43,11 @@ private fun ChatBotScreen() { .padding(horizontal = 24.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { + ChatBotProfileIcon( + modifier = Modifier + .align(Alignment.End) + .padding(top = 26.dp, end = 8.dp), + ) ChatBotHeader() ChatBotSuggestionQuestions() } @@ -49,7 +58,7 @@ private fun ChatBotScreen() { .padding( start = 20.dp, end = 20.dp, - bottom = 92.dp, + bottom = 112.dp, ), ) @@ -59,10 +68,39 @@ private fun ChatBotScreen() { } } +@Composable +private fun ChatBotProfileIcon( + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier.size(28.dp), + shape = CircleShape, + color = DmsTheme.colorScheme.inverseOnSurface, + ) { + Box(contentAlignment = Alignment.BottomCenter) { + Surface( + modifier = Modifier + .padding(bottom = 15.dp) + .size(9.dp), + shape = CircleShape, + color = DmsTheme.colorScheme.surfaceTint, + ) {} + + Surface( + modifier = Modifier + .padding(bottom = 3.dp) + .size(width = 18.dp, height = 9.dp), + shape = RoundedCornerShape(topStart = 9.dp, topEnd = 9.dp), + color = DmsTheme.colorScheme.surfaceTint, + ) {} + } + } +} + @Composable private fun ChatBotHeader() { Column( - modifier = Modifier.padding(top = 108.dp), + modifier = Modifier.padding(top = 44.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { Text( @@ -76,7 +114,7 @@ private fun ChatBotHeader() { modifier = Modifier.padding(top = 22.dp), text = "외출, 점호, 벌점, 세탁실 이용 등 기숙사 규정을 AI\n가 빠르고 정확하게 안내해 드립니다.", color = DmsTheme.colorScheme.inverseOnSurface, - style = DmsTheme.typography.body2, + style = DmsTheme.typography.body3, textAlign = TextAlign.Center, ) } @@ -85,7 +123,7 @@ private fun ChatBotHeader() { @Composable private fun ChatBotSuggestionQuestions() { Column( - modifier = Modifier.padding(top = 68.dp), + modifier = Modifier.padding(top = 74.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(18.dp), ) { @@ -95,3 +133,16 @@ private fun ChatBotSuggestionQuestions() { ChatBotSuggestionChip("벌점 기준 알려줘") } } + +@Preview( + name = "ChatBot Screen", + showBackground = true, + widthDp = 375, + heightDp = 812, +) +@Composable +fun ChatBotScreenPreview() { + DmsTheme { + ChatBotScreen() + } +} From 7b2879ea74c3e34db00560b49d6f5429d52b0f0d Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 22:15:00 +0900 Subject: [PATCH 15/65] =?UTF-8?q?style=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=B0=BD=20=ED=81=AC=EA=B8=B0=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatbot/ui/component/ChatBotInputBar.kt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index 1f6325a0d..85a23e7b6 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -31,28 +31,26 @@ internal fun ChatBotInputBar( Row( modifier = Modifier.padding( start = 24.dp, - top = 10.dp, - end = 10.dp, - bottom = 10.dp, + top = 8.dp, + end = 8.dp, + bottom = 8.dp, ), verticalAlignment = Alignment.CenterVertically, ) { Text( text = "DMS AI에게 질문해 보세요...", - color = DmsTheme.colorScheme.onSurfaceVariant, + color = DmsTheme.colorScheme.inverseOnSurface, style = DmsTheme.typography.body2, ) Spacer(modifier = Modifier.weight(1f)) Surface( - modifier = Modifier.size(48.dp), + modifier = Modifier.size(44.dp), shape = CircleShape, color = DmsTheme.colorScheme.secondary, ) { - Box( - contentAlignment = Alignment.Center, - ) { + Box(contentAlignment = Alignment.Center) { Text( text = "↑", color = DmsTheme.colorScheme.surfaceTint, From b3b7358dcdc06cb7d7e70c32d22691c0a2883825 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 22:15:10 +0900 Subject: [PATCH 16/65] =?UTF-8?q?style=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=B6=94=EC=B2=9C=20=EC=A7=88=EB=AC=B8=20=EC=B9=A9=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/component/ChatBotSuggestionChip.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt index ac6afafa7..d271c1e47 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt @@ -17,15 +17,15 @@ internal fun ChatBotSuggestionChip( modifier: Modifier = Modifier, ) { Surface( - modifier = modifier.widthIn(min = 168.dp), + modifier = modifier, shape = RoundedCornerShape(12.dp), color = DmsTheme.colorScheme.surfaceTint, ) { Text( - modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp), + modifier = Modifier.padding(horizontal = 22.dp, vertical = 14.dp), text = text, color = DmsTheme.colorScheme.onBackground, - style = DmsTheme.typography.body2, + style = DmsTheme.typography.body3, textAlign = TextAlign.Center, ) } From e68ca4771d938821f12891c85a2f2306f8da3086 Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 22:16:27 +0900 Subject: [PATCH 17/65] =?UTF-8?q?refactor=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EA=B0=9C=EB=B3=84=20=ED=95=98=EB=8B=A8?= =?UTF-8?q?=EB=B0=94=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 5 -- .../ui/component/ChatBotBottomNavigation.kt | 82 ------------------- 2 files changed, 87 deletions(-) delete mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index bf050b7ba..b201ddac1 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -20,7 +20,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import team.aliens.dms.android.core.designsystem.DmsTheme -import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotBottomNavigation import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotInputBar import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotSuggestionChip @@ -61,10 +60,6 @@ private fun ChatBotScreen() { bottom = 112.dp, ), ) - - ChatBotBottomNavigation( - modifier = Modifier.align(Alignment.BottomCenter), - ) } } diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt deleted file mode 100644 index 26e6c44ab..000000000 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotBottomNavigation.kt +++ /dev/null @@ -1,82 +0,0 @@ -package team.aliens.dms.android.feature.chatbot.ui.component - -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.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import team.aliens.dms.android.core.designsystem.DmsTheme - -@Composable -internal fun ChatBotBottomNavigation( - modifier: Modifier = Modifier, -) { - Surface( - modifier = modifier.fillMaxWidth(), - shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp), - color = DmsTheme.colorScheme.surfaceTint, - ) { - Row( - modifier = Modifier.padding(horizontal = 32.dp, vertical = 16.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - ChatBotBottomNavigationItem("⌂", "홈", false) - ChatBotBottomNavigationItem("✓", "신청", false) - ChatBotBottomNavigationItem("▱", "챗봇", true) - ChatBotBottomNavigationItem("♙", "마이페이지", false) - } - } -} - -@Composable -private fun ChatBotBottomNavigationItem( - icon: String, - label: String, - selected: Boolean, -) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Surface( - modifier = Modifier.size(32.dp), - shape = CircleShape, - color = if (selected) { - DmsTheme.colorScheme.onBackground - } else { - DmsTheme.colorScheme.surfaceTint - }, - ) { - Box(contentAlignment = Alignment.Center) { - Text( - text = icon, - color = if (selected) { - DmsTheme.colorScheme.surfaceTint - } else { - DmsTheme.colorScheme.onSurfaceVariant - }, - style = DmsTheme.typography.body1, - ) - } - } - - Text( - modifier = Modifier.padding(top = 4.dp), - text = label, - color = if (selected) { - DmsTheme.colorScheme.onBackground - } else { - DmsTheme.colorScheme.onSurfaceVariant - }, - style = DmsTheme.typography.caption, - ) - } -} From 0521153aa6712ac101ba4c51042d2a1725bae14c Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 22:24:03 +0900 Subject: [PATCH 18/65] =?UTF-8?q?style=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=B6=94=EC=B2=9C=20=EC=A7=88=EB=AC=B8=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=91=90=EA=BB=98=EC=99=80=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt | 2 +- .../feature/chatbot/ui/component/ChatBotSuggestionChip.kt | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index b201ddac1..353ba43a4 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -108,7 +108,7 @@ private fun ChatBotHeader() { Text( modifier = Modifier.padding(top = 22.dp), text = "외출, 점호, 벌점, 세탁실 이용 등 기숙사 규정을 AI\n가 빠르고 정확하게 안내해 드립니다.", - color = DmsTheme.colorScheme.inverseOnSurface, + color = DmsTheme.colorScheme.inverseSurface, style = DmsTheme.typography.body3, textAlign = TextAlign.Center, ) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt index d271c1e47..2ddc82892 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt @@ -1,12 +1,12 @@ package team.aliens.dms.android.feature.chatbot.ui.component import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import team.aliens.dms.android.core.designsystem.DmsTheme @@ -24,8 +24,9 @@ internal fun ChatBotSuggestionChip( Text( modifier = Modifier.padding(horizontal = 22.dp, vertical = 14.dp), text = text, - color = DmsTheme.colorScheme.onBackground, + color = DmsTheme.colorScheme.surfaceBright, style = DmsTheme.typography.body3, + fontWeight = FontWeight.Normal, textAlign = TextAlign.Center, ) } From f10cd9edc7f941870b4e29fb5b37cb8c0f1039fe Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 23:35:45 +0900 Subject: [PATCH 19/65] =?UTF-8?q?style=20::=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EC=B9=A9=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt | 4 ++-- .../feature/chatbot/ui/component/ChatBotSuggestionChip.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 353ba43a4..333ef6794 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -118,9 +118,9 @@ private fun ChatBotHeader() { @Composable private fun ChatBotSuggestionQuestions() { Column( - modifier = Modifier.padding(top = 74.dp), + modifier = Modifier.padding(top = 46.dp), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(18.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), ) { ChatBotSuggestionChip("외출 신청은 언제까지 해야 해?") ChatBotSuggestionChip("점호 시간 알려줘") diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt index 2ddc82892..7f88d791c 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt @@ -22,7 +22,7 @@ internal fun ChatBotSuggestionChip( color = DmsTheme.colorScheme.surfaceTint, ) { Text( - modifier = Modifier.padding(horizontal = 22.dp, vertical = 14.dp), + modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), text = text, color = DmsTheme.colorScheme.surfaceBright, style = DmsTheme.typography.body3, From 9dcbe1a9a160333f88ff9316c483480088d7587e Mon Sep 17 00:00:00 2001 From: ashxom Date: Thu, 2 Jul 2026 23:49:29 +0900 Subject: [PATCH 20/65] =?UTF-8?q?style=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=B0=BD=20=ED=85=8D=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=99=80=20=EB=B2=84=ED=8A=BC=20=ED=81=AC=EA=B8=B0=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatbot/ui/component/ChatBotInputBar.kt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index 85a23e7b6..69919ce77 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import team.aliens.dms.android.core.designsystem.DmsTheme @@ -24,37 +25,39 @@ internal fun ChatBotInputBar( Surface( modifier = modifier .fillMaxWidth() - .shadow(14.dp, RoundedCornerShape(28.dp)), + .shadow(4.dp, RoundedCornerShape(28.dp)), shape = RoundedCornerShape(28.dp), color = DmsTheme.colorScheme.surfaceTint, ) { Row( modifier = Modifier.padding( start = 24.dp, - top = 8.dp, - end = 8.dp, - bottom = 8.dp, + top = 6.dp, + end = 6.dp, + bottom = 6.dp, ), verticalAlignment = Alignment.CenterVertically, ) { Text( text = "DMS AI에게 질문해 보세요...", color = DmsTheme.colorScheme.inverseOnSurface, - style = DmsTheme.typography.body2, + style = DmsTheme.typography.body3, + fontWeight = FontWeight.Normal, ) Spacer(modifier = Modifier.weight(1f)) Surface( - modifier = Modifier.size(44.dp), + modifier = Modifier.size(40.dp), shape = CircleShape, - color = DmsTheme.colorScheme.secondary, + color = DmsTheme.colorScheme.onPrimaryContainer, ) { Box(contentAlignment = Alignment.Center) { Text( text = "↑", color = DmsTheme.colorScheme.surfaceTint, - style = DmsTheme.typography.title2, + style = DmsTheme.typography.title3, + fontWeight = FontWeight.Normal, ) } } From 0f0eb48cd285e6367e62094f08d0729a375fc2a4 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 00:03:45 +0900 Subject: [PATCH 21/65] =?UTF-8?q?style=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 43 ++----------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 333ef6794..23a3a251d 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -7,11 +7,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -27,6 +23,7 @@ import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotSuggestionChi fun ChatBotRoute() { ChatBotScreen() } + @Composable private fun ChatBotScreen() { Box( @@ -42,11 +39,6 @@ private fun ChatBotScreen() { .padding(horizontal = 24.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - ChatBotProfileIcon( - modifier = Modifier - .align(Alignment.End) - .padding(top = 26.dp, end = 8.dp), - ) ChatBotHeader() ChatBotSuggestionQuestions() } @@ -63,39 +55,10 @@ private fun ChatBotScreen() { } } -@Composable -private fun ChatBotProfileIcon( - modifier: Modifier = Modifier, -) { - Surface( - modifier = modifier.size(28.dp), - shape = CircleShape, - color = DmsTheme.colorScheme.inverseOnSurface, - ) { - Box(contentAlignment = Alignment.BottomCenter) { - Surface( - modifier = Modifier - .padding(bottom = 15.dp) - .size(9.dp), - shape = CircleShape, - color = DmsTheme.colorScheme.surfaceTint, - ) {} - - Surface( - modifier = Modifier - .padding(bottom = 3.dp) - .size(width = 18.dp, height = 9.dp), - shape = RoundedCornerShape(topStart = 9.dp, topEnd = 9.dp), - color = DmsTheme.colorScheme.surfaceTint, - ) {} - } - } -} - @Composable private fun ChatBotHeader() { Column( - modifier = Modifier.padding(top = 44.dp), + modifier = Modifier.padding(top = 92.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { Text( @@ -137,7 +100,7 @@ private fun ChatBotSuggestionQuestions() { ) @Composable fun ChatBotScreenPreview() { - DmsTheme { + DmsTheme(isDarkTheme = false) { ChatBotScreen() } } From d0be284ac5741c970f060adb9648b99cc5a2386a Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 08:55:43 +0900 Subject: [PATCH 22/65] =?UTF-8?q?feat=20::=20chatbot=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/drawable/ic_chatbot.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 core/design-system/src/main/res/drawable/ic_chatbot.xml diff --git a/core/design-system/src/main/res/drawable/ic_chatbot.xml b/core/design-system/src/main/res/drawable/ic_chatbot.xml new file mode 100644 index 000000000..f81ed1258 --- /dev/null +++ b/core/design-system/src/main/res/drawable/ic_chatbot.xml @@ -0,0 +1,14 @@ + + + + From 8433a70bee71d06a48436d5e8371a520d4eb2d06 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:01:57 +0900 Subject: [PATCH 23/65] =?UTF-8?q?feat=20::=20=EC=84=A0=ED=83=9D=EB=90=9C?= =?UTF-8?q?=20=EC=B1=97=EB=B4=87=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/drawable/ic_chatbot.xml | 16 ++++++++++++---- .../src/main/res/drawable/ic_chatbot_fill.xml | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 core/design-system/src/main/res/drawable/ic_chatbot_fill.xml diff --git a/core/design-system/src/main/res/drawable/ic_chatbot.xml b/core/design-system/src/main/res/drawable/ic_chatbot.xml index f81ed1258..59ff97f3f 100644 --- a/core/design-system/src/main/res/drawable/ic_chatbot.xml +++ b/core/design-system/src/main/res/drawable/ic_chatbot.xml @@ -5,10 +5,18 @@ android:viewportHeight="32"> + android:pathData="M9.828,16H20V14H9.828V16Z" + android:fillColor="#B0B6C1"/> + + diff --git a/core/design-system/src/main/res/drawable/ic_chatbot_fill.xml b/core/design-system/src/main/res/drawable/ic_chatbot_fill.xml new file mode 100644 index 000000000..f81ed1258 --- /dev/null +++ b/core/design-system/src/main/res/drawable/ic_chatbot_fill.xml @@ -0,0 +1,14 @@ + + + + From d9cfbc95321188fb561ef876d78b2a7beb22fbd2 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:08:00 +0900 Subject: [PATCH 24/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EB=A6=AC=EC=86=8C=EC=8A=A4=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aliens/dms/android/core/designsystem/foundation/DmsIcon.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/design-system/src/main/java/team/aliens/dms/android/core/designsystem/foundation/DmsIcon.kt b/core/design-system/src/main/java/team/aliens/dms/android/core/designsystem/foundation/DmsIcon.kt index c01415586..24ed9eb7a 100644 --- a/core/design-system/src/main/java/team/aliens/dms/android/core/designsystem/foundation/DmsIcon.kt +++ b/core/design-system/src/main/java/team/aliens/dms/android/core/designsystem/foundation/DmsIcon.kt @@ -24,6 +24,8 @@ object DmsIcon { val HomeFill = R.drawable.ic_home_fill val CheckCircle = R.drawable.ic_application val CheckCircleFill = R.drawable.ic_application_fill + val ChatBot = R.drawable.ic_chatbot + val ChatBotFill = R.drawable.ic_chatbot_fill val MyPage = R.drawable.ic_my_page val MyPageFill = R.drawable.ic_my_page_fill val Information = R.drawable.ic_information From 0bd8437837edb412e361f1fc483b90060c77fda2 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:08:30 +0900 Subject: [PATCH 25/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=95=98=EB=8B=A8=EB=B0=94=20=EB=A9=94=EB=89=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team/aliens/dms/android/app/navigation/BottomMenu.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomMenu.kt b/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomMenu.kt index 592324707..02c6b6a5f 100644 --- a/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomMenu.kt +++ b/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomMenu.kt @@ -27,6 +27,13 @@ sealed class BottomMenu( title = "신청", ) + data object ChatBot : BottomMenu( + route = ChatBotScreenNav, + icon = DmsIcon.ChatBot, + selectedIcon = DmsIcon.ChatBotFill, + title = "챗봇", + ) + data object MyPage : BottomMenu( route = MyPageScreenNav, icon = DmsIcon.MyPage, From 116161ecbbb787735dfcf3aca88702f21497ad71 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:09:35 +0900 Subject: [PATCH 26/65] =?UTF-8?q?feat=20::=20=ED=95=98=EB=8B=A8=EB=B0=94?= =?UTF-8?q?=EC=97=90=20=EC=B1=97=EB=B4=87=20=EB=A9=94=EB=89=B4=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dms/android/app/navigation/BottomNavigationBar.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomNavigationBar.kt b/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomNavigationBar.kt index 78eee2cf2..a81b974c4 100644 --- a/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomNavigationBar.kt +++ b/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomNavigationBar.kt @@ -25,6 +25,7 @@ import team.aliens.dms.android.core.designsystem.labelB private val bottomMenus = listOf( BottomMenu.Home, BottomMenu.Application, + BottomMenu.ChatBot, BottomMenu.MyPage, ) @@ -64,7 +65,13 @@ fun BottomNavigationBar( ) { Icon( modifier = Modifier.size(32.dp), - painter = painterResource(id = if (selected) destination.selectedIcon else destination.icon), + painter = painterResource( + id = if (selected) { + destination.selectedIcon + } else { + destination.icon + }, + ), contentDescription = destination.title, tint = color, ) From fe7f02eda0e55d75e7f0b675070aea307f16ed16 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:12:47 +0900 Subject: [PATCH 27/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=ED=82=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team/aliens/dms/android/app/navigation/DmsNavKeys.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/kotlin/team/aliens/dms/android/app/navigation/DmsNavKeys.kt b/app/src/main/kotlin/team/aliens/dms/android/app/navigation/DmsNavKeys.kt index ad74e1790..579284444 100644 --- a/app/src/main/kotlin/team/aliens/dms/android/app/navigation/DmsNavKeys.kt +++ b/app/src/main/kotlin/team/aliens/dms/android/app/navigation/DmsNavKeys.kt @@ -14,6 +14,9 @@ data object SignInScreenNav : NavKey @Serializable data object HomeScreenNav : NavKey +@Serializable +data object ChatBotScreenNav : NavKey + @Serializable data object MealScreenNav : NavKey From b9bd842f7e376441247e51563102ccbc80ea0925 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:25:51 +0900 Subject: [PATCH 28/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=9D=BC=EC=9A=B0=ED=8A=B8=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt b/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt index 9136cd0ae..31955978e 100644 --- a/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt +++ b/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt @@ -84,6 +84,8 @@ import team.aliens.dms.android.app.navigation.SignUpSetPasswordNav import team.aliens.dms.android.app.navigation.SignUpTermsNav import team.aliens.dms.android.feature.latestudy.navigation.LateStudyRoute import java.util.UUID +import team.aliens.dms.android.app.navigation.ChatBotScreenNav +import team.aliens.dms.android.feature.chatbot.ui.ChatBotRoute @Composable @@ -101,6 +103,7 @@ fun DmsApp( val shouldShowBottomBar = currentScreen in listOf( HomeScreenNav, ApplicationScreenNav, + ChatBotScreenNav, MyPageScreenNav, ) @@ -137,9 +140,9 @@ fun DmsApp( } backStack.removeAll { it is ApplicationScreenNav || + it is ChatBotScreenNav || it is MyPageScreenNav } - backStack.add(destination) } } ) @@ -213,6 +216,9 @@ fun DmsApp( } ) } + entry { + ChatBotRoute() + } entry { VoteRoute( onNavigateBack = { backStack.remove(VoteScreenNav) }, From 1d083b67aac688f270454910bf3a614f96a048b3 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:30:43 +0900 Subject: [PATCH 29/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=83=81=ED=83=9C=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/viewmodel/ChatBotState.kt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotState.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotState.kt index 2fc36fcab..7f1d7f3a7 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotState.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotState.kt @@ -1,14 +1,12 @@ package team.aliens.dms.android.feature.chatbot.viewmodel -import androidx.compose.runtime.Immutable - -@Immutable -internal data class ChatBotState( +data class ChatBotState( val input: String = "", - val suggestions: List = listOf( - "외출 신청은 언제까지 해야 해?", - "점호 시간 알려줘", - "세탁실 이용 시간이 궁금해", - "벌점 기준 알려줘", - ), + val messages: List = emptyList(), + val isLoading: Boolean = false, +) + +data class ChatBotMessage( + val text: String, + val isUser: Boolean, ) From 36330e1f769b4240ead3a3e24aaf5722339e4a66 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:44:45 +0900 Subject: [PATCH 30/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=A4=91=20=ED=91=9C=EC=8B=9C=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=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 --- .../ui/component/ChatBotTypingIndicator.kt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotTypingIndicator.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotTypingIndicator.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotTypingIndicator.kt new file mode 100644 index 000000000..c068f4234 --- /dev/null +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotTypingIndicator.kt @@ -0,0 +1,27 @@ +package team.aliens.dms.android.feature.chatbot.ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import team.aliens.dms.android.core.designsystem.DmsTheme + +@Composable +internal fun ChatBotTypingIndicator() { + Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { + repeat(3) { + Box( + modifier = Modifier + .size(6.dp) + .clip(CircleShape) + .background(DmsTheme.colorScheme.inverseSurface), + ) + } + } +} From 52af8a1bb192895d2bda5a2d9407a2d95715ebae Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:49:15 +0900 Subject: [PATCH 31/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=A7=90=ED=92=8D=EC=84=A0=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=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 --- .../ui/component/ChatBotMessageBubble.kt | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotMessageBubble.kt diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotMessageBubble.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotMessageBubble.kt new file mode 100644 index 000000000..ab36b2530 --- /dev/null +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotMessageBubble.kt @@ -0,0 +1,55 @@ +package team.aliens.dms.android.feature.chatbot.ui.component + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import team.aliens.dms.android.core.designsystem.DmsTheme + +@Composable +internal fun ChatBotMessageBubble( + text: String, + isUser: Boolean, + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier.widthIn(max = 280.dp), + shape = RoundedCornerShape(12.dp), + color = if (isUser) { + DmsTheme.colorScheme.surfaceVariant + } else { + DmsTheme.colorScheme.surfaceTint + }, + ) { + Text( + modifier = Modifier.padding(horizontal = 18.dp, vertical = 14.dp), + text = text, + color = DmsTheme.colorScheme.surfaceBright, + style = DmsTheme.typography.body3, + fontWeight = FontWeight.Normal, + ) + } +} + +@Composable +internal fun ChatBotTypingBubble( + modifier: Modifier = Modifier, +) { + Surface( + modifier = modifier, + shape = RoundedCornerShape(12.dp), + color = DmsTheme.colorScheme.surfaceTint, + ) { + Box( + modifier = Modifier.padding(horizontal = 18.dp, vertical = 16.dp), + ) { + ChatBotTypingIndicator() + } + } +} From 3ad340f9a707c742959c26312dca9d8489f66b39 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:54:18 +0900 Subject: [PATCH 32/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EC=A7=88=EB=AC=B8=20=EB=84=A4=ED=8A=B8=EC=9B=8C=ED=81=AC=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/network/chatbot/model/ChatBotAnswerResponse.kt | 5 +++++ .../android/network/chatbot/model/ChatBotQuestionRequest.kt | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 network/src/main/kotlin/team/aliens/dms/android/network/chatbot/model/ChatBotAnswerResponse.kt create mode 100644 network/src/main/kotlin/team/aliens/dms/android/network/chatbot/model/ChatBotQuestionRequest.kt diff --git a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/model/ChatBotAnswerResponse.kt b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/model/ChatBotAnswerResponse.kt new file mode 100644 index 000000000..aef8f0d2f --- /dev/null +++ b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/model/ChatBotAnswerResponse.kt @@ -0,0 +1,5 @@ +package team.aliens.dms.android.network.chatbot.model + +data class ChatBotAnswerResponse( + val answer: String, +) diff --git a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/model/ChatBotQuestionRequest.kt b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/model/ChatBotQuestionRequest.kt new file mode 100644 index 000000000..4e7cd59d2 --- /dev/null +++ b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/model/ChatBotQuestionRequest.kt @@ -0,0 +1,5 @@ +package team.aliens.dms.android.network.chatbot.model + +data class ChatBotQuestionRequest( + val question: String, +) From 57b69dd35c6666aae229e25597d320719524b82f Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:55:08 +0900 Subject: [PATCH 33/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20API=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network/chatbot/apiservice/ChatBotApiService.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 network/src/main/kotlin/team/aliens/dms/android/network/chatbot/apiservice/ChatBotApiService.kt diff --git a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/apiservice/ChatBotApiService.kt b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/apiservice/ChatBotApiService.kt new file mode 100644 index 000000000..8f90232eb --- /dev/null +++ b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/apiservice/ChatBotApiService.kt @@ -0,0 +1,13 @@ +package team.aliens.dms.android.network.chatbot.apiservice + +import retrofit2.http.Body +import retrofit2.http.POST +import team.aliens.dms.android.network.chatbot.model.ChatBotAnswerResponse +import team.aliens.dms.android.network.chatbot.model.ChatBotQuestionRequest + +interface ChatBotApiService { + @POST("/chatbots/questions") + suspend fun askQuestion( + @Body request: ChatBotQuestionRequest, + ): ChatBotAnswerResponse +} From 5d0f237d6e6784f33de3662b37279c684ba1c7c4 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:56:53 +0900 Subject: [PATCH 34/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20Reposito?= =?UTF-8?q?ry=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/chatbot/repository/ChatBotRepository.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepository.kt diff --git a/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepository.kt b/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepository.kt new file mode 100644 index 000000000..bd24f69cc --- /dev/null +++ b/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepository.kt @@ -0,0 +1,14 @@ +package team.aliens.dms.android.data.chatbot.repository + +import team.aliens.dms.android.network.chatbot.apiservice.ChatBotApiService +import team.aliens.dms.android.network.chatbot.model.ChatBotQuestionRequest + +class ChatBotRepository( + private val chatBotApi: ChatBotApiService, +) { + suspend fun askQuestion(question: String): String { + return chatBotApi.askQuestion( + request = ChatBotQuestionRequest(question = question), + ).answer + } +} From bb5937f1ec2ae68dc0aad74830ef3e85467318dc Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:58:21 +0900 Subject: [PATCH 35/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EB=84=A4=ED=8A=B8=EC=9B=8C=ED=81=AC=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EC=86=8C=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/NetworkChatBotDataSource.kt | 10 ++++++++++ .../datasource/NetworkChatBotDataSourceImpl.kt | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 network/src/main/kotlin/team/aliens/dms/android/network/chatbot/datasource/NetworkChatBotDataSource.kt create mode 100644 network/src/main/kotlin/team/aliens/dms/android/network/chatbot/datasource/NetworkChatBotDataSourceImpl.kt diff --git a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/datasource/NetworkChatBotDataSource.kt b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/datasource/NetworkChatBotDataSource.kt new file mode 100644 index 000000000..f638161a8 --- /dev/null +++ b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/datasource/NetworkChatBotDataSource.kt @@ -0,0 +1,10 @@ +package team.aliens.dms.android.network.chatbot.datasource + +import team.aliens.dms.android.network.chatbot.model.ChatBotAnswerResponse +import team.aliens.dms.android.network.chatbot.model.ChatBotQuestionRequest + +interface NetworkChatBotDataSource { + suspend fun askQuestion( + request: ChatBotQuestionRequest, + ): ChatBotAnswerResponse +} diff --git a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/datasource/NetworkChatBotDataSourceImpl.kt b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/datasource/NetworkChatBotDataSourceImpl.kt new file mode 100644 index 000000000..3ba3806e3 --- /dev/null +++ b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/datasource/NetworkChatBotDataSourceImpl.kt @@ -0,0 +1,16 @@ +package team.aliens.dms.android.network.chatbot.datasource + +import team.aliens.dms.android.network.chatbot.apiservice.ChatBotApiService +import team.aliens.dms.android.network.chatbot.model.ChatBotAnswerResponse +import team.aliens.dms.android.network.chatbot.model.ChatBotQuestionRequest +import javax.inject.Inject + +class NetworkChatBotDataSourceImpl @Inject constructor( + private val chatBotApiService: ChatBotApiService, +) : NetworkChatBotDataSource { + override suspend fun askQuestion( + request: ChatBotQuestionRequest, + ): ChatBotAnswerResponse { + return chatBotApiService.askQuestion(request) + } +} From 6b35cf22033043ac06f6340a3ed781fb847d180e Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 09:59:17 +0900 Subject: [PATCH 36/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=EB=84=A4=ED=8A=B8=EC=9B=8C=ED=81=AC=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatbot/di/ChatBotNetworkModule.kt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt diff --git a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt new file mode 100644 index 000000000..323cfdb6b --- /dev/null +++ b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt @@ -0,0 +1,32 @@ +package team.aliens.dms.android.network.chatbot.di + +import dagger.Binds +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import retrofit2.Retrofit +import team.aliens.dms.android.network.chatbot.apiservice.ChatBotApiService +import team.aliens.dms.android.network.chatbot.datasource.NetworkChatBotDataSource +import team.aliens.dms.android.network.chatbot.datasource.NetworkChatBotDataSourceImpl +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal abstract class ChatBotNetworkModule { + @Binds + @Singleton + abstract fun bindNetworkChatBotDataSource( + networkChatBotDataSourceImpl: NetworkChatBotDataSourceImpl, + ): NetworkChatBotDataSource + + companion object { + @Provides + @Singleton + fun provideChatBotApiService( + retrofit: Retrofit, + ): ChatBotApiService { + return retrofit.create(ChatBotApiService::class.java) + } + } +} From 3c4377cbf4bc30cffcd6190b0762b3236a4aea0d Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:00:43 +0900 Subject: [PATCH 37/65] =?UTF-8?q?feat=20::=20Repository=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=B2=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/chatbot/repository/ChatBotRepository.kt | 13 ++----------- .../chatbot/repository/ChatBotRepositoryImpl.kt | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepositoryImpl.kt diff --git a/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepository.kt b/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepository.kt index bd24f69cc..d217d59a8 100644 --- a/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepository.kt +++ b/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepository.kt @@ -1,14 +1,5 @@ package team.aliens.dms.android.data.chatbot.repository -import team.aliens.dms.android.network.chatbot.apiservice.ChatBotApiService -import team.aliens.dms.android.network.chatbot.model.ChatBotQuestionRequest - -class ChatBotRepository( - private val chatBotApi: ChatBotApiService, -) { - suspend fun askQuestion(question: String): String { - return chatBotApi.askQuestion( - request = ChatBotQuestionRequest(question = question), - ).answer - } +interface ChatBotRepository { + suspend fun askQuestion(question: String): String } diff --git a/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepositoryImpl.kt b/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepositoryImpl.kt new file mode 100644 index 000000000..37e283bf9 --- /dev/null +++ b/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/repository/ChatBotRepositoryImpl.kt @@ -0,0 +1,15 @@ +package team.aliens.dms.android.data.chatbot.repository + +import team.aliens.dms.android.network.chatbot.datasource.NetworkChatBotDataSource +import team.aliens.dms.android.network.chatbot.model.ChatBotQuestionRequest +import javax.inject.Inject + +class ChatBotRepositoryImpl @Inject constructor( + private val networkChatBotDataSource: NetworkChatBotDataSource, +) : ChatBotRepository { + override suspend fun askQuestion(question: String): String { + return networkChatBotDataSource.askQuestion( + request = ChatBotQuestionRequest(question = question), + ).answer + } +} From f16eeef52bf8e5b68e329cb542cb91b283752e9a Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:01:34 +0900 Subject: [PATCH 38/65] =?UTF-8?q?feat=20::=20Repository=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/chatbot/di/ChatBotDataModule.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 data/src/main/kotlin/team/aliens/dms/android/data/chatbot/di/ChatBotDataModule.kt diff --git a/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/di/ChatBotDataModule.kt b/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/di/ChatBotDataModule.kt new file mode 100644 index 000000000..0a6b84702 --- /dev/null +++ b/data/src/main/kotlin/team/aliens/dms/android/data/chatbot/di/ChatBotDataModule.kt @@ -0,0 +1,19 @@ +package team.aliens.dms.android.data.chatbot.di + +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import team.aliens.dms.android.data.chatbot.repository.ChatBotRepository +import team.aliens.dms.android.data.chatbot.repository.ChatBotRepositoryImpl +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal abstract class ChatBotDataModule { + @Binds + @Singleton + abstract fun bindChatBotRepository( + chatBotRepositoryImpl: ChatBotRepositoryImpl, + ): ChatBotRepository +} From c5af8fcd438668bb5747a76b1e87a2e394bc5151 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:02:44 +0900 Subject: [PATCH 39/65] =?UTF-8?q?feat=20::=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EC=A0=84=EC=86=A1=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatbot/viewmodel/ChatBotViewModel.kt | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt index ab9e84eb1..d9727983b 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt @@ -1,11 +1,69 @@ package team.aliens.dms.android.feature.chatbot.viewmodel import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import team.aliens.dms.android.data.chatbot.repository.ChatBotRepository +import javax.inject.Inject -internal class ChatBotViewModel : ViewModel() { +@HiltViewModel +internal class ChatBotViewModel @Inject constructor( + private val chatBotRepository: ChatBotRepository, +) : ViewModel() { private val _state = MutableStateFlow(ChatBotState()) val state: StateFlow = _state.asStateFlow() + + fun onInputChange(input: String) { + _state.update { + it.copy(input = input) + } + } + + fun sendQuestion() { + val question = state.value.input.trim() + + if (question.isEmpty() || state.value.isLoading) return + + viewModelScope.launch { + _state.update { + it.copy( + input = "", + isLoading = true, + messages = it.messages + ChatBotMessage( + text = question, + isUser = true, + ), + ) + } + + runCatching { + chatBotRepository.askQuestion(question) + }.onSuccess { answer -> + _state.update { + it.copy( + isLoading = false, + messages = it.messages + ChatBotMessage( + text = answer, + isUser = false, + ), + ) + } + }.onFailure { + _state.update { + it.copy( + isLoading = false, + messages = it.messages + ChatBotMessage( + text = "답변을 불러오지 못했어요. 잠시 후 다시 시도해 주세요.", + isUser = false, + ), + ) + } + } + } + } } From 0f4c057dc00ca19ccf4278dce7a1bd08d68a369a Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:04:21 +0900 Subject: [PATCH 40/65] =?UTF-8?q?feat=20::=20=EC=B1=97=EB=B4=87=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 114 ++++++++++++++++-- 1 file changed, 104 insertions(+), 10 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 23a3a251d..3927ea4b9 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -10,22 +10,47 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign 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 team.aliens.dms.android.core.designsystem.DmsTheme import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotInputBar +import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotMessageBubble import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotSuggestionChip +import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotTypingBubble +import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotMessage +import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotState +import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotViewModel @Composable -fun ChatBotRoute() { - ChatBotScreen() +fun ChatBotRoute( + viewModel: ChatBotViewModel = hiltViewModel(), +) { + val state by viewModel.state.collectAsStateWithLifecycle() + + ChatBotScreen( + state = state, + onInputChange = viewModel::onInputChange, + onSendClick = viewModel::sendQuestion, + onSuggestionClick = { question -> + viewModel.onInputChange(question) + viewModel.sendQuestion() + }, + ) } @Composable -private fun ChatBotScreen() { +private fun ChatBotScreen( + state: ChatBotState, + onInputChange: (String) -> Unit, + onSendClick: () -> Unit, + onSuggestionClick: (String) -> Unit, +) { Box( modifier = Modifier .fillMaxSize() @@ -40,10 +65,23 @@ private fun ChatBotScreen() { horizontalAlignment = Alignment.CenterHorizontally, ) { ChatBotHeader() - ChatBotSuggestionQuestions() + + if (state.messages.isEmpty() && !state.isLoading) { + ChatBotSuggestionQuestions( + onSuggestionClick = onSuggestionClick, + ) + } else { + ChatBotMessages( + messages = state.messages, + isLoading = state.isLoading, + ) + } } ChatBotInputBar( + value = state.input, + onValueChange = onInputChange, + onSendClick = onSendClick, modifier = Modifier .align(Alignment.BottomCenter) .padding( @@ -79,16 +117,63 @@ private fun ChatBotHeader() { } @Composable -private fun ChatBotSuggestionQuestions() { +private fun ChatBotSuggestionQuestions( + onSuggestionClick: (String) -> Unit, +) { + val suggestions = listOf( + "외출 신청은 언제까지 해야 해?", + "점호 시간 알려줘", + "세탁실 이용 시간이 궁금해", + "벌점 기준 알려줘", + ) + Column( modifier = Modifier.padding(top = 46.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp), ) { - ChatBotSuggestionChip("외출 신청은 언제까지 해야 해?") - ChatBotSuggestionChip("점호 시간 알려줘") - ChatBotSuggestionChip("세탁실 이용 시간이 궁금해") - ChatBotSuggestionChip("벌점 기준 알려줘") + suggestions.forEach { suggestion -> + ChatBotSuggestionChip( + text = suggestion, + onClick = { onSuggestionClick(suggestion) }, + ) + } + } +} + +@Composable +private fun ChatBotMessages( + messages: List, + isLoading: Boolean, +) { + Column( + modifier = Modifier.padding(top = 52.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + ) { + messages.forEach { message -> + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = if (message.isUser) { + Alignment.TopEnd + } else { + Alignment.TopStart + }, + ) { + ChatBotMessageBubble( + text = message.text, + isUser = message.isUser, + ) + } + } + + if (isLoading) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.TopStart, + ) { + ChatBotTypingBubble() + } + } } } @@ -101,6 +186,15 @@ private fun ChatBotSuggestionQuestions() { @Composable fun ChatBotScreenPreview() { DmsTheme(isDarkTheme = false) { - ChatBotScreen() + ChatBotScreen( + state = ChatBotState( + input = "", + messages = emptyList(), + isLoading = false, + ), + onInputChange = {}, + onSendClick = {}, + onSuggestionClick = {}, + ) } } From d0031d63409058ffdebc588f3c959b0b249e8b7f Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:05:05 +0900 Subject: [PATCH 41/65] =?UTF-8?q?feat=20::=20=EC=B6=94=EC=B2=9C=20?= =?UTF-8?q?=EC=A7=88=EB=AC=B8=20=ED=81=B4=EB=A6=AD=20=EC=9D=B4=EB=B2=A4?= =?UTF-8?q?=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 --- .../feature/chatbot/ui/component/ChatBotSuggestionChip.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt index 7f88d791c..0841e3f6b 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotSuggestionChip.kt @@ -1,5 +1,6 @@ package team.aliens.dms.android.feature.chatbot.ui.component +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Surface @@ -14,15 +15,16 @@ import team.aliens.dms.android.core.designsystem.DmsTheme @Composable internal fun ChatBotSuggestionChip( text: String, + onClick: () -> Unit, modifier: Modifier = Modifier, ) { Surface( - modifier = modifier, + modifier = modifier.clickable(onClick = onClick), shape = RoundedCornerShape(12.dp), color = DmsTheme.colorScheme.surfaceTint, ) { Text( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), + modifier = Modifier.padding(horizontal = 22.dp, vertical = 14.dp), text = text, color = DmsTheme.colorScheme.surfaceBright, style = DmsTheme.typography.body3, From e018d6c7e2869908f18bf5bcb77a678644ba37a3 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:06:12 +0900 Subject: [PATCH 42/65] =?UTF-8?q?feat=20::=20=EC=9E=85=EB=A0=A5=EC=B0=BD?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatbot/ui/component/ChatBotInputBar.kt | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index 69919ce77..8806a1d46 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -8,6 +8,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.clickable import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -20,12 +22,15 @@ import team.aliens.dms.android.core.designsystem.DmsTheme @Composable internal fun ChatBotInputBar( + value: String, + onValueChange: (String) -> Unit, + onSendClick: () -> Unit, modifier: Modifier = Modifier, ) { Surface( modifier = modifier .fillMaxWidth() - .shadow(4.dp, RoundedCornerShape(28.dp)), + .shadow(12.dp, RoundedCornerShape(28.dp)), shape = RoundedCornerShape(28.dp), color = DmsTheme.colorScheme.surfaceTint, ) { @@ -38,19 +43,39 @@ internal fun ChatBotInputBar( ), verticalAlignment = Alignment.CenterVertically, ) { - Text( - text = "DMS AI에게 질문해 보세요...", - color = DmsTheme.colorScheme.inverseOnSurface, - style = DmsTheme.typography.body3, - fontWeight = FontWeight.Normal, - ) + Box( + modifier = Modifier.weight(1f), + contentAlignment = Alignment.CenterStart, + ) { + if (value.isEmpty()) { + Text( + text = "DMS AI에게 질문해 보세요...", + color = DmsTheme.colorScheme.inverseOnSurface, + style = DmsTheme.typography.body3, + fontWeight = FontWeight.Normal, + ) + } + + BasicTextField( + value = value, + onValueChange = onValueChange, + textStyle = DmsTheme.typography.body3.copy( + color = DmsTheme.colorScheme.surfaceBright, + fontWeight = FontWeight.Normal, + ), + singleLine = true, + modifier = Modifier.fillMaxWidth(), + ) + } - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.size(8.dp)) Surface( - modifier = Modifier.size(40.dp), + modifier = Modifier + .size(40.dp) + .clickable(onClick = onSendClick), shape = CircleShape, - color = DmsTheme.colorScheme.onPrimaryContainer, + color = DmsTheme.colorScheme.secondary, ) { Box(contentAlignment = Alignment.Center) { Text( From 99ce764247763fa3caa595aaea7626a1423b1a44 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:10:52 +0900 Subject: [PATCH 43/65] =?UTF-8?q?fix=20::=20Route=20ViewModel=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 3927ea4b9..2d6a0731b 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -27,10 +27,10 @@ import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotMessage import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotState import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotViewModel + @Composable -fun ChatBotRoute( - viewModel: ChatBotViewModel = hiltViewModel(), -) { +fun ChatBotRoute() { + val viewModel: ChatBotViewModel = hiltViewModel() val state by viewModel.state.collectAsStateWithLifecycle() ChatBotScreen( From 19a502e16311123b59df14a67bdcd5288ae19f85 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:12:10 +0900 Subject: [PATCH 44/65] =?UTF-8?q?fix=20::=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EB=A7=90=ED=92=8D=EC=84=A0=20=EC=A0=95=EB=A0=AC=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 --- .../android/feature/chatbot/ui/ChatBotScreen.kt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 2d6a0731b..ab5571d79 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Arrangement 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.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding @@ -147,16 +148,18 @@ private fun ChatBotMessages( isLoading: Boolean, ) { Column( - modifier = Modifier.padding(top = 52.dp), + modifier = Modifier + .fillMaxWidth() + .padding(top = 52.dp), verticalArrangement = Arrangement.spacedBy(16.dp), ) { messages.forEach { message -> Box( - modifier = Modifier.fillMaxSize(), + modifier = Modifier.fillMaxWidth(), contentAlignment = if (message.isUser) { - Alignment.TopEnd + Alignment.CenterEnd } else { - Alignment.TopStart + Alignment.CenterStart }, ) { ChatBotMessageBubble( @@ -168,8 +171,8 @@ private fun ChatBotMessages( if (isLoading) { Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.TopStart, + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.CenterStart, ) { ChatBotTypingBubble() } @@ -177,6 +180,7 @@ private fun ChatBotMessages( } } + @Preview( name = "ChatBot Screen", showBackground = true, From 96b8c0943ee0e2bf342a307d4216c5d9f6a13c1c Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:14:13 +0900 Subject: [PATCH 45/65] =?UTF-8?q?feat=20::=20=EC=9E=85=EB=A0=A5=EC=B0=BD?= =?UTF-8?q?=20=ED=82=A4=EB=B3=B4=EB=93=9C=20=EC=A0=84=EC=86=A1=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dms/android/feature/chatbot/ui/ChatBotScreen.kt | 1 - .../feature/chatbot/ui/component/ChatBotInputBar.kt | 13 ++++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index ab5571d79..c7a399b47 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -180,7 +180,6 @@ private fun ChatBotMessages( } } - @Preview( name = "ChatBot Screen", showBackground = true, diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index 8806a1d46..f636fc14a 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -1,5 +1,6 @@ package team.aliens.dms.android.feature.chatbot.ui.component +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -9,7 +10,8 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.clickable +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -17,6 +19,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import team.aliens.dms.android.core.designsystem.DmsTheme @@ -64,6 +67,14 @@ internal fun ChatBotInputBar( fontWeight = FontWeight.Normal, ), singleLine = true, + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Send, + ), + keyboardActions = KeyboardActions( + onSend = { + onSendClick() + }, + ), modifier = Modifier.fillMaxWidth(), ) } From 7d5bf52e7e39a43b7be9f3a00c9a273fd0460fc9 Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:17:33 +0900 Subject: [PATCH 46/65] =?UTF-8?q?fix=20::=20=EC=B1=97=EB=B4=87=20=EC=A7=88?= =?UTF-8?q?=EB=AC=B8=20=EC=A4=91=EB=B3=B5=20=EC=A0=84=EC=86=A1=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dms/android/feature/chatbot/ui/ChatBotScreen.kt | 1 + .../feature/chatbot/ui/component/ChatBotInputBar.kt | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index c7a399b47..c300e0dff 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -83,6 +83,7 @@ private fun ChatBotScreen( value = state.input, onValueChange = onInputChange, onSendClick = onSendClick, + enabled = !state.isLoading, modifier = Modifier .align(Alignment.BottomCenter) .padding( diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index f636fc14a..a0a080f82 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -29,6 +29,7 @@ internal fun ChatBotInputBar( onValueChange: (String) -> Unit, onSendClick: () -> Unit, modifier: Modifier = Modifier, + enabled: Boolean = true, ) { Surface( modifier = modifier @@ -62,6 +63,7 @@ internal fun ChatBotInputBar( BasicTextField( value = value, onValueChange = onValueChange, + enabled = enabled, textStyle = DmsTheme.typography.body3.copy( color = DmsTheme.colorScheme.surfaceBright, fontWeight = FontWeight.Normal, @@ -72,7 +74,9 @@ internal fun ChatBotInputBar( ), keyboardActions = KeyboardActions( onSend = { - onSendClick() + if (enabled) { + onSendClick() + } }, ), modifier = Modifier.fillMaxWidth(), @@ -84,7 +88,10 @@ internal fun ChatBotInputBar( Surface( modifier = Modifier .size(40.dp) - .clickable(onClick = onSendClick), + .clickable( + enabled = enabled, + onClick = onSendClick, + ), shape = CircleShape, color = DmsTheme.colorScheme.secondary, ) { From 6415307b0df59ae42062ca6eb269f9bc6fc6193b Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:20:33 +0900 Subject: [PATCH 47/65] =?UTF-8?q?feat=20::=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=20=EB=AA=A9=EB=A1=9D=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index c300e0dff..c1835e794 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -9,6 +9,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -148,13 +150,13 @@ private fun ChatBotMessages( messages: List, isLoading: Boolean, ) { - Column( + LazyColumn( modifier = Modifier .fillMaxWidth() - .padding(top = 52.dp), + .padding(top = 52.dp, bottom = 120.dp), verticalArrangement = Arrangement.spacedBy(16.dp), ) { - messages.forEach { message -> + items(messages) { message -> Box( modifier = Modifier.fillMaxWidth(), contentAlignment = if (message.isUser) { @@ -171,11 +173,13 @@ private fun ChatBotMessages( } if (isLoading) { - Box( - modifier = Modifier.fillMaxWidth(), - contentAlignment = Alignment.CenterStart, - ) { - ChatBotTypingBubble() + item { + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.CenterStart, + ) { + ChatBotTypingBubble() + } } } } From 921819dfbc8012c4b2d70c7cd9e9a04aa3ea19be Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:21:47 +0900 Subject: [PATCH 48/65] =?UTF-8?q?feat=20::=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EC=A0=84=EC=86=A1=20=EC=8B=9C=20=ED=82=A4=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=88=A8=EA=B9=80=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dms/android/feature/chatbot/ui/ChatBotScreen.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index c1835e794..c9811d0be 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -16,6 +16,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -35,12 +36,17 @@ import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotViewModel fun ChatBotRoute() { val viewModel: ChatBotViewModel = hiltViewModel() val state by viewModel.state.collectAsStateWithLifecycle() + val keyboardController = LocalSoftwareKeyboardController.current ChatBotScreen( state = state, onInputChange = viewModel::onInputChange, - onSendClick = viewModel::sendQuestion, + onSendClick = { + keyboardController?.hide() + viewModel.sendQuestion() + }, onSuggestionClick = { question -> + keyboardController?.hide() viewModel.onInputChange(question) viewModel.sendQuestion() }, From 15e96fa0ac764568a7001ddcdfaee8e647b1e4fb Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:29:35 +0900 Subject: [PATCH 49/65] =?UTF-8?q?fix=20::=20=EC=B1=97=EB=B4=87=20API=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20Retrofit=20=EC=A3=BC=EC=9E=85=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 --- .../dms/android/network/chatbot/di/ChatBotNetworkModule.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt index 323cfdb6b..83024f286 100644 --- a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt +++ b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt @@ -6,6 +6,7 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import retrofit2.Retrofit +import team.aliens.dms.android.core.network.di.DefaultRetrofitClient import team.aliens.dms.android.network.chatbot.apiservice.ChatBotApiService import team.aliens.dms.android.network.chatbot.datasource.NetworkChatBotDataSource import team.aliens.dms.android.network.chatbot.datasource.NetworkChatBotDataSourceImpl @@ -24,7 +25,7 @@ internal abstract class ChatBotNetworkModule { @Provides @Singleton fun provideChatBotApiService( - retrofit: Retrofit, + @DefaultRetrofitClient retrofit: Retrofit, ): ChatBotApiService { return retrofit.create(ChatBotApiService::class.java) } From b9f7cfd1844f5a2d75688a7feb7f00cfc4974dde Mon Sep 17 00:00:00 2001 From: ashxom Date: Fri, 3 Jul 2026 10:57:22 +0900 Subject: [PATCH 50/65] =?UTF-8?q?fix=20::=20=ED=95=98=EB=8B=A8=EB=B0=94=20?= =?UTF-8?q?=ED=83=AD=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20=EB=8C=80=EC=83=81?= =?UTF-8?q?=20=ED=99=94=EB=A9=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dms/android/app/navigation/BottomNavigationBar.kt | 6 ++++-- .../main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt | 9 +++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomNavigationBar.kt b/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomNavigationBar.kt index a81b974c4..580170834 100644 --- a/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomNavigationBar.kt +++ b/app/src/main/kotlin/team/aliens/dms/android/app/navigation/BottomNavigationBar.kt @@ -52,9 +52,11 @@ fun BottomNavigationBar( NavigationBarItem( selected = selected, - enabled = !selected, + enabled = true, onClick = { - onNavigate(destination.route) + if (!selected) { + onNavigate(destination.route) + } }, colors = NavigationBarItemDefaults.colors( indicatorColor = Color.Transparent, diff --git a/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt b/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt index 31955978e..d64530e14 100644 --- a/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt +++ b/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt @@ -133,16 +133,13 @@ fun DmsApp( currentScreen = currentScreen.toString(), onNavigate = { destination -> if (currentScreen != destination) { - when (destination) { - is HomeScreenNav -> { - backStack.remove(HomeScreenNav) - } - } backStack.removeAll { - it is ApplicationScreenNav || + it is HomeScreenNav || + it is ApplicationScreenNav || it is ChatBotScreenNav || it is MyPageScreenNav } + backStack.add(destination) } } ) From bc949a570e3450b43e722ccf852069f1df30f9e5 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 15:14:53 +0900 Subject: [PATCH 51/65] =?UTF-8?q?fix=20::=20=EC=B1=97=EB=B4=87=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=B0=BD=20=ED=82=A4=EB=B3=B4=EB=93=9C=20=EB=8C=80?= =?UTF-8?q?=EC=9D=91=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 188 ++++++++++-------- .../chatbot/ui/component/ChatBotInputBar.kt | 2 +- 2 files changed, 109 insertions(+), 81 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index c9811d0be..c0ad71bf6 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -4,19 +4,23 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -31,24 +35,22 @@ import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotMessage import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotState import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotViewModel - @Composable fun ChatBotRoute() { val viewModel: ChatBotViewModel = hiltViewModel() val state by viewModel.state.collectAsStateWithLifecycle() - val keyboardController = LocalSoftwareKeyboardController.current + val focusManager = LocalFocusManager.current ChatBotScreen( state = state, onInputChange = viewModel::onInputChange, onSendClick = { - keyboardController?.hide() viewModel.sendQuestion() }, onSuggestionClick = { question -> - keyboardController?.hide() viewModel.onInputChange(question) viewModel.sendQuestion() + focusManager.clearFocus() }, ) } @@ -60,30 +62,63 @@ private fun ChatBotScreen( onSendClick: () -> Unit, onSuggestionClick: (String) -> Unit, ) { + val density = LocalDensity.current + val isKeyboardVisible = WindowInsets.ime.getBottom(density) > 0 + val listState = rememberLazyListState() + + LaunchedEffect(state.messages.size, state.isLoading) { + if (state.messages.isNotEmpty() || state.isLoading) { + listState.animateScrollToItem( + index = state.messages.size + if (state.isLoading) 1 else 0, + ) + } + } + Box( modifier = Modifier .fillMaxSize() .background(DmsTheme.colorScheme.background) - .statusBarsPadding() - .navigationBarsPadding(), + .statusBarsPadding(), ) { - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - ChatBotHeader() - - if (state.messages.isEmpty() && !state.isLoading) { + if (state.messages.isEmpty() && !isKeyboardVisible) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + ChatBotHeader() ChatBotSuggestionQuestions( onSuggestionClick = onSuggestionClick, ) - } else { - ChatBotMessages( - messages = state.messages, - isLoading = state.isLoading, - ) + } + } else { + LazyColumn( + state = listState, + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 20.dp), + contentPadding = PaddingValues( + top = if (isKeyboardVisible) 72.dp else 120.dp, + bottom = if (isKeyboardVisible) 88.dp else 208.dp, + ), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + item { + ChatBotCompactHeader() + } + + state.messages.forEach { message -> + item { + ChatBotMessageItem(message = message) + } + } + + if (state.isLoading) { + item { + ChatBotTypingBubble() + } + } } } @@ -94,10 +129,14 @@ private fun ChatBotScreen( enabled = !state.isLoading, modifier = Modifier .align(Alignment.BottomCenter) + .padding(horizontal = 20.dp) + .imePadding() .padding( - start = 20.dp, - end = 20.dp, - bottom = 112.dp, + bottom = if (isKeyboardVisible) { + 0.dp + } else { + 112.dp + }, ), ) } @@ -126,68 +165,61 @@ private fun ChatBotHeader() { } } +@Composable +private fun ChatBotCompactHeader() { + Text( + modifier = Modifier.padding(top = 8.dp), + text = "외출, 점호, 벌점, 세탁실 이용 등 기숙사 규정을 AI\n가 빠르고 정확하게 안내해 드립니다.", + color = DmsTheme.colorScheme.inverseSurface, + style = DmsTheme.typography.body3, + textAlign = TextAlign.Center, + ) +} + @Composable private fun ChatBotSuggestionQuestions( onSuggestionClick: (String) -> Unit, ) { - val suggestions = listOf( - "외출 신청은 언제까지 해야 해?", - "점호 시간 알려줘", - "세탁실 이용 시간이 궁금해", - "벌점 기준 알려줘", - ) - Column( modifier = Modifier.padding(top = 46.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp), ) { - suggestions.forEach { suggestion -> - ChatBotSuggestionChip( - text = suggestion, - onClick = { onSuggestionClick(suggestion) }, - ) - } + ChatBotSuggestionChip( + text = "외출 신청은 언제까지 해야 해?", + onClick = { onSuggestionClick("외출 신청은 언제까지 해야 해?") }, + ) + ChatBotSuggestionChip( + text = "점호 시간 알려줘", + onClick = { onSuggestionClick("점호 시간 알려줘") }, + ) + ChatBotSuggestionChip( + text = "세탁실 이용 시간이 궁금해", + onClick = { onSuggestionClick("세탁실 이용 시간이 궁금해") }, + ) + ChatBotSuggestionChip( + text = "벌점 기준 알려줘", + onClick = { onSuggestionClick("벌점 기준 알려줘") }, + ) } } @Composable -private fun ChatBotMessages( - messages: List, - isLoading: Boolean, +private fun ChatBotMessageItem( + message: ChatBotMessage, ) { - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .padding(top = 52.dp, bottom = 120.dp), - verticalArrangement = Arrangement.spacedBy(16.dp), + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = if (message.isUser) { + Alignment.CenterEnd + } else { + Alignment.CenterStart + }, ) { - items(messages) { message -> - Box( - modifier = Modifier.fillMaxWidth(), - contentAlignment = if (message.isUser) { - Alignment.CenterEnd - } else { - Alignment.CenterStart - }, - ) { - ChatBotMessageBubble( - text = message.text, - isUser = message.isUser, - ) - } - } - - if (isLoading) { - item { - Box( - modifier = Modifier.fillMaxWidth(), - contentAlignment = Alignment.CenterStart, - ) { - ChatBotTypingBubble() - } - } - } + ChatBotMessageBubble( + text = message.text, + isUser = message.isUser, + ) } } @@ -198,14 +230,10 @@ private fun ChatBotMessages( heightDp = 812, ) @Composable -fun ChatBotScreenPreview() { +private fun ChatBotScreenPreview() { DmsTheme(isDarkTheme = false) { ChatBotScreen( - state = ChatBotState( - input = "", - messages = emptyList(), - isLoading = false, - ), + state = ChatBotState(), onInputChange = {}, onSendClick = {}, onSuggestionClick = {}, diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index a0a080f82..0824b4b94 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -93,7 +93,7 @@ internal fun ChatBotInputBar( onClick = onSendClick, ), shape = CircleShape, - color = DmsTheme.colorScheme.secondary, + color = DmsTheme.colorScheme.onPrimaryContainer, ) { Box(contentAlignment = Alignment.Center) { Text( From 4a3bb07f00897753b753674eec318fb23d61b0cb Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 15:19:42 +0900 Subject: [PATCH 52/65] =?UTF-8?q?fix=20::=20=EC=B1=97=EB=B4=87=20=EC=95=88?= =?UTF-8?q?=EB=82=B4=20=EB=AC=B8=EA=B5=AC=20=EC=A4=91=EC=95=99=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index c0ad71bf6..1685f6431 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -5,10 +5,8 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.ime -import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.LazyColumn @@ -17,9 +15,12 @@ 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.platform.LocalDensity +import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -62,8 +63,7 @@ private fun ChatBotScreen( onSendClick: () -> Unit, onSuggestionClick: (String) -> Unit, ) { - val density = LocalDensity.current - val isKeyboardVisible = WindowInsets.ime.getBottom(density) > 0 + var isInputFocused by remember { mutableStateOf(false) } val listState = rememberLazyListState() LaunchedEffect(state.messages.size, state.isLoading) { @@ -80,7 +80,7 @@ private fun ChatBotScreen( .background(DmsTheme.colorScheme.background) .statusBarsPadding(), ) { - if (state.messages.isEmpty() && !isKeyboardVisible) { + if (state.messages.isEmpty() && !isInputFocused) { Column( modifier = Modifier .fillMaxSize() @@ -99,10 +99,11 @@ private fun ChatBotScreen( .fillMaxSize() .padding(horizontal = 20.dp), contentPadding = PaddingValues( - top = if (isKeyboardVisible) 72.dp else 120.dp, - bottom = if (isKeyboardVisible) 88.dp else 208.dp, + top = 72.dp, + bottom = if (isInputFocused) 76.dp else 208.dp, ), verticalArrangement = Arrangement.spacedBy(12.dp), + horizontalAlignment = Alignment.CenterHorizontally, ) { item { ChatBotCompactHeader() @@ -129,15 +130,18 @@ private fun ChatBotScreen( enabled = !state.isLoading, modifier = Modifier .align(Alignment.BottomCenter) - .padding(horizontal = 20.dp) - .imePadding() .padding( - bottom = if (isKeyboardVisible) { + start = 20.dp, + end = 20.dp, + bottom = if (isInputFocused) { 0.dp } else { 112.dp }, - ), + ) + .onFocusChanged { focusState -> + isInputFocused = focusState.hasFocus + }, ) } } @@ -156,7 +160,9 @@ private fun ChatBotHeader() { ) Text( - modifier = Modifier.padding(top = 22.dp), + modifier = Modifier + .fillMaxWidth() + .padding(top = 22.dp), text = "외출, 점호, 벌점, 세탁실 이용 등 기숙사 규정을 AI\n가 빠르고 정확하게 안내해 드립니다.", color = DmsTheme.colorScheme.inverseSurface, style = DmsTheme.typography.body3, @@ -168,7 +174,9 @@ private fun ChatBotHeader() { @Composable private fun ChatBotCompactHeader() { Text( - modifier = Modifier.padding(top = 8.dp), + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), text = "외출, 점호, 벌점, 세탁실 이용 등 기숙사 규정을 AI\n가 빠르고 정확하게 안내해 드립니다.", color = DmsTheme.colorScheme.inverseSurface, style = DmsTheme.typography.body3, @@ -209,7 +217,7 @@ private fun ChatBotMessageItem( message: ChatBotMessage, ) { Box( - modifier = Modifier.fillMaxSize(), + modifier = Modifier.fillMaxWidth(), contentAlignment = if (message.isUser) { Alignment.CenterEnd } else { From bee28e9be81f124a2202f2442db93cb97293cdca Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 19:28:15 +0900 Subject: [PATCH 53/65] =?UTF-8?q?fix=20::=20=EC=B1=97=EB=B4=87=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=B0=BD=20=ED=82=A4=EB=B3=B4=EB=93=9C=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EC=B2=98=EB=A6=AC=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 20 +++++++++++-------- .../chatbot/ui/component/ChatBotInputBar.kt | 8 +++++++- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 1685f6431..497efb4da 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.LazyColumn @@ -20,7 +21,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -100,7 +100,11 @@ private fun ChatBotScreen( .padding(horizontal = 20.dp), contentPadding = PaddingValues( top = 72.dp, - bottom = if (isInputFocused) 76.dp else 208.dp, + bottom = if (isInputFocused) { + 76.dp + } else { + 208.dp + }, ), verticalArrangement = Arrangement.spacedBy(12.dp), horizontalAlignment = Alignment.CenterHorizontally, @@ -128,20 +132,20 @@ private fun ChatBotScreen( onValueChange = onInputChange, onSendClick = onSendClick, enabled = !state.isLoading, + onFocusChanged = { focused -> + isInputFocused = focused + }, modifier = Modifier .align(Alignment.BottomCenter) + .padding(horizontal = 20.dp) + .imePadding() .padding( - start = 20.dp, - end = 20.dp, bottom = if (isInputFocused) { 0.dp } else { 112.dp }, - ) - .onFocusChanged { focusState -> - isInputFocused = focusState.hasFocus - }, + ), ) } } diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index 0824b4b94..2e027ec76 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow +import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp @@ -30,6 +31,7 @@ internal fun ChatBotInputBar( onSendClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, + onFocusChanged: (Boolean) -> Unit = {}, ) { Surface( modifier = modifier @@ -79,7 +81,11 @@ internal fun ChatBotInputBar( } }, ), - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .fillMaxWidth() + .onFocusChanged { focusState -> + onFocusChanged(focusState.hasFocus) + }, ) } From a47dc31f125ecb8496d95ba8d2299937d4f2303d Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 19:40:33 +0900 Subject: [PATCH 54/65] =?UTF-8?q?feat=20::=20=EC=9E=85=EB=A0=A5=EC=B0=BD?= =?UTF-8?q?=20=EC=83=81=EC=9C=84=EB=A1=9C=20=EC=A0=84=EB=8B=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=BD=9C=EB=B0=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/feature/chatbot/ui/ChatBotScreen.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 497efb4da..ecb3ec36f 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -37,7 +37,9 @@ import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotState import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotViewModel @Composable -fun ChatBotRoute() { +fun ChatBotRoute( + onInputFocusChanged: (Boolean) -> Unit = {}, +) { val viewModel: ChatBotViewModel = hiltViewModel() val state by viewModel.state.collectAsStateWithLifecycle() val focusManager = LocalFocusManager.current @@ -53,6 +55,7 @@ fun ChatBotRoute() { viewModel.sendQuestion() focusManager.clearFocus() }, + onInputFocusChanged = onInputFocusChanged, ) } @@ -62,6 +65,7 @@ private fun ChatBotScreen( onInputChange: (String) -> Unit, onSendClick: () -> Unit, onSuggestionClick: (String) -> Unit, + onInputFocusChanged: (Boolean) -> Unit = {}, ) { var isInputFocused by remember { mutableStateOf(false) } val listState = rememberLazyListState() @@ -100,11 +104,7 @@ private fun ChatBotScreen( .padding(horizontal = 20.dp), contentPadding = PaddingValues( top = 72.dp, - bottom = if (isInputFocused) { - 76.dp - } else { - 208.dp - }, + bottom = 96.dp, ), verticalArrangement = Arrangement.spacedBy(12.dp), horizontalAlignment = Alignment.CenterHorizontally, @@ -134,12 +134,14 @@ private fun ChatBotScreen( enabled = !state.isLoading, onFocusChanged = { focused -> isInputFocused = focused + onInputFocusChanged(focused) }, modifier = Modifier .align(Alignment.BottomCenter) - .padding(horizontal = 20.dp) .imePadding() .padding( + start = 20.dp, + end = 20.dp, bottom = if (isInputFocused) { 0.dp } else { From c6e9e7fcf0fa01aed9afa564d228e4b1a7c68922 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 19:40:53 +0900 Subject: [PATCH 55/65] =?UTF-8?q?fix=20::=20=EC=9E=85=EB=A0=A5=EC=B0=BD=20?= =?UTF-8?q?=ED=8F=AC=EC=BB=A4=EC=8A=A4=20=EC=8B=9C=20=EB=84=A4=EB=B9=84?= =?UTF-8?q?=EA=B2=8C=EC=9D=B4=EC=85=98=20=EB=B0=94=20=EC=88=A8=EA=B9=80=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/team/aliens/dms/android/app/ui/DmsApp.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt b/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt index d64530e14..c3ceeb8d8 100644 --- a/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt +++ b/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt @@ -13,6 +13,9 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState 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.unit.dp @@ -99,13 +102,14 @@ fun DmsApp( val backStack = rememberNavBackStack(OnboardingScreenNav) val resultStore = rememberResultStore() + var isChatInputFocused by remember { mutableStateOf(false) } val currentScreen = backStack.lastOrNull() val shouldShowBottomBar = currentScreen in listOf( HomeScreenNav, ApplicationScreenNav, ChatBotScreenNav, MyPageScreenNav, - ) + ) && !(currentScreen == ChatBotScreenNav && isChatInputFocused) LaunchedEffect(isStartupResolved, isOnboardingCompleted, isJwtAvailable) { if (!isStartupResolved) return@LaunchedEffect @@ -214,7 +218,11 @@ fun DmsApp( ) } entry { - ChatBotRoute() + ChatBotRoute( + onInputFocusChanged = { focused -> + isChatInputFocused = focused + }, + ) } entry { VoteRoute( From ce70603eceb29effa194c770c71a11b91593ad4b Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 19:44:26 +0900 Subject: [PATCH 56/65] =?UTF-8?q?style=20::=20=EC=9E=85=EB=A0=A5=EC=B0=BD?= =?UTF-8?q?=20=ED=82=A4=EB=B3=B4=EB=93=9C=20=EA=B0=84=EA=B2=A9=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index ecb3ec36f..4a7bf2309 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -143,7 +143,7 @@ private fun ChatBotScreen( start = 20.dp, end = 20.dp, bottom = if (isInputFocused) { - 0.dp + 12.dp } else { 112.dp }, From ac228454eed3132ba55cd3eb709b391f42d727a0 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 19:55:59 +0900 Subject: [PATCH 57/65] =?UTF-8?q?fix=20::=20=EC=B1=97=EB=B4=87=20API?= =?UTF-8?q?=EC=97=90=20=EC=9D=B8=EC=A6=9D=20Retrofit=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/viewmodel/ChatBotViewModel.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt index d9727983b..131c33d03 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt @@ -1,5 +1,6 @@ package team.aliens.dms.android.feature.chatbot.viewmodel +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -53,7 +54,13 @@ internal class ChatBotViewModel @Inject constructor( ), ) } - }.onFailure { + }.onFailure { throwable -> + Log.e( + "ChatBot", + "request failed: ${throwable::class.java.simpleName}, message=${throwable.message}", + throwable, + ) + _state.update { it.copy( isLoading = false, From 48d4069361127d5d44aa699421114113acaae58f Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 21:21:45 +0900 Subject: [PATCH 58/65] =?UTF-8?q?fix=20::=20=EC=B1=97=EB=B4=87=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=ED=95=98?= =?UTF-8?q?=EB=8B=A8=20=EC=97=AC=EB=B0=B1=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 4a7bf2309..7a02ecc52 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -74,6 +74,7 @@ private fun ChatBotScreen( if (state.messages.isNotEmpty() || state.isLoading) { listState.animateScrollToItem( index = state.messages.size + if (state.isLoading) 1 else 0, + scrollOffset = 120, ) } } @@ -104,7 +105,11 @@ private fun ChatBotScreen( .padding(horizontal = 20.dp), contentPadding = PaddingValues( top = 72.dp, - bottom = 96.dp, + bottom = if (isInputFocused) { + 120.dp + } else { + 320.dp + }, ), verticalArrangement = Arrangement.spacedBy(12.dp), horizontalAlignment = Alignment.CenterHorizontally, From 51b120867950c83afbc169f2b7d5b8c4b64bde45 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 21:22:41 +0900 Subject: [PATCH 59/65] =?UTF-8?q?fix=20::=20API=EC=97=90=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20Retrofit=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dms/android/network/chatbot/di/ChatBotNetworkModule.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt index 83024f286..bf641bb99 100644 --- a/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt +++ b/network/src/main/kotlin/team/aliens/dms/android/network/chatbot/di/ChatBotNetworkModule.kt @@ -6,7 +6,7 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import retrofit2.Retrofit -import team.aliens.dms.android.core.network.di.DefaultRetrofitClient +import team.aliens.dms.android.core.network.di.GlobalRetrofitClient import team.aliens.dms.android.network.chatbot.apiservice.ChatBotApiService import team.aliens.dms.android.network.chatbot.datasource.NetworkChatBotDataSource import team.aliens.dms.android.network.chatbot.datasource.NetworkChatBotDataSourceImpl @@ -25,7 +25,7 @@ internal abstract class ChatBotNetworkModule { @Provides @Singleton fun provideChatBotApiService( - @DefaultRetrofitClient retrofit: Retrofit, + @GlobalRetrofitClient retrofit: Retrofit, ): ChatBotApiService { return retrofit.create(ChatBotApiService::class.java) } From d879523458be55586c74e3fc153226f25a518553 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 21:32:15 +0900 Subject: [PATCH 60/65] =?UTF-8?q?fix=20::=20=EC=9E=85=EB=A0=A5=EC=B0=BD=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EB=B0=8F=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EC=97=AC=EB=B0=B1=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dms/android/feature/chatbot/ui/ChatBotScreen.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 7a02ecc52..e2ea02ead 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -74,7 +74,7 @@ private fun ChatBotScreen( if (state.messages.isNotEmpty() || state.isLoading) { listState.animateScrollToItem( index = state.messages.size + if (state.isLoading) 1 else 0, - scrollOffset = 120, + scrollOffset = 80, ) } } @@ -106,9 +106,9 @@ private fun ChatBotScreen( contentPadding = PaddingValues( top = 72.dp, bottom = if (isInputFocused) { - 120.dp + 112.dp } else { - 320.dp + 132.dp }, ), verticalArrangement = Arrangement.spacedBy(12.dp), @@ -150,7 +150,7 @@ private fun ChatBotScreen( bottom = if (isInputFocused) { 12.dp } else { - 112.dp + 16.dp }, ), ) From 4fee05d8aa89129a169bc6112245170c8cf17a96 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 21:41:43 +0900 Subject: [PATCH 61/65] =?UTF-8?q?fix=20::=20=EC=9E=85=EB=A0=A5=20=EC=A4=91?= =?UTF-8?q?=20=ED=91=9C=EC=8B=9C=20=EC=99=BC=EC=AA=BD=20=EC=A0=95=EB=A0=AC?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/feature/chatbot/ui/ChatBotScreen.kt | 14 ++++++++++++-- .../chatbot/ui/component/ChatBotTypingIndicator.kt | 10 +++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index e2ea02ead..e5e1f17ed 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -31,7 +31,7 @@ import team.aliens.dms.android.core.designsystem.DmsTheme import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotInputBar import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotMessageBubble import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotSuggestionChip -import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotTypingBubble +import team.aliens.dms.android.feature.chatbot.ui.component.ChatBotTypingIndicator import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotMessage import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotState import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotViewModel @@ -126,7 +126,7 @@ private fun ChatBotScreen( if (state.isLoading) { item { - ChatBotTypingBubble() + ChatBotTypingItem() } } } @@ -242,6 +242,16 @@ private fun ChatBotMessageItem( } } +@Composable +private fun ChatBotTypingItem() { + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.CenterStart, + ) { + ChatBotTypingIndicator() + } +} + @Preview( name = "ChatBot Screen", showBackground = true, diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotTypingIndicator.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotTypingIndicator.kt index c068f4234..dd67905ab 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotTypingIndicator.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotTypingIndicator.kt @@ -4,8 +4,10 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -14,7 +16,13 @@ import team.aliens.dms.android.core.designsystem.DmsTheme @Composable internal fun ChatBotTypingIndicator() { - Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { + Row( + modifier = Modifier + .clip(RoundedCornerShape(14.dp)) + .background(DmsTheme.colorScheme.surface) + .padding(horizontal = 18.dp, vertical = 14.dp), + horizontalArrangement = Arrangement.spacedBy(5.dp), + ) { repeat(3) { Box( modifier = Modifier From a49a1b07f7da9f11f54fd2cee60f684a39466f99 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 21:51:15 +0900 Subject: [PATCH 62/65] =?UTF-8?q?style=20::=20=EC=9E=85=EB=A0=A5=EC=B0=BD?= =?UTF-8?q?=20=EA=B7=B8=EB=A6=BC=EC=9E=90=20=EC=8A=A4=ED=83=80=EC=9D=BC=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/component/ChatBotInputBar.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index 2e027ec76..1c6d26c27 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp @@ -36,7 +37,12 @@ internal fun ChatBotInputBar( Surface( modifier = modifier .fillMaxWidth() - .shadow(12.dp, RoundedCornerShape(28.dp)), + .shadow( + elevation = 20.dp, + shape = RoundedCornerShape(28.dp), + ambientColor = Color.Black.copy(alpha = 0.20f), + spotColor = Color.Black.copy(alpha = 0.30f), + ), shape = RoundedCornerShape(28.dp), color = DmsTheme.colorScheme.surfaceTint, ) { From d61bfe524976c16ec3dd57ee7dcf2c5b48d0bda3 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 22:32:05 +0900 Subject: [PATCH 63/65] =?UTF-8?q?fix=20::=20=ED=8F=AC=EC=BB=A4=EC=8A=A4=20?= =?UTF-8?q?=EC=BD=9C=EB=B0=B1=20=EB=84=A4=EC=9D=B4=EB=B0=8D=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 --- .../kotlin/team/aliens/dms/android/app/ui/DmsApp.kt | 2 +- .../dms/android/feature/chatbot/ui/ChatBotScreen.kt | 10 +++++----- .../feature/chatbot/ui/component/ChatBotInputBar.kt | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt b/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt index c3ceeb8d8..189feaf79 100644 --- a/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt +++ b/app/src/main/kotlin/team/aliens/dms/android/app/ui/DmsApp.kt @@ -219,7 +219,7 @@ fun DmsApp( } entry { ChatBotRoute( - onInputFocusChanged = { focused -> + onInputFocusChange = { focused -> isChatInputFocused = focused }, ) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index e5e1f17ed..6a853ba19 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -38,7 +38,7 @@ import team.aliens.dms.android.feature.chatbot.viewmodel.ChatBotViewModel @Composable fun ChatBotRoute( - onInputFocusChanged: (Boolean) -> Unit = {}, + onInputFocusChange: (Boolean) -> Unit = {}, ) { val viewModel: ChatBotViewModel = hiltViewModel() val state by viewModel.state.collectAsStateWithLifecycle() @@ -55,7 +55,7 @@ fun ChatBotRoute( viewModel.sendQuestion() focusManager.clearFocus() }, - onInputFocusChanged = onInputFocusChanged, + onInputFocusChange = onInputFocusChange, ) } @@ -65,7 +65,7 @@ private fun ChatBotScreen( onInputChange: (String) -> Unit, onSendClick: () -> Unit, onSuggestionClick: (String) -> Unit, - onInputFocusChanged: (Boolean) -> Unit = {}, + onInputFocusChange: (Boolean) -> Unit = {}, ) { var isInputFocused by remember { mutableStateOf(false) } val listState = rememberLazyListState() @@ -137,9 +137,9 @@ private fun ChatBotScreen( onValueChange = onInputChange, onSendClick = onSendClick, enabled = !state.isLoading, - onFocusChanged = { focused -> + onFocusChange = { focused -> isInputFocused = focused - onInputFocusChanged(focused) + onInputFocusChange(focused) }, modifier = Modifier .align(Alignment.BottomCenter) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt index 1c6d26c27..a0922ecd9 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/component/ChatBotInputBar.kt @@ -32,7 +32,7 @@ internal fun ChatBotInputBar( onSendClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, - onFocusChanged: (Boolean) -> Unit = {}, + onFocusChange: (Boolean) -> Unit = {}, ) { Surface( modifier = modifier @@ -90,7 +90,7 @@ internal fun ChatBotInputBar( modifier = Modifier .fillMaxWidth() .onFocusChanged { focusState -> - onFocusChanged(focusState.hasFocus) + onFocusChange(focusState.hasFocus) }, ) } From a0cef4d89214282e9959df5a7dcd77b2de4b95a6 Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 22:34:21 +0900 Subject: [PATCH 64/65] =?UTF-8?q?chore=20::=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=20=EB=A1=9C=EA=B7=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/viewmodel/ChatBotViewModel.kt | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt index 131c33d03..d9727983b 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/viewmodel/ChatBotViewModel.kt @@ -1,6 +1,5 @@ package team.aliens.dms.android.feature.chatbot.viewmodel -import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -54,13 +53,7 @@ internal class ChatBotViewModel @Inject constructor( ), ) } - }.onFailure { throwable -> - Log.e( - "ChatBot", - "request failed: ${throwable::class.java.simpleName}, message=${throwable.message}", - throwable, - ) - + }.onFailure { _state.update { it.copy( isLoading = false, From 49f04fe8a4e734b6154260814db6f1cac504cc5c Mon Sep 17 00:00:00 2001 From: ashxom Date: Sun, 5 Jul 2026 22:36:20 +0900 Subject: [PATCH 65/65] =?UTF-8?q?chore=20::=20=ED=99=94=EB=A9=B4=20preview?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/chatbot/ui/ChatBotScreen.kt | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt index 6a853ba19..0d388226f 100644 --- a/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt +++ b/feature/src/main/kotlin/team/aliens/dms/android/feature/chatbot/ui/ChatBotScreen.kt @@ -23,7 +23,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -251,21 +250,3 @@ private fun ChatBotTypingItem() { ChatBotTypingIndicator() } } - -@Preview( - name = "ChatBot Screen", - showBackground = true, - widthDp = 375, - heightDp = 812, -) -@Composable -private fun ChatBotScreenPreview() { - DmsTheme(isDarkTheme = false) { - ChatBotScreen( - state = ChatBotState(), - onInputChange = {}, - onSendClick = {}, - onSuggestionClick = {}, - ) - } -}