-
Notifications
You must be signed in to change notification settings - Fork 0
[feat] #59, #64, #69 아카이브 API 연동 및 페이징 구현 #73
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
Merged
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
197d1e8
[chore] #64: `core:data-api` 모듈을 Android 라이브러리로 변경
ikseong00 367fd97
[feat] #64: 미디어 업로드 티켓 발급 API 분리 및 URI/URL 업로드 기능 추가
ikseong00 1bc5510
[feat] #64: 여러 장의 사진을 업로드하는 UseCase 추가
ikseong00 cb51a9a
[feat] #64: MediaUploadRepository 이미지 업로드 기능 구현
ikseong00 94b2c4d
[refactor] #64: 이미지 업로드 방식을 ByteArray에서 URL로 변경
ikseong00 ba9933a
[feat] #64: 이미지 여러 장 업로드 기능 구현
ikseong00 e82e376
[feat] #69: 폴더 생성 및 목록 조회 API 구현
ikseong00 956d3c9
[feat] #69: 앨범 목록 조회 기능 추가
ikseong00 1b9f5b6
[feat] #69: 새 앨범 추가 기능 구현
ikseong00 e566956
[feat] #69: 전체 앨범 화면 API 연동
ikseong00 41c8a06
[feat] #69: 업로드 시 앨범 목록 조회 기능 추가
ikseong00 9a3ea5e
[feat] #69: 앨범 상세화면 사진 목록 API 연동
ikseong00 08cc5de
[feat] #59: 사진 목록 페이징 기능 구현
ikseong00 7a7695e
[feat] #59: 앨범 상세 화면 Paging 적용
ikseong00 491f052
[feat] #70: 전체 사진 화면 Paging 적용
ikseong00 f2ca191
[refactor] #59: Paging 초기 로드 사이즈 조정
ikseong00 3e2d451
[refactor] #69: 앨범 상세 화면 이동 시 albumId 대신 AlbumPreview 객체 전달
ikseong00 1fd2acd
[feat] #69: 모든 앨범 앨범 추가 API 연동
ikseong00 5b2b0f1
[feat] #69: 앨범 추가 성공 시 fetch api 호출
ikseong00 82c8897
[refactor] #69: 폴더 생성 API 응답 타입 변경 및 불필요한 반환값 제거
ikseong00 7d9cea1
[feat] #69: 앨범 삭제 기능 구현
ikseong00 b3613cb
[refactor] #59: 사진 그리드 레이아웃 관련 상수명 변경 및 적용
ikseong00 84db147
[refactor] #69 일반 앨범에서 사진 삭제 로직 구현
ikseong00 447dbb8
[feat] #69: 전체 사진 화면 필터링 기능 적용
ikseong00 597c7f9
[refactor] #69: ScrollToTop Effect 수신 후, LoadState가 완료된 후에, scrollToI…
ikseong00 a3671f2
[fix] #64: 여러 개 업로드 타입 오류 수정
ikseong00 221d8b4
[refactor] #64: 사진 여러개 업로드 병렬 및 Dispatcher 적용
ikseong00 4bd7919
[refactor] #59: 프리페치 거리 조정
ikseong00 4a0e1e1
[fix] #69: 앨범 상세화면에서 사진 삭제 실패 시 다이얼로그/바텀시트가 닫히지 않는 버그 수정
ikseong00 e5fb897
[chore] #69: 린트 수정
ikseong00 44dc5ea
[refactor] #69: 포토카드 상세화면 결과 타입을 ArchiveResult로 변경
ikseong00 f1b12f3
[refactor] #69: 앨범 이름 중복 검사 로직 개선
ikseong00 d5f26e4
[refactor] #64: 업로드 타입 로직 변경
ikseong00 36095a6
[feat] #69: 사진 상세에서 삭제/즐겨찾기 변경 시 목록 화면 동기화
ikseong00 8c7521f
[fix] #69: entry 중첩 구조 오류 수정
ikseong00 ac6e255
[refactor] #64: 업로드 타입 로직 변경
ikseong00 fb2196a
Merge branch 'develop' into feat/#59,64,69-archive-api
ikseong00 1f52203
[build] #59,64,69: detekt 린트 수정
ikseong00 7bdf2b6
[refactor] 아카이브 EntryProvider 통합
ikseong00 75ed9d5
[feat] #70: 폴더 삭제 API deletePhotos 쿼리 추가 및 앨범 사진 삭제 옵션별 분기 구현
ikseong00 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,14 @@ | ||
| plugins { | ||
| alias(libs.plugins.neki.kotlin.library) | ||
| alias(libs.plugins.neki.android.library) | ||
| } | ||
|
|
||
| android { | ||
| namespace = "com.neki.android.core.dataapi" | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation(projects.core.model) | ||
| implementation(libs.kotlinx.coroutines.core) | ||
| api(libs.androidx.datastore.preferences) | ||
| api(libs.androidx.paging.runtime) | ||
| } |
10 changes: 10 additions & 0 deletions
10
core/data-api/src/main/java/com/neki/android/core/dataapi/repository/FolderRepository.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.neki.android.core.dataapi.repository | ||
|
|
||
| import com.neki.android.core.model.AlbumPreview | ||
|
|
||
| interface FolderRepository { | ||
| suspend fun getFolders(): Result<List<AlbumPreview>> | ||
| suspend fun createFolder(name: String): Result<Unit> | ||
| suspend fun deleteFolder(id: List<Long>, deletePhotos: Boolean): Result<Unit> | ||
| suspend fun removePhotosFromFolder(folderId: Long, photoIds: List<Long>): Result<Unit> | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
core/data/src/main/java/com/neki/android/core/data/paging/FavoritePhotoPagingSource.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package com.neki.android.core.data.paging | ||
|
|
||
| import androidx.paging.PagingSource | ||
| import androidx.paging.PagingState | ||
| import com.neki.android.core.data.remote.api.PhotoService | ||
| import com.neki.android.core.model.Photo | ||
| import com.neki.android.core.model.SortOrder | ||
|
|
||
| class FavoritePhotoPagingSource( | ||
| private val photoService: PhotoService, | ||
| private val sortOrder: SortOrder, | ||
| ) : PagingSource<Int, Photo>() { | ||
|
|
||
| override fun getRefreshKey(state: PagingState<Int, Photo>): Int? { | ||
| return state.anchorPosition?.let { anchorPosition -> | ||
| state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1) | ||
| ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1) | ||
| } | ||
| } | ||
|
|
||
| override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Photo> { | ||
| return try { | ||
| val page = params.key ?: 0 | ||
| val response = photoService.getFavoritePhotos( | ||
| page = page, | ||
| size = params.loadSize, | ||
| sortOrder = sortOrder.name, | ||
| ) | ||
| val photos = response.data.toModels() | ||
| val hasNext = response.data.hasNext | ||
|
|
||
| LoadResult.Page( | ||
| data = photos, | ||
| prevKey = if (page == 0) null else page - 1, | ||
| nextKey = if (hasNext) page + 1 else null, | ||
| ) | ||
| } catch (e: Exception) { | ||
| LoadResult.Error(e) | ||
| } | ||
| } | ||
| } |
42 changes: 42 additions & 0 deletions
42
core/data/src/main/java/com/neki/android/core/data/paging/PhotoPagingSource.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package com.neki.android.core.data.paging | ||
|
|
||
| import androidx.paging.PagingSource | ||
| import androidx.paging.PagingState | ||
| import com.neki.android.core.data.remote.api.PhotoService | ||
| import com.neki.android.core.model.Photo | ||
|
|
||
| class PhotoPagingSource( | ||
| private val photoService: PhotoService, | ||
| private val folderId: Long?, | ||
| private val sortOrder: String, | ||
| ) : PagingSource<Int, Photo>() { | ||
|
|
||
| override fun getRefreshKey(state: PagingState<Int, Photo>): Int? { | ||
| return state.anchorPosition?.let { anchorPosition -> | ||
| state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1) | ||
| ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1) | ||
| } | ||
| } | ||
|
|
||
| override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Photo> { | ||
| return try { | ||
| val page = params.key ?: 0 | ||
| val response = photoService.getPhotos( | ||
| folderId = folderId, | ||
| page = page, | ||
| size = params.loadSize, | ||
| sortOrder = sortOrder, | ||
| ) | ||
| val photos = response.data.toModels() | ||
| val hasNext = response.data.hasNext | ||
|
|
||
| LoadResult.Page( | ||
| data = photos, | ||
| prevKey = if (page == 0) null else page - 1, | ||
| nextKey = if (hasNext) page + 1 else null, | ||
| ) | ||
| } catch (e: Exception) { | ||
| LoadResult.Error(e) | ||
| } | ||
| } | ||
| } | ||
46 changes: 46 additions & 0 deletions
46
core/data/src/main/java/com/neki/android/core/data/remote/api/FolderService.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package com.neki.android.core.data.remote.api | ||
|
|
||
| import com.neki.android.core.data.remote.model.request.CreateFolderRequest | ||
| import com.neki.android.core.data.remote.model.request.DeleteFolderRequest | ||
| import com.neki.android.core.data.remote.model.request.DeletePhotoRequest | ||
| import com.neki.android.core.data.remote.model.response.BasicNullableResponse | ||
| import com.neki.android.core.data.remote.model.response.BasicResponse | ||
| import com.neki.android.core.data.remote.model.response.CreateFolderResponse | ||
| import com.neki.android.core.data.remote.model.response.FolderResponse | ||
| import io.ktor.client.HttpClient | ||
| import io.ktor.client.call.body | ||
| import io.ktor.client.request.delete | ||
| import io.ktor.client.request.get | ||
| import io.ktor.client.request.parameter | ||
| import io.ktor.client.request.post | ||
| import io.ktor.client.request.setBody | ||
| import javax.inject.Inject | ||
|
|
||
| class FolderService @Inject constructor( | ||
| private val client: HttpClient, | ||
| ) { | ||
| // 폴더 목록 조회 | ||
| suspend fun getFolders(): BasicResponse<FolderResponse> { | ||
| return client.get("/api/folders").body() | ||
| } | ||
|
|
||
| // 폴더 생성 | ||
| suspend fun createFolder(requestBody: CreateFolderRequest): BasicNullableResponse<CreateFolderResponse> { | ||
| return client.post("/api/folders") { setBody(requestBody) }.body() | ||
| } | ||
|
|
||
| // 폴더 삭제 | ||
| suspend fun deleteFolder(requestBody: DeleteFolderRequest, deletePhotos: Boolean): BasicNullableResponse<Unit> { | ||
| return client.delete("/api/folders") { | ||
| setBody(requestBody) | ||
| parameter("deletePhotos", deletePhotos) | ||
| }.body() | ||
| } | ||
|
|
||
| // 폴더에서 사진 제거 (사진 자체는 삭제되지 않음) | ||
| suspend fun removePhotosFromFolder(folderId: Long, requestBody: DeletePhotoRequest): BasicNullableResponse<Unit> { | ||
| return client.delete("/api/folders/$folderId/photos") { | ||
| setBody(requestBody) | ||
| }.body() | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
...data/src/main/java/com/neki/android/core/data/remote/model/request/CreateFolderRequest.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package com.neki.android.core.data.remote.model.request | ||
|
|
||
| import kotlinx.serialization.SerialName | ||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class CreateFolderRequest( | ||
| @SerialName("name") val name: String, | ||
| ) |
9 changes: 9 additions & 0 deletions
9
...data/src/main/java/com/neki/android/core/data/remote/model/request/DeleteFolderRequest.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package com.neki.android.core.data.remote.model.request | ||
|
|
||
| import kotlinx.serialization.SerialName | ||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class DeleteFolderRequest( | ||
| @SerialName("folderIds") val folderIds: List<Long>, | ||
| ) |
10 changes: 10 additions & 0 deletions
10
...ta/src/main/java/com/neki/android/core/data/remote/model/response/CreateFolderResponse.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.neki.android.core.data.remote.model.response | ||
|
|
||
| import kotlinx.serialization.SerialName | ||
| import kotlinx.serialization.Serializable | ||
|
|
||
| // TODO: 추후 API 스펙 업데이트 시 제거 | ||
| @Serializable | ||
| data class CreateFolderResponse( | ||
| @SerialName("folderId") val folderId: Long, | ||
| ) |
27 changes: 27 additions & 0 deletions
27
core/data/src/main/java/com/neki/android/core/data/remote/model/response/FolderResponse.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package com.neki.android.core.data.remote.model.response | ||
|
|
||
| import com.neki.android.core.model.AlbumPreview | ||
| import kotlinx.serialization.SerialName | ||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class FolderResponse( | ||
| @SerialName("items") val items: List<Item>, | ||
| ) { | ||
| @Serializable | ||
| data class Item( | ||
| @SerialName("folderId") val folderId: Long, | ||
| @SerialName("name") val name: String, | ||
| @SerialName("latestImageUrl") val latestImageUrl: String?, | ||
| @SerialName("totalCount") val totalCount: Int, | ||
| ) { | ||
| internal fun toModel() = AlbumPreview( | ||
| id = folderId, | ||
| title = name, | ||
| thumbnailUrl = latestImageUrl, | ||
| photoCount = totalCount, | ||
| ) | ||
| } | ||
|
|
||
| fun toModels() = items.map { it.toModel() } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
core/data/src/main/java/com/neki/android/core/data/repository/impl/FolderRepositoryImpl.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package com.neki.android.core.data.repository.impl | ||
|
|
||
| import com.neki.android.core.data.remote.api.FolderService | ||
| import com.neki.android.core.data.remote.model.request.CreateFolderRequest | ||
| import com.neki.android.core.data.remote.model.request.DeleteFolderRequest | ||
| import com.neki.android.core.data.remote.model.request.DeletePhotoRequest | ||
| import com.neki.android.core.data.util.runSuspendCatching | ||
| import com.neki.android.core.dataapi.repository.FolderRepository | ||
| import com.neki.android.core.model.AlbumPreview | ||
| import javax.inject.Inject | ||
|
|
||
| class FolderRepositoryImpl @Inject constructor( | ||
| private val folderService: FolderService, | ||
| ) : FolderRepository { | ||
| override suspend fun getFolders(): Result<List<AlbumPreview>> = runSuspendCatching { | ||
| folderService.getFolders().data.toModels() | ||
| } | ||
|
|
||
| override suspend fun createFolder(name: String): Result<Unit> = runSuspendCatching { | ||
| folderService.createFolder( | ||
| requestBody = CreateFolderRequest(name = name), | ||
| ).data | ||
| } | ||
|
|
||
| override suspend fun deleteFolder(id: List<Long>, deletePhotos: Boolean): Result<Unit> = runSuspendCatching { | ||
| folderService.deleteFolder( | ||
| requestBody = DeleteFolderRequest(folderIds = id), | ||
| deletePhotos = deletePhotos, | ||
| ).data | ||
| } | ||
|
|
||
| override suspend fun removePhotosFromFolder(folderId: Long, photoIds: List<Long>): Result<Unit> = runSuspendCatching { | ||
| folderService.removePhotosFromFolder( | ||
| folderId = folderId, | ||
| requestBody = DeletePhotoRequest(photoIds = photoIds), | ||
| ).data | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.