From f9da0b1b33d6d6878b9751122831169443794090 Mon Sep 17 00:00:00 2001 From: nhyeonii Date: Sun, 16 Feb 2025 15:55:32 +0900 Subject: [PATCH 1/4] =?UTF-8?q?#16=20[MOD]=20=EB=8F=84=EB=A1=9C=ED=86=B5?= =?UTF-8?q?=EC=A0=9C=EC=A0=95=EB=B3=B4=20api=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datasource/CrowdZeroDataSource.kt | 2 ++ .../datasourceimpl/CrowdZeroDataSourceImpl.kt | 6 ++++++ .../gdg/data/dto/response/RoadResponseDto.kt | 16 ++++++++++++++ .../gdg/data/mapper/ResponseRoadDtoMapper.kt | 14 +++++++++++++ .../repositoryimpl/CrowdZeroRepositoryImpl.kt | 9 ++++++++ .../com/gdg/data/service/CrowdZeroService.kt | 7 +++++++ .../domain/repository/CrowdZeroRepository.kt | 2 ++ .../main/java/com/gdg/feature/map/MapRoute.kt | 8 ++++++- .../java/com/gdg/feature/map/MapViewModel.kt | 21 +++++++++++++++++++ 9 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 data/src/main/java/com/gdg/data/dto/response/RoadResponseDto.kt create mode 100644 data/src/main/java/com/gdg/data/mapper/ResponseRoadDtoMapper.kt diff --git a/data/src/main/java/com/gdg/data/datasource/CrowdZeroDataSource.kt b/data/src/main/java/com/gdg/data/datasource/CrowdZeroDataSource.kt index 5853177..57349c8 100644 --- a/data/src/main/java/com/gdg/data/datasource/CrowdZeroDataSource.kt +++ b/data/src/main/java/com/gdg/data/datasource/CrowdZeroDataSource.kt @@ -2,9 +2,11 @@ package com.gdg.data.datasource import com.gdg.data.dto.BaseResponse import com.gdg.data.dto.response.CongestionResponseDto +import com.gdg.data.dto.response.RoadResponseDto import com.gdg.data.dto.response.WeatherResponseDto interface CrowdZeroDataSource { suspend fun getWeather(areaId: Long): BaseResponse suspend fun getCongestion(areaId: Long): BaseResponse + suspend fun getRoad(areaId: Int): BaseResponse } \ No newline at end of file diff --git a/data/src/main/java/com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt b/data/src/main/java/com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt index ce701c9..889b7be 100644 --- a/data/src/main/java/com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt +++ b/data/src/main/java/com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt @@ -3,6 +3,7 @@ package com.gdg.data.datasourceimpl import com.gdg.data.datasource.CrowdZeroDataSource import com.gdg.data.dto.BaseResponse import com.gdg.data.dto.response.CongestionResponseDto +import com.gdg.data.dto.response.RoadResponseDto import com.gdg.data.dto.response.WeatherResponseDto import com.gdg.data.service.CrowdZeroService import javax.inject.Inject @@ -17,4 +18,9 @@ class CrowdZeroDataSourceImpl @Inject constructor( override suspend fun getCongestion(areaId: Long): BaseResponse { return crowdZeroApiService.getCongestion(areaId) } + + override suspend fun getRoad(areaId: Int): BaseResponse { + return crowdZeroApiService.getRoad(areaId) + } + } \ No newline at end of file diff --git a/data/src/main/java/com/gdg/data/dto/response/RoadResponseDto.kt b/data/src/main/java/com/gdg/data/dto/response/RoadResponseDto.kt new file mode 100644 index 0000000..081a7e8 --- /dev/null +++ b/data/src/main/java/com/gdg/data/dto/response/RoadResponseDto.kt @@ -0,0 +1,16 @@ +package com.gdg.data.dto.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RoadResponseDto( + @SerialName("id") val id: Long, + @SerialName("acdntOccrDt") val acdntOccrDt: String, + @SerialName("expClrDt") val expClrDt: String, + @SerialName("acdntInfo") val acdntInfo: String, + @SerialName("acdntX") val acdntX: Double, + @SerialName("acdntY") val acdntY: Double, + @SerialName("acdntTime") val acdntTime: String, + @SerialName("areaId") val areaId: Int +) \ No newline at end of file diff --git a/data/src/main/java/com/gdg/data/mapper/ResponseRoadDtoMapper.kt b/data/src/main/java/com/gdg/data/mapper/ResponseRoadDtoMapper.kt new file mode 100644 index 0000000..0d9fa55 --- /dev/null +++ b/data/src/main/java/com/gdg/data/mapper/ResponseRoadDtoMapper.kt @@ -0,0 +1,14 @@ +package com.gdg.data.mapper + +import com.gdg.data.dto.response.RoadResponseDto +import com.gdg.domain.entity.RoadEntity + +fun RoadResponseDto.toRoadEntity() = RoadEntity( + areaId = areaId, + acdntOccrDt = acdntOccrDt, + expClrDt = expClrDt, + acdntInfo = acdntInfo, + acdntX = acdntX, + acdntY = acdntY, + acdntTime = acdntTime +) diff --git a/data/src/main/java/com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt b/data/src/main/java/com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt index db0ec7d..4aa2d03 100644 --- a/data/src/main/java/com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt +++ b/data/src/main/java/com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt @@ -3,7 +3,9 @@ package com.gdg.data.repositoryimpl import com.gdg.data.datasource.CrowdZeroDataSource import com.gdg.data.mapper.toCongestionEntity import com.gdg.data.mapper.toWeatherEntity +import com.gdg.data.mapper.toRoadEntity import com.gdg.domain.entity.CongestionEntity +import com.gdg.domain.entity.RoadEntity import com.gdg.domain.entity.WeatherEntity import com.gdg.domain.repository.CrowdZeroRepository import javax.inject.Inject @@ -25,4 +27,11 @@ class CrowdZeroRepositoryImpl @Inject constructor( } } + override suspend fun getRoad(areaId: Int): Result { + return runCatching { + crowdZeroDataSource.getRoad(areaId).data?.toRoadEntity() + ?: throw Exception("Data is null") + } + } + } diff --git a/data/src/main/java/com/gdg/data/service/CrowdZeroService.kt b/data/src/main/java/com/gdg/data/service/CrowdZeroService.kt index 45361dc..3ef2662 100644 --- a/data/src/main/java/com/gdg/data/service/CrowdZeroService.kt +++ b/data/src/main/java/com/gdg/data/service/CrowdZeroService.kt @@ -2,7 +2,9 @@ package com.gdg.data.service import com.gdg.data.dto.BaseResponse import com.gdg.data.dto.response.CongestionResponseDto +import com.gdg.data.dto.response.RoadResponseDto import com.gdg.data.dto.response.WeatherResponseDto +import com.gdg.data.service.ApiKeyStorage.ACDNT import com.gdg.data.service.ApiKeyStorage.API import com.gdg.data.service.ApiKeyStorage.AREA_ID import com.gdg.data.service.ApiKeyStorage.PPLTN @@ -20,4 +22,9 @@ interface CrowdZeroService { suspend fun getCongestion( @Path(AREA_ID) areaId: Long ): BaseResponse + + @GET("/$API/$ACDNT/{$AREA_ID}") + suspend fun getRoad( + @Path(AREA_ID) areaId: Int + ): BaseResponse } diff --git a/domain/src/main/java/com/gdg/domain/repository/CrowdZeroRepository.kt b/domain/src/main/java/com/gdg/domain/repository/CrowdZeroRepository.kt index 9a535fd..3f2fd40 100644 --- a/domain/src/main/java/com/gdg/domain/repository/CrowdZeroRepository.kt +++ b/domain/src/main/java/com/gdg/domain/repository/CrowdZeroRepository.kt @@ -1,9 +1,11 @@ package com.gdg.domain.repository import com.gdg.domain.entity.CongestionEntity +import com.gdg.domain.entity.RoadEntity import com.gdg.domain.entity.WeatherEntity interface CrowdZeroRepository { suspend fun getWeather(areaId: Long): Result suspend fun getCongestion(areaId: Long): Result + suspend fun getRoad(areaId: Int): Result } \ No newline at end of file diff --git a/feature/src/main/java/com/gdg/feature/map/MapRoute.kt b/feature/src/main/java/com/gdg/feature/map/MapRoute.kt index d988ac9..5b10b71 100644 --- a/feature/src/main/java/com/gdg/feature/map/MapRoute.kt +++ b/feature/src/main/java/com/gdg/feature/map/MapRoute.kt @@ -17,6 +17,7 @@ import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -81,6 +82,11 @@ fun MapRoute( } val getCongestionState by mapViewModel.getCongestionState.collectAsStateWithLifecycle() val context = LocalContext.current + val roads by mapViewModel.roads.collectAsStateWithLifecycle() // roads 리스트를 가져옵니다. + + LaunchedEffect(Unit) { + mapViewModel.getRoads() // 1부터 5까지 도로 정보 가져오기 + } LaunchedEffect(key1 = mapViewModel.sideEffects) { mapViewModel.sideEffects.collect { sideEffect -> @@ -96,7 +102,7 @@ fun MapRoute( mapUiSettings = mapUiSettings, cameraPositionState = cameraPositionState, locations = mapViewModel.locations, - roads = mapViewModel.mockRoadEntity, + roads = roads, congestionState = getCongestionState, getPlaceEntity = { id -> mapViewModel.getCongestion(id) }, onButtonClick = mapViewModel::navigateToDetail diff --git a/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt b/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt index d0b7c28..07f78b4 100644 --- a/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt +++ b/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import okhttp3.internal.immutableListOf +import timber.log.Timber import javax.inject.Inject @HiltViewModel @@ -29,6 +30,9 @@ class MapViewModel @Inject constructor( private val _sideEffects: MutableSharedFlow = MutableSharedFlow() val sideEffects: SharedFlow get() = _sideEffects + private val _roads = MutableStateFlow>(emptyList()) + val roads: StateFlow> get() = _roads + fun getCongestion(areaId: Long) { viewModelScope.launch { _getCongestionState.emit(UiState.Loading) @@ -51,6 +55,23 @@ class MapViewModel @Inject constructor( } } + fun getRoads() { + viewModelScope.launch { + _roads.emit(emptyList()) + // 1부터 5까지의 areaId에 대해 getRoad 호출 + (1..5).forEach { areaId -> + crowdZeroRepository.getRoad(areaId).fold( + onSuccess = { + _roads.emit(_roads.value + it) // 기존 리스트에 도로 정보를 추가 + }, + onFailure = { + + } + ) + } + } + } + @Stable val locations = immutableListOf( LocationType.GANGNAM_STATION, From 6c9ffc20d761d2af95c53e1023be5296b1a1c193 Mon Sep 17 00:00:00 2001 From: nhyeonii Date: Sun, 16 Feb 2025 16:40:02 +0900 Subject: [PATCH 2/4] =?UTF-8?q?#16=20[FEAT]=20=EB=8F=84=EB=A1=9C=ED=86=B5?= =?UTF-8?q?=EC=A0=9C=EC=A0=95=EB=B3=B4=20api=20=EB=B7=B0=EB=9E=91=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gdg/data/mapper/ResponseRoadDtoMapper.kt | 2 +- .../main/java/com/gdg/feature/map/MapRoute.kt | 5 ++--- .../java/com/gdg/feature/map/MapViewModel.kt | 17 ++++++++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/data/src/main/java/com/gdg/data/mapper/ResponseRoadDtoMapper.kt b/data/src/main/java/com/gdg/data/mapper/ResponseRoadDtoMapper.kt index 0d9fa55..bfec87e 100644 --- a/data/src/main/java/com/gdg/data/mapper/ResponseRoadDtoMapper.kt +++ b/data/src/main/java/com/gdg/data/mapper/ResponseRoadDtoMapper.kt @@ -4,7 +4,7 @@ import com.gdg.data.dto.response.RoadResponseDto import com.gdg.domain.entity.RoadEntity fun RoadResponseDto.toRoadEntity() = RoadEntity( - areaId = areaId, + areaId = id.toInt(), acdntOccrDt = acdntOccrDt, expClrDt = expClrDt, acdntInfo = acdntInfo, diff --git a/feature/src/main/java/com/gdg/feature/map/MapRoute.kt b/feature/src/main/java/com/gdg/feature/map/MapRoute.kt index 6d68864..e8dcaf7 100644 --- a/feature/src/main/java/com/gdg/feature/map/MapRoute.kt +++ b/feature/src/main/java/com/gdg/feature/map/MapRoute.kt @@ -17,7 +17,6 @@ import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -82,10 +81,10 @@ fun MapRoute( } val getCongestionState by mapViewModel.getCongestionState.collectAsStateWithLifecycle() val context = LocalContext.current - val roads by mapViewModel.roads.collectAsStateWithLifecycle() // roads 리스트를 가져옵니다. + val roads by mapViewModel.roads.collectAsStateWithLifecycle() LaunchedEffect(Unit) { - mapViewModel.getRoads() // 1부터 5까지 도로 정보 가져오기 + mapViewModel.getRoads() } LaunchedEffect(key1 = mapViewModel.sideEffects) { diff --git a/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt b/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt index 90a07e2..ebe183d 100644 --- a/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt +++ b/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import okhttp3.internal.immutableListOf -import timber.log.Timber import javax.inject.Inject @HiltViewModel @@ -27,14 +26,16 @@ class MapViewModel @Inject constructor( MutableStateFlow(UiState.Empty) val getCongestionState: StateFlow> get() = _getCongestionState + private val _getRoadState: MutableStateFlow>> = MutableStateFlow(UiState.Empty) + val getRoadState: StateFlow>> get() = _getRoadState + private val _sideEffects: MutableSharedFlow = MutableSharedFlow() val sideEffects: SharedFlow get() = _sideEffects - fun getCongestion(areaId: Int) { private val _roads = MutableStateFlow>(emptyList()) val roads: StateFlow> get() = _roads - fun getCongestion(areaId: Long) { + fun getCongestion(areaId: Int) { viewModelScope.launch { _getCongestionState.emit(UiState.Loading) crowdZeroRepository.getCongestion(areaId).fold( @@ -58,18 +59,24 @@ class MapViewModel @Inject constructor( fun getRoads() { viewModelScope.launch { + _getRoadState.emit(UiState.Loading) _roads.emit(emptyList()) - // 1부터 5까지의 areaId에 대해 getRoad 호출 (1..5).forEach { areaId -> crowdZeroRepository.getRoad(areaId).fold( onSuccess = { _roads.emit(_roads.value + it) // 기존 리스트에 도로 정보를 추가 }, onFailure = { - + _getRoadState.emit(UiState.Failure(it.message.toString())) } ) } + // 도로 정보를 모두 가져온 후, Success 상태로 전환 + if (_roads.value.isNotEmpty()) { + _getRoadState.emit(UiState.Success(_roads.value)) // _roads.value를 Success로 전달 + } else { + _getRoadState.emit(UiState.Failure("도로 정보를 가져오는 데 실패했습니다.")) + } } } From 89bce4291ff9d534e1789a9af2da10a6214001a9 Mon Sep 17 00:00:00 2001 From: nhyeonii Date: Sun, 16 Feb 2025 17:06:30 +0900 Subject: [PATCH 3/4] =?UTF-8?q?#16=20[MOD]=20RoadEntity=20List=20=ED=98=95?= =?UTF-8?q?=ED=83=9C=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gdg/data/datasource/CrowdZeroDataSource.kt | 2 +- .../com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt | 2 +- .../com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt | 6 +++--- data/src/main/java/com/gdg/data/service/CrowdZeroService.kt | 2 +- .../java/com/gdg/domain/repository/CrowdZeroRepository.kt | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/data/src/main/java/com/gdg/data/datasource/CrowdZeroDataSource.kt b/data/src/main/java/com/gdg/data/datasource/CrowdZeroDataSource.kt index 39305b6..fa836c1 100644 --- a/data/src/main/java/com/gdg/data/datasource/CrowdZeroDataSource.kt +++ b/data/src/main/java/com/gdg/data/datasource/CrowdZeroDataSource.kt @@ -8,5 +8,5 @@ import com.gdg.data.dto.response.WeatherResponseDto interface CrowdZeroDataSource { suspend fun getWeather(areaId: Int): BaseResponse suspend fun getCongestion(areaId: Int): BaseResponse - suspend fun getRoad(areaId: Int): BaseResponse + suspend fun getRoad(areaId: Int): BaseResponse> } \ No newline at end of file diff --git a/data/src/main/java/com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt b/data/src/main/java/com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt index 9b22f17..1882235 100644 --- a/data/src/main/java/com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt +++ b/data/src/main/java/com/gdg/data/datasourceimpl/CrowdZeroDataSourceImpl.kt @@ -19,7 +19,7 @@ class CrowdZeroDataSourceImpl @Inject constructor( return crowdZeroApiService.getCongestion(areaId) } - override suspend fun getRoad(areaId: Int): BaseResponse { + override suspend fun getRoad(areaId: Int): BaseResponse> { return crowdZeroApiService.getRoad(areaId) } diff --git a/data/src/main/java/com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt b/data/src/main/java/com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt index db0c084..6d5dccd 100644 --- a/data/src/main/java/com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt +++ b/data/src/main/java/com/gdg/data/repositoryimpl/CrowdZeroRepositoryImpl.kt @@ -2,6 +2,7 @@ package com.gdg.data.repositoryimpl import com.gdg.data.datasource.CrowdZeroDataSource import com.gdg.data.mapper.toCongestionEntity +import com.gdg.data.mapper.toExampleEntity import com.gdg.data.mapper.toWeatherEntity import com.gdg.data.mapper.toRoadEntity import com.gdg.domain.entity.CongestionEntity @@ -27,10 +28,9 @@ class CrowdZeroRepositoryImpl @Inject constructor( } } - override suspend fun getRoad(areaId: Int): Result { + override suspend fun getRoad(areaId: Int): Result> { return runCatching { - crowdZeroDataSource.getRoad(areaId).data?.toRoadEntity() - ?: throw Exception("Data is null") + crowdZeroDataSource.getRoad(areaId).data?.map { it.toRoadEntity() } ?: emptyList() } } diff --git a/data/src/main/java/com/gdg/data/service/CrowdZeroService.kt b/data/src/main/java/com/gdg/data/service/CrowdZeroService.kt index da4bbee..60726a5 100644 --- a/data/src/main/java/com/gdg/data/service/CrowdZeroService.kt +++ b/data/src/main/java/com/gdg/data/service/CrowdZeroService.kt @@ -26,5 +26,5 @@ interface CrowdZeroService { @GET("/$API/$ACDNT/{$AREA_ID}") suspend fun getRoad( @Path(AREA_ID) areaId: Int - ): BaseResponse + ): BaseResponse> } diff --git a/domain/src/main/java/com/gdg/domain/repository/CrowdZeroRepository.kt b/domain/src/main/java/com/gdg/domain/repository/CrowdZeroRepository.kt index e942a7d..a644e8b 100644 --- a/domain/src/main/java/com/gdg/domain/repository/CrowdZeroRepository.kt +++ b/domain/src/main/java/com/gdg/domain/repository/CrowdZeroRepository.kt @@ -7,5 +7,5 @@ import com.gdg.domain.entity.WeatherEntity interface CrowdZeroRepository { suspend fun getWeather(areaId: Int): Result suspend fun getCongestion(areaId: Int): Result - suspend fun getRoad(areaId: Int): Result + suspend fun getRoad(areaId: Int): Result> } \ No newline at end of file From 3fc7acac9be68077a1aa5e5ca9bbf13cade06848 Mon Sep 17 00:00:00 2001 From: nhyeonii Date: Sun, 16 Feb 2025 17:29:06 +0900 Subject: [PATCH 4/4] =?UTF-8?q?#16=20[CHORE]=20=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A4=84=EA=B0=84=EA=B2=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gdg/feature/map/MapRoute.kt | 44 +++++++--------- .../java/com/gdg/feature/map/MapViewModel.kt | 50 ++----------------- 2 files changed, 23 insertions(+), 71 deletions(-) diff --git a/feature/src/main/java/com/gdg/feature/map/MapRoute.kt b/feature/src/main/java/com/gdg/feature/map/MapRoute.kt index e8dcaf7..df3538a 100644 --- a/feature/src/main/java/com/gdg/feature/map/MapRoute.kt +++ b/feature/src/main/java/com/gdg/feature/map/MapRoute.kt @@ -59,8 +59,7 @@ import timber.log.Timber @Composable fun MapRoute( - mapViewModel: MapViewModel = hiltViewModel(), - navigateToDetail: (Long) -> Unit + mapViewModel: MapViewModel = hiltViewModel(), navigateToDetail: (Long) -> Unit ) { val mapProperties by remember { mutableStateOf( @@ -155,8 +154,7 @@ fun MapScreen( } if (roads.isNotEmpty()) { roads.forEach { road -> - Marker( - width = 20.dp, + Marker(width = 20.dp, height = 20.dp, state = MarkerState(position = LatLng(road.acdntY, road.acdntX)), icon = OverlayImage.fromResource(R.drawable.ic_ban_marker), @@ -167,8 +165,7 @@ fun MapScreen( sheetState.show() } true - } - ) + }) } } } @@ -176,29 +173,24 @@ fun MapScreen( modifier = Modifier .fillMaxWidth() .align(Alignment.TopCenter) - .padding(top = 110.dp, start = 10.dp, end = 10.dp), - state = listState + .padding(top = 110.dp, start = 10.dp, end = 10.dp), state = listState ) { itemsIndexed(locations) { index, location -> - MapChip( - title = location, - isSelected = selectedLocation == location, - onClick = { - if (selectedLocation == location) { - selectedLocation = null - } else { - selectedLocation = location - getPlaceEntity(location.id) - cameraPositionState.move( - CameraUpdate.scrollAndZoomTo(location.latLng, 17.0) - .animate(CameraAnimation.Easing) - ) - } - coroutineScope.launch { - listState.animateScrollToItem(index) - } + MapChip(title = location, isSelected = selectedLocation == location, onClick = { + if (selectedLocation == location) { + selectedLocation = null + } else { + selectedLocation = location + getPlaceEntity(location.id) + cameraPositionState.move( + CameraUpdate.scrollAndZoomTo(location.latLng, 17.0) + .animate(CameraAnimation.Easing) + ) } - ) + coroutineScope.launch { + listState.animateScrollToItem(index) + } + }) } } selectedLocation?.let { location -> diff --git a/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt b/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt index ebe183d..242c00e 100644 --- a/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt +++ b/feature/src/main/java/com/gdg/feature/map/MapViewModel.kt @@ -26,7 +26,8 @@ class MapViewModel @Inject constructor( MutableStateFlow(UiState.Empty) val getCongestionState: StateFlow> get() = _getCongestionState - private val _getRoadState: MutableStateFlow>> = MutableStateFlow(UiState.Empty) + private val _getRoadState: MutableStateFlow>> = + MutableStateFlow(UiState.Empty) val getRoadState: StateFlow>> get() = _getRoadState private val _sideEffects: MutableSharedFlow = MutableSharedFlow() @@ -64,16 +65,16 @@ class MapViewModel @Inject constructor( (1..5).forEach { areaId -> crowdZeroRepository.getRoad(areaId).fold( onSuccess = { - _roads.emit(_roads.value + it) // 기존 리스트에 도로 정보를 추가 + _roads.emit(_roads.value + it) }, onFailure = { _getRoadState.emit(UiState.Failure(it.message.toString())) } ) } - // 도로 정보를 모두 가져온 후, Success 상태로 전환 + if (_roads.value.isNotEmpty()) { - _getRoadState.emit(UiState.Success(_roads.value)) // _roads.value를 Success로 전달 + _getRoadState.emit(UiState.Success(_roads.value)) } else { _getRoadState.emit(UiState.Failure("도로 정보를 가져오는 데 실패했습니다.")) } @@ -89,51 +90,10 @@ class MapViewModel @Inject constructor( LocationType.YEOUIDO ) - fun getPlaceEntity(id: Long): PlaceEntity? { - return mockPlaces.find { it.id == id } - } - fun navigateToDetail(id: Long) { viewModelScope.launch { _sideEffects.emit(MapSideEffect.NavigateToDetail(id)) } } - private val mockPlaces = listOf( - PlaceEntity(1, "강남역", "보통", 100, 200), - PlaceEntity(2, "광화문 광장", "보통", 100, 200), - PlaceEntity(3, "삼각지역", "보통", 100, 200), - PlaceEntity(4, "서울역", "보통", 100, 200), - PlaceEntity(5, "여의도", "보통", 100, 200) - ) - - val mockRoadEntity = listOf( - RoadEntity( - 1, - "2021-09-01 13:00", - "2021-09-01 13:00", - "사고1", - 126.97719959199067, - 37.57473917460146, - "2021-09-01 13:00" - ), - RoadEntity( - 2, - "2021-09-01 13:00", - "2021-09-01 13:00", - "사고2", - 126.97724062015716, - 37.57196573522649, - "2021-09-01 13:00" - ), - RoadEntity( - 3, - "2021-09-01 13:00", - "2021-09-01 13:00", - "사고3", - 126.97681755577895, - 37.56963658011575, - "2021-09-01 13:00" - ) - ) }