Skip to content
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
4 changes: 3 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ android {
}
}

// 룸 디비 제거
// 좋아요 기능 좀더 생각해보기

dependencies {
// 프로젝트 의존성
implementation(projects.core.resource)
Expand All @@ -83,7 +86,6 @@ dependencies {
implementation(projects.core.authKakao)
implementation(projects.core.network)
implementation(projects.core.datastore)
implementation(projects.core.database)

implementation(projects.data.account)
implementation(projects.data.library)
Expand Down
316 changes: 138 additions & 178 deletions app/src/main/java/com/into/websoso/data/repository/FeedRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.into.websoso.data.repository

import android.net.Uri
import com.into.websoso.core.common.util.ImageCompressor
import com.into.websoso.data.library.datasource.LibraryLocalDataSource
import com.into.websoso.data.mapper.MultiPartMapper
import com.into.websoso.data.mapper.toData
import com.into.websoso.data.model.CommentsEntity
Expand All @@ -20,201 +19,162 @@ import javax.inject.Singleton

@Singleton
class FeedRepository
@Inject
constructor(
private val feedApi: FeedApi,
private val multiPartMapper: MultiPartMapper,
private val imageDownloader: ImageDownloader,
private val imageCompressor: ImageCompressor,
private val libraryLocalDataSource: LibraryLocalDataSource,
) {
private val _cachedFeeds: MutableList<FeedEntity> = mutableListOf()
val cachedFeeds: List<FeedEntity> get() = _cachedFeeds.toList()

fun clearCachedFeeds() {
if (cachedFeeds.isNotEmpty()) _cachedFeeds.clear()
}

suspend fun fetchFeeds(
category: String,
lastFeedId: Long,
size: Int,
): FeedsEntity =
feedApi
.getFeeds(
category = if (category == "all") null else category,
lastFeedId = lastFeedId,
size = size,
).toData()
.also { _cachedFeeds.addAll(it.feeds) }
.copy(feeds = cachedFeeds)

suspend fun saveFeed(
relevantCategories: List<String>,
feedContent: String,
novelId: Long?,
isSpoiler: Boolean,
isPublic: Boolean,
images: List<Uri>,
) {
runCatching {
feedApi.postFeed(
feedRequestDto = multiPartMapper.formatToMultipart<FeedRequestDto>(
target = FeedRequestDto(
relevantCategories = relevantCategories,
feedContent = feedContent,
novelId = novelId,
isSpoiler = isSpoiler,
isPublic = isPublic,
),
partName = PART_NAME_FEED,
fileName = "feed.json",
),
images = images.map { multiPartMapper.formatToMultipart(it) },
)
}.onSuccess {
val novel = novelId?.let { id ->
libraryLocalDataSource.selectNovelByNovelId(id)
}

if (novel != null) {
val updatedNovel = novel.copy(myFeeds = listOf(feedContent) + novel.myFeeds)
libraryLocalDataSource.insertNovel(updatedNovel)
}
}
}

suspend fun saveEditedFeed(
feedId: Long,
relevantCategories: List<String>,
editedFeed: String,
legacyFeed: String,
novelId: Long?,
isSpoiler: Boolean,
isPublic: Boolean,
images: List<Uri>,
) {
runCatching {
feedApi.putFeed(
feedId = feedId,
feedRequestDto = multiPartMapper.formatToMultipart<FeedRequestDto>(
target = FeedRequestDto(
relevantCategories = relevantCategories,
feedContent = editedFeed,
novelId = novelId,
isSpoiler = isSpoiler,
isPublic = isPublic,
),
partName = "feed",
fileName = "feed.json",
),
images = images.map { multiPartMapper.formatToMultipart(it) },
)
}.onSuccess {
val novel = novelId?.let { id ->
libraryLocalDataSource.selectNovelByNovelId(id)
}

if (novel != null) {
val updatedNovel = novel.copy(
myFeeds = novel.myFeeds.map { currentFeed ->
if (currentFeed == legacyFeed) editedFeed else currentFeed
},
)
libraryLocalDataSource.insertNovel(updatedNovel)
}
}
}
@Inject
constructor(
private val feedApi: FeedApi,
private val multiPartMapper: MultiPartMapper,
private val imageDownloader: ImageDownloader,
private val imageCompressor: ImageCompressor,
) {
private val _cachedFeeds: MutableList<FeedEntity> = mutableListOf()
val cachedFeeds: List<FeedEntity> get() = _cachedFeeds.toList()

fun clearCachedFeeds() {
if (cachedFeeds.isNotEmpty()) _cachedFeeds.clear()
}

suspend fun fetchFeed(feedId: Long): FeedDetailEntity = feedApi.getFeed(feedId).toData()
suspend fun fetchFeeds(
category: String,
lastFeedId: Long,
size: Int,
): FeedsEntity =
feedApi
.getFeeds(
category = if (category == "all") null else category,
lastFeedId = lastFeedId,
size = size,
).toData()
.also { _cachedFeeds.addAll(it.feeds) }
.copy(feeds = cachedFeeds)

suspend fun saveFeed(
relevantCategories: List<String>,
feedContent: String,
novelId: Long?,
isSpoiler: Boolean,
isPublic: Boolean,
images: List<Uri>,
) {
feedApi.postFeed(
feedRequestDto = multiPartMapper.formatToMultipart<FeedRequestDto>(
target = FeedRequestDto(
relevantCategories = relevantCategories,
feedContent = feedContent,
novelId = novelId,
isSpoiler = isSpoiler,
isPublic = isPublic,
),
partName = PART_NAME_FEED,
fileName = "feed.json",
),
images = images.map { multiPartMapper.formatToMultipart(it) },
)
}

suspend fun fetchPopularFeeds(): PopularFeedsEntity = feedApi.getPopularFeeds().toData()
suspend fun saveEditedFeed(
feedId: Long,
relevantCategories: List<String>,
editedFeed: String,
novelId: Long?,
isSpoiler: Boolean,
isPublic: Boolean,
images: List<Uri>,
) {
feedApi.putFeed(
feedId = feedId,
feedRequestDto = multiPartMapper.formatToMultipart<FeedRequestDto>(
target = FeedRequestDto(
relevantCategories = relevantCategories,
feedContent = editedFeed,
novelId = novelId,
isSpoiler = isSpoiler,
isPublic = isPublic,
),
partName = "feed",
fileName = "feed.json",
),
images = images.map { multiPartMapper.formatToMultipart(it) },
)
}

suspend fun fetchUserInterestFeeds(): UserInterestFeedsEntity = feedApi.getUserInterestFeeds().toData()
suspend fun fetchFeed(feedId: Long): FeedDetailEntity = feedApi.getFeed(feedId).toData()

suspend fun saveRemovedFeed(
feedId: Long,
novelId: Long?,
content: String,
) {
runCatching {
feedApi.deleteFeed(feedId)
}.onSuccess {
_cachedFeeds.removeIf { it.id == feedId }
suspend fun fetchPopularFeeds(): PopularFeedsEntity = feedApi.getPopularFeeds().toData()

val novel = novelId?.let { id ->
libraryLocalDataSource.selectNovelByNovelId(id)
}
suspend fun fetchUserInterestFeeds(): UserInterestFeedsEntity =
feedApi.getUserInterestFeeds().toData()

if (novel != null) {
val updatedNovel = novel.copy(myFeeds = novel.myFeeds.filterNot { it == content })
libraryLocalDataSource.insertNovel(updatedNovel)
}
}
suspend fun saveRemovedFeed(feedId: Long) {
runCatching {
feedApi.deleteFeed(feedId)
}.onSuccess {
_cachedFeeds.removeIf { it.id == feedId }
}
}

suspend fun saveSpoilerFeed(feedId: Long) {
feedApi.postSpoilerFeed(feedId)
}
suspend fun saveSpoilerFeed(feedId: Long) {
feedApi.postSpoilerFeed(feedId)
}

suspend fun saveImpertinenceFeed(feedId: Long) {
feedApi.postImpertinenceFeed(feedId)
}
suspend fun saveImpertinenceFeed(feedId: Long) {
feedApi.postImpertinenceFeed(feedId)
}

suspend fun saveLike(
isLikedOfLikedFeed: Boolean,
selectedFeedId: Long,
) {
when (isLikedOfLikedFeed) {
true -> feedApi.deleteLikes(selectedFeedId)
false -> feedApi.postLikes(selectedFeedId)
}
suspend fun saveLike(
isLikedOfLikedFeed: Boolean,
selectedFeedId: Long,
) {
when (isLikedOfLikedFeed) {
true -> feedApi.deleteLikes(selectedFeedId)
false -> feedApi.postLikes(selectedFeedId)
}
}

suspend fun fetchComments(feedId: Long): CommentsEntity = feedApi.getComments(feedId).toData()
suspend fun fetchComments(feedId: Long): CommentsEntity = feedApi.getComments(feedId).toData()

suspend fun saveComment(
feedId: Long,
comment: String,
) {
feedApi.postComment(feedId, CommentRequestDto(comment))
}
suspend fun saveComment(
feedId: Long,
comment: String,
) {
feedApi.postComment(feedId, CommentRequestDto(comment))
}

suspend fun saveModifiedComment(
feedId: Long,
commentId: Long,
comment: String,
) {
feedApi.putComment(feedId, commentId, CommentRequestDto(comment))
}
suspend fun saveModifiedComment(
feedId: Long,
commentId: Long,
comment: String,
) {
feedApi.putComment(feedId, commentId, CommentRequestDto(comment))
}

suspend fun deleteComment(
feedId: Long,
commentId: Long,
) {
feedApi.deleteComment(feedId, commentId)
}
suspend fun deleteComment(
feedId: Long,
commentId: Long,
) {
feedApi.deleteComment(feedId, commentId)
}

suspend fun saveSpoilerComment(
feedId: Long,
commentId: Long,
) {
feedApi.postSpoilerComment(feedId, commentId)
}
suspend fun saveSpoilerComment(
feedId: Long,
commentId: Long,
) {
feedApi.postSpoilerComment(feedId, commentId)
}

suspend fun saveImpertinenceComment(
feedId: Long,
commentId: Long,
) {
feedApi.postImpertinenceComment(feedId, commentId)
}
suspend fun saveImpertinenceComment(
feedId: Long,
commentId: Long,
) {
feedApi.postImpertinenceComment(feedId, commentId)
}

suspend fun downloadImage(imageUrl: String): Result<Uri?> = imageDownloader.formatImageToUri(imageUrl)
suspend fun downloadImage(imageUrl: String): Result<Uri?> =
imageDownloader.formatImageToUri(imageUrl)

suspend fun compressImages(imageUris: List<Uri>): List<Uri> = imageCompressor.compressUris(imageUris)
suspend fun compressImages(imageUris: List<Uri>): List<Uri> =
imageCompressor.compressUris(imageUris)

companion object {
private const val PART_NAME_FEED: String = "feed"
private const val FILE_NAME_FEED: String = "feed.json"
}
companion object {
private const val PART_NAME_FEED: String = "feed"
}
}
Loading