Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 86 additions & 35 deletions feature/src/main/java/com/example/feature/MainScreen.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
package com.example.feature

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
Expand Down Expand Up @@ -52,7 +69,6 @@ import com.example.feature.ui.onboarding.screen.LanguageScreen
import com.example.feature.ui.onboarding.screen.LoginScreen
import com.example.feature.ui.splash.screen.SplashScreen

// 아이콘 리소스 구성 (기본 / 클릭)
data class NavItem(
val route: String,
val iconResId: Int,
Expand All @@ -68,55 +84,90 @@ val items = listOf(
NavItem("커뮤니티", R.drawable.ic_community, R.drawable.ic_community_click)
)

@Preview
@Composable
private fun preview() {
MyBottomNavigation(rememberNavController())
}

@Composable
fun MyBottomNavigation(navController: NavHostController) {
val currentDestination = navController.currentBackStackEntryAsState().value?.destination
val currentRoute = currentDestination?.route

NavigationBar(
containerColor = Color.White,
tonalElevation = 0.dp
// 바 전체 컨테이너 (둥글게 + 그림자 + 패딩)
Box(
modifier = Modifier
.fillMaxWidth()
.background(Color.White)
.navigationBarsPadding()
.height(60.dp)
) {
items.forEach { item ->
val isSelected = currentDestination?.route == item.route
val iconRes = if (isSelected) item.iconClickResId else item.iconResId
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 15.dp, end = 15.dp, bottom = 15.dp),
verticalAlignment = Alignment.CenterVertically
) {
items.forEach { item ->
val isSelected = currentRoute == item.route
val iconRes = if (isSelected) item.iconClickResId else item.iconResId

NavigationBarItem(
selected = isSelected,
onClick = {
if (!isSelected) {
if (item.route == "홈") {
// ✅ 홈으로 갈 때마다 전체 스택 초기화
navController.navigate("홈") {
popUpTo(0) { inclusive = true }
launchSingleTop = true
}
} else {
// 나머지 탭은 기존처럼 동작
navController.navigate(item.route) {
popUpTo(navController.graph.startDestinationId) {
saveState = true
BottomBarItem(
modifier = Modifier.weight(1f), // ✅ 균등 분배
selected = isSelected,
iconRes = iconRes,
contentDescription = item.route,
onClick = {
if (!isSelected) {
if (item.route == "홈") {
navController.navigate("홈") {
popUpTo(0) { inclusive = true }
launchSingleTop = true
}
} else {
navController.navigate(item.route) {
popUpTo(navController.graph.startDestinationId) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
launchSingleTop = true
restoreState = true
}
}
}
},
icon = {
Icon(
painter = painterResource(id = iconRes),
contentDescription = item.route,
tint = Color.Unspecified // 아이콘 색상 유지
)
},
colors = NavigationBarItemDefaults.colors(
indicatorColor = Color.Transparent
)
)
}
}
}
}

@Composable
private fun BottomBarItem(
modifier: Modifier = Modifier,
selected: Boolean,
iconRes: Int,
contentDescription: String,
onClick: () -> Unit,
) {
Box(
modifier = modifier
.fillMaxHeight()
.clickable(
onClick = onClick
),
contentAlignment = Alignment.Center
) {
Icon(
painter = painterResource(id = iconRes),
contentDescription = contentDescription,
tint = Color.Unspecified,
modifier = Modifier.size(66.dp) // 아이콘 크기
)
}
}


// 메인 네비게이션 호스트
@Composable
fun MyNavigationHost(navController: NavHostController) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ internal fun RecentChattingScreen(
painter = painterResource(id = R.drawable.ic_arrow_up),
contentDescription = "Send",
modifier = Modifier
.align(Alignment.CenterEnd)
.align(Alignment.TopEnd)
.padding(6.dp)
.clickable(
enabled = userInput.isNotBlank(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,11 @@ fun ConsultationCenterScreen(
// 위치 → 행정구역명 갱신
LaunchedEffect(userLocation) {
userLocation?.let { ll ->
reverseGeocodeToSidoGu(context, ll)?.let { sidoGu ->
locationTitle = sidoGu
val sidoGu = reverseGeocodeToSidoGu(context, ll)
Log.d("LOCATION_DEBUG", "📍 reverseGeocode result = $sidoGu (lat=${ll.latitude}, lng=${ll.longitude})")

sidoGu?.let {
locationTitle = it
}
}
}
Expand Down Expand Up @@ -457,22 +460,66 @@ suspend fun reverseGeocodeToSidoGu(
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
suspendCancellableCoroutine { cont ->
geocoder.getFromLocation(lat, lng, 1) { list ->
Log.d("GEOCODER_DEBUG", "getFromLocation size=${list.size}, lat=$lat, lng=$lng")

val a = list.firstOrNull()
val sido = normalizeSido(a?.adminArea)
val gu = a?.locality ?: a?.subLocality ?: a?.subAdminArea
cont.resume(
if (!sido.isNullOrBlank() && !gu.isNullOrBlank())
"$sido $gu" else null
if (a == null) {
Log.w("GEOCODER_DEBUG", "Address is null (empty list)")
cont.resume(null)
return@getFromLocation
}

Log.d(
"GEOCODER_DEBUG",
"""
adminArea=${a.adminArea}
subAdminArea=${a.subAdminArea}
locality=${a.locality}
subLocality=${a.subLocality}
thoroughfare=${a.thoroughfare}
featureName=${a.featureName}
""".trimIndent()
)

val sido = normalizeSido(a.adminArea)
// 🔥 여기 추가 / 교체
val guOrDong =
a.subAdminArea
?: a.locality
?: a.subLocality
?: a.thoroughfare // ✅ 역삼동
?: a.subThoroughfare
?: a.featureName

val result =
if (!sido.isNullOrBlank() && !guOrDong.isNullOrBlank())
"$sido $guOrDong"
else null

Log.d("GEOCODER_DEBUG", "result=$result (sido=$sido, gu=$guOrDong)")

cont.resume(result)
}
}
} else {
withContext(Dispatchers.IO) {
try {
val a = geocoder.getFromLocation(lat, lng, 1)?.firstOrNull()
val sido = normalizeSido(a?.adminArea)
val gu = a?.locality ?: a?.subLocality ?: a?.subAdminArea
if (!sido.isNullOrBlank() && !gu.isNullOrBlank()) "$sido $gu" else null
if (a == null) return@withContext null

val sido = normalizeSido(a.adminArea)

val guOrDong =
a.subAdminArea
?: a.locality
?: a.subLocality
?: a.thoroughfare
?: a.subThoroughfare
?: a.featureName

if (!sido.isNullOrBlank() && !guOrDong.isNullOrBlank())
"$sido $guOrDong"
else null
} catch (_: Exception) {
null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fun LogoHeader(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(start = 20.dp, top = 16.dp),
.padding(horizontal = 24.dp, vertical = 18.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Expand Down
Loading