diff --git a/core/data/src/main/java/com/idle/data/repository/JobPostingRepositoryImpl.kt b/core/data/src/main/java/com/idle/data/repository/JobPostingRepositoryImpl.kt index 1c62aa8a..3f0f132e 100644 --- a/core/data/src/main/java/com/idle/data/repository/JobPostingRepositoryImpl.kt +++ b/core/data/src/main/java/com/idle/data/repository/JobPostingRepositoryImpl.kt @@ -8,6 +8,7 @@ import com.idle.domain.model.jobposting.CenterJobPosting import com.idle.domain.model.jobposting.CenterJobPostingDetail import com.idle.domain.model.jobposting.CrawlingJobPosting import com.idle.domain.model.jobposting.CrawlingJobPostingDetail +import com.idle.domain.model.jobposting.CrawlingJobPostingPage import com.idle.domain.model.jobposting.DayOfWeek import com.idle.domain.model.jobposting.JobPostingSummary import com.idle.domain.model.jobposting.JobPostingType @@ -17,6 +18,7 @@ import com.idle.domain.model.jobposting.PayType import com.idle.domain.model.jobposting.SharedJobPostingInfo import com.idle.domain.model.jobposting.WorkerJobPosting import com.idle.domain.model.jobposting.WorkerJobPostingDetail +import com.idle.domain.model.jobposting.WorkerJobPostingPage import com.idle.domain.repositorry.JobPostingRepository import com.idle.network.model.jobposting.ApplyJobPostingRequest import com.idle.network.model.jobposting.FavoriteJobPostingRequest @@ -151,7 +153,7 @@ class JobPostingRepositoryImpl @Inject constructor( override suspend fun getJobPostings( next: String?, limit: Int - ): Result>> = jobPostingDataSource.getJobPostings( + ): Result = jobPostingDataSource.getJobPostings( next = next, limit = limit ).mapCatching { it.toVO() } @@ -159,7 +161,7 @@ class JobPostingRepositoryImpl @Inject constructor( override suspend fun getJobPostingsApplied( next: String?, limit: Int - ): Result>> = jobPostingDataSource.getJobPostingsApplied( + ): Result = jobPostingDataSource.getJobPostingsApplied( next = next, limit = limit ).mapCatching { it.toVO() } @@ -213,8 +215,9 @@ class JobPostingRepositoryImpl @Inject constructor( override suspend fun getCrawlingJobPostings( next: String?, limit: Int, - ): Result>> = - jobPostingDataSource.getCrawlingJobPostings(next, limit).mapCatching { it.toVO() } + distance: Int, + ): Result = + jobPostingDataSource.getCrawlingJobPostings(next, limit, distance).mapCatching { it.toVO() } override suspend fun getCrawlingJobPostingDetail(jobPostingId: String): Result = jobPostingDataSource.getCrawlingJobPostingsDetail(jobPostingId).mapCatching { it.toVO() } diff --git a/core/domain/src/main/kotlin/com/idle/domain/model/jobposting/CrawlingJobPosting.kt b/core/domain/src/main/kotlin/com/idle/domain/model/jobposting/CrawlingJobPosting.kt index f85e8e82..b0926939 100644 --- a/core/domain/src/main/kotlin/com/idle/domain/model/jobposting/CrawlingJobPosting.kt +++ b/core/domain/src/main/kotlin/com/idle/domain/model/jobposting/CrawlingJobPosting.kt @@ -10,4 +10,10 @@ data class CrawlingJobPosting( val workingSchedule: String, val payInfo: String, val applyDeadline: String, -) : JobPosting(id, distance, jobPostingType, isFavorite) \ No newline at end of file +) : JobPosting(id, distance, jobPostingType, isFavorite) + +data class CrawlingJobPostingPage( + val nextCursor: String?, + val items: List, + val nextDistance: Int, +) diff --git a/core/domain/src/main/kotlin/com/idle/domain/model/jobposting/WorkerJobPosting.kt b/core/domain/src/main/kotlin/com/idle/domain/model/jobposting/WorkerJobPosting.kt index c7a7f881..ff4d8f6a 100644 --- a/core/domain/src/main/kotlin/com/idle/domain/model/jobposting/WorkerJobPosting.kt +++ b/core/domain/src/main/kotlin/com/idle/domain/model/jobposting/WorkerJobPosting.kt @@ -24,3 +24,8 @@ data class WorkerJobPosting( val applyDeadline: LocalDate, val applyTime: LocalDateTime?, ) : JobPosting(id, distance, jobPostingType, isFavorite) + +data class WorkerJobPostingPage( + val nextCursor: String?, + val items: List, +) diff --git a/core/domain/src/main/kotlin/com/idle/domain/repositorry/JobPostingRepository.kt b/core/domain/src/main/kotlin/com/idle/domain/repositorry/JobPostingRepository.kt index 921ea40f..73b88659 100644 --- a/core/domain/src/main/kotlin/com/idle/domain/repositorry/JobPostingRepository.kt +++ b/core/domain/src/main/kotlin/com/idle/domain/repositorry/JobPostingRepository.kt @@ -8,6 +8,7 @@ import com.idle.domain.model.jobposting.CenterJobPosting import com.idle.domain.model.jobposting.CenterJobPostingDetail import com.idle.domain.model.jobposting.CrawlingJobPosting import com.idle.domain.model.jobposting.CrawlingJobPostingDetail +import com.idle.domain.model.jobposting.CrawlingJobPostingPage import com.idle.domain.model.jobposting.DayOfWeek import com.idle.domain.model.jobposting.JobPostingSummary import com.idle.domain.model.jobposting.JobPostingType @@ -17,6 +18,7 @@ import com.idle.domain.model.jobposting.PayType import com.idle.domain.model.jobposting.SharedJobPostingInfo import com.idle.domain.model.jobposting.WorkerJobPosting import com.idle.domain.model.jobposting.WorkerJobPostingDetail +import com.idle.domain.model.jobposting.WorkerJobPostingPage interface JobPostingRepository { var sharedJobPostingInfo: SharedJobPostingInfo? @@ -81,12 +83,12 @@ interface JobPostingRepository { suspend fun getJobPostings( next: String?, limit: Int = 10, - ): Result>> + ): Result suspend fun getJobPostingsApplied( next: String?, limit: Int = 10, - ): Result>> + ): Result suspend fun getMyFavoritesJobPostings(): Result> @@ -116,7 +118,8 @@ interface JobPostingRepository { suspend fun getCrawlingJobPostings( next: String?, limit: Int = 10, - ): Result>> + distance: Int = 15, + ): Result suspend fun getCrawlingJobPostingDetail(jobPostingId: String): Result } diff --git a/core/network/src/main/java/com/idle/network/api/JobPostingApi.kt b/core/network/src/main/java/com/idle/network/api/JobPostingApi.kt index 74611164..49afad03 100644 --- a/core/network/src/main/java/com/idle/network/api/JobPostingApi.kt +++ b/core/network/src/main/java/com/idle/network/api/JobPostingApi.kt @@ -98,6 +98,7 @@ interface JobPostingApi { suspend fun getCrawlingJobPostings( @Query("next") next: String?, @Query("limit") limit: Int, + @Query("distance") distance: Int, ): Response @GET("api/v1/crawling-job-postings/{crawling-job-posting-id}") diff --git a/core/network/src/main/java/com/idle/network/model/jobposting/GetCrawlingJobPostingsResponse.kt b/core/network/src/main/java/com/idle/network/model/jobposting/GetCrawlingJobPostingsResponse.kt index 103aa6cf..cf45a98c 100644 --- a/core/network/src/main/java/com/idle/network/model/jobposting/GetCrawlingJobPostingsResponse.kt +++ b/core/network/src/main/java/com/idle/network/model/jobposting/GetCrawlingJobPostingsResponse.kt @@ -1,6 +1,7 @@ package com.idle.network.model.jobposting import com.idle.domain.model.jobposting.CrawlingJobPosting +import com.idle.domain.model.jobposting.CrawlingJobPostingPage import com.idle.domain.model.jobposting.JobPostingType import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -10,9 +11,13 @@ data class GetCrawlingJobPostingsResponse( @SerialName("items") val crawlingJobPostingResponses: List = listOf(), val next: String? = null, val total: Int = 0, + val nextDistance: Int = 15, ) { - fun toVO(): Pair> = - next to crawlingJobPostingResponses.map { it.toVO() } + fun toVO(): CrawlingJobPostingPage = CrawlingJobPostingPage( + nextCursor = next, + items = crawlingJobPostingResponses.map { it.toVO() }, + nextDistance = nextDistance, + ) } @Serializable diff --git a/core/network/src/main/java/com/idle/network/model/jobposting/GetJobPostingsResponse.kt b/core/network/src/main/java/com/idle/network/model/jobposting/GetJobPostingsResponse.kt index e85b194a..25961f55 100644 --- a/core/network/src/main/java/com/idle/network/model/jobposting/GetJobPostingsResponse.kt +++ b/core/network/src/main/java/com/idle/network/model/jobposting/GetJobPostingsResponse.kt @@ -6,6 +6,7 @@ import com.idle.domain.model.jobposting.DayOfWeek import com.idle.domain.model.jobposting.JobPostingType import com.idle.domain.model.jobposting.PayType import com.idle.domain.model.jobposting.WorkerJobPosting +import com.idle.domain.model.jobposting.WorkerJobPostingPage import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import java.time.LocalDate @@ -18,8 +19,11 @@ data class GetJobPostingsResponse( val next: String?, val total: Int ) { - fun toVO(): Pair> = - next to workerJobPostingResponses.map { it.toVO() } + fun toVO(): WorkerJobPostingPage = + WorkerJobPostingPage( + nextCursor = next, + items = workerJobPostingResponses.map { it.toVO() }, + ) } @Serializable diff --git a/core/network/src/main/java/com/idle/network/source/JobPostingDataSource.kt b/core/network/src/main/java/com/idle/network/source/JobPostingDataSource.kt index 03066f75..5b7c03c3 100644 --- a/core/network/src/main/java/com/idle/network/source/JobPostingDataSource.kt +++ b/core/network/src/main/java/com/idle/network/source/JobPostingDataSource.kt @@ -93,9 +93,10 @@ class JobPostingDataSource @Inject constructor( suspend fun getCrawlingJobPostings( next: String?, - limit: Int + limit: Int, + distance: Int, ): Result = - safeApiCall { jobPostingApi.getCrawlingJobPostings(next = next, limit = limit) } + safeApiCall { jobPostingApi.getCrawlingJobPostings(next = next, limit = limit, distance = distance) } suspend fun getCrawlingJobPostingsDetail( jobPostingId: String diff --git a/feature/chatting-detail/src/main/java/com/idle/chatting_detail/ui/component/CareChatTextBubble.kt b/feature/chatting-detail/src/main/java/com/idle/chatting_detail/ui/component/CareChatTextBubble.kt index 64e93b5f..5531dda5 100644 --- a/feature/chatting-detail/src/main/java/com/idle/chatting_detail/ui/component/CareChatTextBubble.kt +++ b/feature/chatting-detail/src/main/java/com/idle/chatting_detail/ui/component/CareChatTextBubble.kt @@ -157,7 +157,6 @@ fun CareChatSenderTextBubble( chatMessage: ChatMessage, isLast: Boolean, modifier: Modifier = Modifier, - isRead: Boolean = false, onSeeAllChatClicked: (String) -> Unit = {}, ) { Row(modifier = modifier.fillMaxWidth()) { @@ -225,7 +224,7 @@ fun CareChatSenderTextBubble( .align(Alignment.Bottom) .padding(start = 6.dp), ) { - if (isRead) { + if (chatMessage.isRead) { Text( text = "읽음", style = CareTheme.typography.caption1, @@ -248,7 +247,6 @@ fun CareChatReceiverTextBubble( chatMessage: ChatMessage, isLast: Boolean, modifier: Modifier = Modifier, - isRead: Boolean = false, onSeeAllChatClicked: (String) -> Unit = {}, ) { Row( @@ -263,7 +261,7 @@ fun CareChatReceiverTextBubble( .align(Alignment.Bottom) .padding(end = 6.dp), ) { - if (isRead) { + if (chatMessage.isRead) { Text( text = "읽음", style = CareTheme.typography.caption1, diff --git a/feature/chatting-detail/src/main/java/com/idle/chatting_detail/ui/component/ChattingBody.kt b/feature/chatting-detail/src/main/java/com/idle/chatting_detail/ui/component/ChattingBody.kt index 0562d767..ed7ec9bf 100644 --- a/feature/chatting-detail/src/main/java/com/idle/chatting_detail/ui/component/ChattingBody.kt +++ b/feature/chatting-detail/src/main/java/com/idle/chatting_detail/ui/component/ChattingBody.kt @@ -106,7 +106,6 @@ fun ChattingBody( CareChatSenderTextBubble( chatMessage = chatMessage, isLast = isLast, - isRead = isLast, onSeeAllChatClicked = { navigateTo(DeepLinkDestination.SeeAllChat(it)) }, modifier = Modifier.padding(itemPadding), ) diff --git a/feature/worker-home/src/main/java/com/idle/worker/home/WorkerHomeViewModel.kt b/feature/worker-home/src/main/java/com/idle/worker/home/WorkerHomeViewModel.kt index e7266c31..305027df 100644 --- a/feature/worker-home/src/main/java/com/idle/worker/home/WorkerHomeViewModel.kt +++ b/feature/worker-home/src/main/java/com/idle/worker/home/WorkerHomeViewModel.kt @@ -37,7 +37,8 @@ class WorkerHomeViewModel @Inject constructor( private val _profile = MutableStateFlow(null) val profile = _profile.asStateFlow() - private val next = MutableStateFlow(null) + private var nextCursorId: String? = null + private var nextDistance: Int = 15 private val _jobPostings = MutableStateFlow?>(null) val jobPostings = _jobPostings.asStateFlow() @@ -153,29 +154,34 @@ class WorkerHomeViewModel @Inject constructor( } private suspend fun fetchInAppJobPostings() { - jobPostingRepository.getJobPostings(next = next.value).onSuccess { (nextId, postings) -> - next.value = nextId - if (nextId == null) { - _callType.value = JobPostingCallType.CRAWLING - } - _jobPostings.value = _jobPostings.value?.plus(postings) ?: postings - - if (_jobPostings.value?.isEmpty() != false) { - getJobPostings() - } - }.onFailure { errorHelper.sendError(it) } - } - - private suspend fun fetchCrawlingJobPostings() { - jobPostingRepository.getCrawlingJobPostings(next = next.value) + jobPostingRepository.getJobPostings(next = nextCursorId) .onSuccess { (nextId, postings) -> - next.value = nextId + nextCursorId = nextId if (nextId == null) { - _callType.value = JobPostingCallType.END + _callType.value = JobPostingCallType.CRAWLING } _jobPostings.value = _jobPostings.value?.plus(postings) ?: postings + + if (_jobPostings.value?.isEmpty() != false) { + getJobPostings() + } }.onFailure { errorHelper.sendError(it) } } + + private suspend fun fetchCrawlingJobPostings() { + jobPostingRepository.getCrawlingJobPostings( + next = nextCursorId, + distance = nextDistance, + ).onSuccess { pageInfo -> + nextCursorId = pageInfo.nextCursor + nextDistance = pageInfo.nextDistance + + if (pageInfo.nextCursor == null) { + _callType.value = JobPostingCallType.END + } + _jobPostings.value = _jobPostings.value?.plus(pageInfo.items) ?: pageInfo.items + }.onFailure { errorHelper.sendError(it) } + } } enum class JobPostingCallType { diff --git a/feature/worker-job-posting/src/main/java/com/idle/worker/job/posting/WorkerJobPostingViewModel.kt b/feature/worker-job-posting/src/main/java/com/idle/worker/job/posting/WorkerJobPostingViewModel.kt index 7d41042d..4214cd04 100644 --- a/feature/worker-job-posting/src/main/java/com/idle/worker/job/posting/WorkerJobPostingViewModel.kt +++ b/feature/worker-job-posting/src/main/java/com/idle/worker/job/posting/WorkerJobPostingViewModel.kt @@ -35,7 +35,7 @@ class WorkerJobPostingViewModel @Inject constructor( private val _recruitmentPostStatus = MutableStateFlow(RecruitmentPostStatus.APPLY) val recruitmentPostStatus = _recruitmentPostStatus.asStateFlow() - private val next = MutableStateFlow(null) + private var nextCursorId: String? = null private val _appliedJobPostings = MutableStateFlow?>(null) val appliedJobPostings = _appliedJobPostings.asStateFlow() @@ -66,9 +66,7 @@ class WorkerJobPostingViewModel @Inject constructor( } internal fun getAppliedJobPostings() = viewModelScope.launch { - if (isLoading) { - return@launch - } + if (isLoading) return@launch isLoading = true try { @@ -76,16 +74,16 @@ class WorkerJobPostingViewModel @Inject constructor( return@launch } - jobPostingRepository.getJobPostingsApplied(next = next.value) - .onSuccess { (nextId, postings) -> - next.value = nextId + jobPostingRepository.getJobPostingsApplied(next = nextCursorId) + .onSuccess { nextPage -> + nextCursorId = nextPage.nextCursor - if (nextId == null) { + if (nextPage.nextCursor == null) { appliedJobPostingCallType = JobPostingCallType.END } _appliedJobPostings.value = - _appliedJobPostings.value?.plus(postings) ?: postings + _appliedJobPostings.value?.plus(nextPage.items) ?: nextPage.items }.onFailure { errorHelper.sendError(it) } } finally { isLoading = false @@ -213,5 +211,5 @@ enum class RecruitmentPostStatus(val displayName: String) { } enum class JobPostingCallType { - IN_APP, CRAWLING, END + IN_APP, END }