Skip to content

Commit

Permalink
[FEAT/#110] 검색어 요청 매핑
Browse files Browse the repository at this point in the history
  • Loading branch information
arinming committed Jul 17, 2024
1 parent 9bb7e84 commit fc32774
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fun InternItemWithShadow(
title: String,
dateDeadline: String,
workingPeriod: String,
isScraped: Boolean,
scrapId: Long?,
) {
Box(
modifier = Modifier
Expand All @@ -35,7 +35,7 @@ fun InternItemWithShadow(
title = title,
dateDeadline = dateDeadline,
workingPeriod = workingPeriod,
isScraped = isScraped
isScraped = scrapId != null
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ data class SearchResultResponseDto(
@SerialName("internshipAnnouncementId")
val internshipAnnouncementId: Long,
@SerialName("scrapId")
val scrapId: Long,
val scrapId: Long?,
@SerialName("dDay")
val dDay: String,
@SerialName("companyImage")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,21 @@ fun SearchRoute(
}
}

when (viewState.searchViewsList) {
is UiState.Loading -> {}
is UiState.Empty -> {}
is UiState.Failure -> {}
is UiState.Success -> {
SearchScreen(
navController = navController,
searchViewsList = (viewState.searchViewsList as UiState.Success<List<InternshipAnnouncementModel>>).data,
searchScrapsList = (scrapState.searchScrapsList as UiState.Success<List<InternshipAnnouncementModel>>).data
)
}
val searchViewsList = when (viewState.searchViewsList) {
is UiState.Success -> (viewState.searchViewsList as UiState.Success<List<InternshipAnnouncementModel>>).data
else -> emptyList()
}

val searchScrapsList = when (scrapState.searchScrapsList) {
is UiState.Success -> (scrapState.searchScrapsList as UiState.Success<List<InternshipAnnouncementModel>>).data
else -> emptyList()
}

SearchScreen(
navController = navController,
searchViewsList = searchViewsList,
searchScrapsList = searchScrapsList
)
}

@Composable
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.terning.core.designsystem.component.bottomsheet.SortingBottomSheet
import com.terning.core.designsystem.component.button.SortingButton
import com.terning.core.designsystem.component.item.InternItemWithShadow
Expand All @@ -52,13 +53,30 @@ private const val MAX_LINES = 1
@Composable
fun SearchProcessRoute(
navController: NavHostController,
viewModel: SearchProcessViewModel = hiltViewModel(),
) {
val lifecycleOwner = LocalLifecycleOwner.current

val currentSortBy: MutableState<Int> = remember {
mutableIntStateOf(0)
}
val searchListState by viewModel.searchListState.collectAsStateWithLifecycle(lifecycleOwner = lifecycleOwner)

LaunchedEffect(viewModel.sideEffect, lifecycleOwner) {
viewModel.sideEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
.collect { sideEffect ->
when (sideEffect) {
is SearchProcessSideEffect.Toast -> {
sideEffect.message
}
}
}
}

SearchProcessScreen(
navController = navController,
currentSortBy = currentSortBy
currentSortBy = currentSortBy,
viewModel = viewModel,
)
}

Expand Down Expand Up @@ -136,7 +154,7 @@ fun SearchProcessScreen(
onDoneAction = {
viewModel.getSearchList(
query = state.text,
sortBy = SORT_BY,
sortBy = "deadlineSoon",
page = 0,
size = 10
)
Expand All @@ -153,7 +171,7 @@ fun SearchProcessScreen(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
if (state.existSearchResults) {
if (internSearchResultData.isNotEmpty()) {
Row(
modifier = Modifier
.fillMaxWidth(),
Expand All @@ -171,13 +189,13 @@ fun SearchProcessScreen(
),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(internSearchResultData.size) { index ->
items(viewModel.internSearchResultData.value.size) { index ->
InternItemWithShadow(
imageUrl = internSearchResultData[index].imgUrl,
imageUrl = internSearchResultData[index].companyImage,
title = internSearchResultData[index].title,
dateDeadline = internSearchResultData[index].dDay.toString(),
workingPeriod = internSearchResultData[index].workingPeriod.toString(),
isScraped = internSearchResultData[index].isScrapped
dateDeadline = internSearchResultData[index].dDay,
workingPeriod = internSearchResultData[index].workingPeriod,
scrapId = internSearchResultData[index].scrapId
)
}
}
Expand Down Expand Up @@ -236,14 +254,7 @@ fun SearchProcessScreen(
@Composable
fun SearchProcessScreenPreview() {
TerningPointTheme {
SearchProcessScreen(
navController = rememberNavController(),
currentSortBy = remember {
mutableIntStateOf(0)
}
)
}
}


private const val SORT_BY = "deadlineSoon"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.terning.feature.search.searchprocess

import androidx.annotation.StringRes

sealed class SearchProcessSideEffect {
data class Toast(@StringRes val message: Int) : SearchProcessSideEffect()

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ package com.terning.feature.search.searchprocess

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.terning.core.state.UiState
import com.terning.domain.entity.response.SearchResultModel
import com.terning.domain.repository.SearchRepository
import com.terning.feature.home.home.model.InternData
import com.terning.feature.R
import com.terning.feature.search.searchprocess.models.SearchProcessState
import com.terning.feature.search.searchprocess.models.SearchResultState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand All @@ -20,16 +22,18 @@ class SearchProcessViewModel @Inject constructor(
) : ViewModel() {
private val _state: MutableStateFlow<SearchProcessState> =
MutableStateFlow(SearchProcessState())
val state: StateFlow<SearchProcessState> get() = _state
val state: StateFlow<SearchProcessState> = _state.asStateFlow()

private val _sideEffect: MutableSharedFlow<SearchProcessSideEffect> = MutableSharedFlow()
val sideEffect = _sideEffect.asSharedFlow()

private val _searchListState: MutableStateFlow<SearchResultState> =
MutableStateFlow(SearchResultState())
val searchListState: StateFlow<SearchResultState> get() = _searchListState
val searchListState: StateFlow<SearchResultState> = _searchListState.asStateFlow()

private val _internSearchResultState = MutableStateFlow(
getRecommendData()
)
val internSearchResultData get() = _internSearchResultState.asStateFlow()
private val _internSearchResultData = MutableStateFlow<List<SearchResultModel>>(emptyList())
val internSearchResultData: StateFlow<List<SearchResultModel>> =
_internSearchResultData.asStateFlow()

fun getSearchList(
query: String,
Expand All @@ -40,14 +44,10 @@ class SearchProcessViewModel @Inject constructor(
viewModelScope.launch {
searchRepository.getSearchList(query, sortBy, page, size)
.onSuccess {
_searchListState.value = _searchListState.value.copy(
searchList = UiState.Success(it)
)
_internSearchResultData.value = it
}
.onFailure {
_searchListState.value = _searchListState.value.copy(
searchList = UiState.Failure(it.message.toString())
)
_sideEffect.emit(SearchProcessSideEffect.Toast(R.string.server_failure))
}
}
}
Expand All @@ -65,83 +65,13 @@ class SearchProcessViewModel @Inject constructor(
_state.value = _state.value.copy(existSearchResults = true)
}


fun updateExistSearchResults(query: String) {
val exist =
_internSearchResultState.value.any { it.title.contains(query, ignoreCase = true) }
_internSearchResultData.value.any { it.title.contains(query, ignoreCase = true) }
_state.value = _state.value.copy(existSearchResults = exist)
}
}

private fun getRecommendData(): List<InternData> = listOf(
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 22,
workingPeriod = 2,
isScrapped = true,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "ㅇㄻㅇㅁㄻㄹㅇㅁㅇㄹ",
dDay = 9,
workingPeriod = 6,
isScrapped = false,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 2,
workingPeriod = 4,
isScrapped = true,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 2,
workingPeriod = 4,
isScrapped = false,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 2,
workingPeriod = 4,
isScrapped = true,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 2,
workingPeriod = 4,
isScrapped = true,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 2,
workingPeriod = 4,
isScrapped = false,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 2,
workingPeriod = 4,
isScrapped = true,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 2,
workingPeriod = 4,
isScrapped = false,
),
InternData(
imgUrl = "https://reqres.in/img/faces/7-image.jpg",
title = "[유한킴벌리] 그린캠프 w.대학생 숲 활동가",
dDay = 2,
workingPeriod = 4,
isScrapped = true,
),
)
companion object {
private const val SORT_BY = "deadlineSoon"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import com.terning.core.state.UiState
import com.terning.domain.entity.response.SearchResultModel

data class SearchResultState(
var searchList: UiState<List<SearchResultModel>> = UiState.Loading,
var searchListState: UiState<List<SearchResultModel>> = UiState.Loading,
)

0 comments on commit fc32774

Please sign in to comment.