Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT/#328] 탐색 뷰 / 페이징 추가 #329

Merged
merged 9 commits into from
Jan 13, 2025
Merged
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
3 changes: 3 additions & 0 deletions data/search/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ android {
dependencies {
// domain
implementation(projects.domain.search)

// paging
implementation(libs.androidx.paging.common.android)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class SearchDataSourceImpl @Inject constructor(
request.keyword,
request.sortBy,
request.page,
request.size
)

override suspend fun getSearchViews(): BaseResponse<SearchAnnouncementResponseDto> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,4 @@ data class SearchRequestDto(
val sortBy: String,
@SerialName("page")
val page: Int,
@SerialName("size")
val size: Int,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ package com.terning.data.search.mapper
import com.terning.data.search.dto.response.SearchResultResponseDto
import com.terning.domain.search.entity.SearchResult

fun SearchResultResponseDto.toSearchResultList(): List<SearchResult> {
return announcements.map {
SearchResult(
internshipAnnouncementId = it.internshipAnnouncementId,
title = it.title,
dDay = it.dDay,
workingPeriod = it.workingPeriod,
companyImage = it.companyImage,
isScrapped = it.isScrapped,
deadline = it.deadline,
startYearMonth = it.startYearMonth,
color = it.color
)
}
}
fun SearchResultResponseDto.SearchAnnouncementDto.toSearchResultList(totalCount: Int): SearchResult =
SearchResult(
totalCount = totalCount,
internshipAnnouncementId = this.internshipAnnouncementId,
title = this.title,
dDay = this.dDay,
workingPeriod = this.workingPeriod,
companyImage = this.companyImage,
isScrapped = this.isScrapped,
deadline = this.deadline,
startYearMonth = this.startYearMonth,
color = this.color,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.terning.data.search.pagingsource

import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.terning.data.search.datasource.SearchDataSource
import com.terning.data.search.dto.request.SearchRequestDto
import com.terning.data.search.dto.response.SearchResultResponseDto

class SearchPagingSource(
private val query: String,
private val sortBy: String,
private val dataSource: SearchDataSource,
) : PagingSource<Int, Pair<Int, SearchResultResponseDto.SearchAnnouncementDto>>() {

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Pair<Int, SearchResultResponseDto.SearchAnnouncementDto>> {
return try {
val nextParamKey = params.key ?: 0

val response = dataSource.getSearch(
request = SearchRequestDto(
keyword = query,
sortBy = sortBy,
page = nextParamKey,
)
)
val totalCount = response.result.totalCount
val hasNextPage = response.result.hasNext

val nextKey = if (hasNextPage) nextParamKey + 1 else null

LoadResult.Page(
data = response.result.announcements.map {
Pair(totalCount, it)
},
prevKey = null,
nextKey = nextKey
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}

override fun getRefreshKey(state: PagingState<Int, Pair<Int, SearchResultResponseDto.SearchAnnouncementDto>>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,43 @@
package com.terning.data.search.repositoryimpl

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.map
import com.terning.data.search.datasource.SearchDataSource
import com.terning.data.search.dto.request.SearchRequestDto
import com.terning.data.search.mapper.toSearchBannerList
import com.terning.data.search.mapper.toSearchPopularAnnouncementList
import com.terning.data.search.mapper.toSearchResultList
import com.terning.data.search.pagingsource.SearchPagingSource
import com.terning.domain.search.entity.SearchBanner
import com.terning.domain.search.entity.SearchPopularAnnouncement
import com.terning.domain.search.entity.SearchResult
import com.terning.domain.search.repository.SearchRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

class SearchRepositoryImpl @Inject constructor(
private val searchDataSource: SearchDataSource,
) : SearchRepository {
override suspend fun getSearchList(

override fun getSearchList(
query: String,
sortBy: String,
page: Int,
size: Int,
): Result<List<SearchResult>> {
return runCatching {
searchDataSource.getSearch(
SearchRequestDto(
keyword = query,
sortBy = sortBy,
page = page,
size = size
)
).result.toSearchResultList()
): Flow<PagingData<SearchResult>> {
return Pager(
PagingConfig(
pageSize = 10,
enablePlaceholders = false
)
) {
SearchPagingSource(
query = query,
sortBy = sortBy,
dataSource = searchDataSource
)
}.flow.map { pagedData ->
pagedData.map { it.second.toSearchResultList(it.first) }
}
}

Expand All @@ -43,7 +52,7 @@ class SearchRepositoryImpl @Inject constructor(
}

override suspend fun getSearchBannersList(): Result<List<SearchBanner>> =
kotlin.runCatching {
runCatching {
searchDataSource.getSearchBanners().result.toSearchBannerList()
}
}
4 changes: 4 additions & 0 deletions domain/search/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
plugins {
alias(libs.plugins.terning.kotlin)
}

dependencies {
implementation(libs.paging.common)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.terning.domain.search.entity

data class SearchResult(
val totalCount: Int,
val internshipAnnouncementId: Long,
val title: String,
val dDay: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.terning.domain.search.repository

import androidx.paging.PagingData
import com.terning.domain.search.entity.SearchBanner
import com.terning.domain.search.entity.SearchPopularAnnouncement
import com.terning.domain.search.entity.SearchResult
import kotlinx.coroutines.flow.Flow

interface SearchRepository {
suspend fun getSearchList(

fun getSearchList(
query: String,
sortBy: String,
page: Int,
size: Int,
): Result<List<SearchResult>>
): Flow<PagingData<SearchResult>>

suspend fun getSearchViewsList(): Result<List<SearchPopularAnnouncement>>
suspend fun getSearchScrapsList(): Result<List<SearchPopularAnnouncement>>
Expand Down
4 changes: 4 additions & 0 deletions feature/search/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ dependencies {

// feature
implementation(projects.feature.dialog)

// paging
implementation(libs.paging.runtime)
implementation(libs.paging.compose)
}
Loading
Loading