Skip to content

Commit

Permalink
Feat : Delete Post Firestore connect
Browse files Browse the repository at this point in the history
- #53
  • Loading branch information
inwoo13 committed Nov 28, 2024
1 parent 392d41b commit 2922c0a
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface PostDataSource {
key: String?,
perPage: Long
): Result<List<PostModel>>

suspend fun deletePost(postId: String): Result<Unit>
suspend fun getUserFollowerPost(uid: String, perPage: Long): Result<List<PostModel>>
}

Expand Down Expand Up @@ -154,4 +154,11 @@ class PostDataSourceImpl @Inject constructor(
}
}

override suspend fun deletePost(postId: String): Result<Unit> {
return runCatching {
throw Exception("Test")
val documentId = postId.substringAfter("-")
postCollection.document(documentId).delete().await()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import com.kolown.data.remote.ReactionDto
import com.kolown.data.remote.toReactionModel
import com.kolown.model.ReactionModel
import com.kolown.model.Reactions
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.tasks.await
import java.io.IOException
import javax.inject.Inject
Expand All @@ -15,6 +18,7 @@ interface ReactionDataSource {
suspend fun getReactionByPostId(postId: String): Result<List<ReactionModel>>
suspend fun updatePostReaction(userId: String, postId: String, reaction: Reactions)
suspend fun removePostReaction(userId: String, postId: String): Result<Unit>
suspend fun deletePostReaction(postId: String): Result<Unit>
}

class ReactionDataSourceImpl @Inject constructor(
Expand Down Expand Up @@ -73,6 +77,20 @@ class ReactionDataSourceImpl @Inject constructor(
}
}

override suspend fun deletePostReaction(postId: String): Result<Unit> {
return runCatching {
val reactions = reactionCollection.whereEqualTo("postId", postId).get().await()

coroutineScope {
reactions.documents.map {
async {
reactionCollection.document(it.id).delete().await()
}
}.awaitAll()
}
}
}

private suspend fun CollectionReference.contains(
postId: String,
userId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface TagDataSource {
suspend fun getPostTag(postId: String): Result<List<TagModel>>
suspend fun getPostTagByTagId(tagId: String): Result<List<String>>
suspend fun getTagBySearch(searchText: String,key:String?,perPage:Long) : Result<List<Tag>>
suspend fun deletePostTag(postId: String): Result<Unit>
}

class TagDataSourceImpl @Inject constructor(
Expand Down Expand Up @@ -131,6 +132,20 @@ class TagDataSourceImpl @Inject constructor(
}
}

override suspend fun deletePostTag(postId: String): Result<Unit> {
return runCatching {
val postTags = postTagCollection.whereEqualTo("postId", postId).get().await()

coroutineScope {
postTags.documents.map {
async {
postTagCollection.document(it.id).delete().await()
}
}.awaitAll()
}
}
}

private suspend fun CollectionReference.contains(
field: String,
value: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kolown.data.repository

import android.net.Uri
import android.util.Log
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
Expand Down Expand Up @@ -38,6 +39,7 @@ interface PostRepository {
suspend fun removePostReaction(postId: String): Result<Unit>
fun getUserPosts(userId: String? = null): Flow<PagingData<PostContentModel>>
suspend fun getPostBySearch(tagId: String): Flow<PagingData<PostContentModel>>
suspend fun deletePost(postId: String): Flow<Boolean>
}

class PostRepositoryImpl @Inject constructor(
Expand Down Expand Up @@ -215,6 +217,46 @@ class PostRepositoryImpl @Inject constructor(
).flow
}

override suspend fun deletePost(postId: String): Flow<Boolean> = flow {
coroutineScope {
val deletePostTagDeferred = async {
retryWithLimit {
tagDataSource.deletePostTag(postId).getOrElse {
throw IOException("포스트 태그 삭제 실패")
}
}
}
val deleteReactionDeferred = async {
retryWithLimit {
reactionDataSource.deletePostReaction(postId).getOrElse {
throw IOException("리액션 삭제 실패")
}
}
}
val deletePostDeferred = async {
retryWithLimit {
postDataSource.deletePost(postId).getOrElse {
throw IOException("게시물 삭제 실패")
}
}
}

val results = awaitAll(
deletePostTagDeferred,
deleteReactionDeferred,
deletePostDeferred
)

val allSuccess = results.all { it.isSuccess }

if(allSuccess) {
emit(true)
} else {
throw IOException("하나 이상의 작업이 실패하였습니다.")
}
}
}

private suspend fun updateImageUrl(postId: String, fileUri: Uri): Result<Unit> {
return runCatching {
val authorId = googleAuthDataSource.getUserId()
Expand Down
4 changes: 3 additions & 1 deletion feature/my/src/main/java/com/kolown/my/MyScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ fun MyScreen(
content = {
items(pagingItems.itemCount) { index ->
pagingItems[index]?.let {
GalleryItem(it, width)
GalleryItem(it, width) {
viewModel.deletePost(it.postId)
}
}
}

Expand Down
18 changes: 18 additions & 0 deletions feature/my/src/main/java/com/kolown/my/MyViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.kolown.my

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.cachedIn
Expand All @@ -8,7 +9,11 @@ import com.kolown.data.di.Fake
import com.kolown.data.repository.GalleryRepository
import com.kolown.data.repository.PostRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
Expand All @@ -17,4 +22,17 @@ class MyViewModel @Inject constructor(
) : ViewModel() {
val galleryFlow = postRepository.getUserPosts().cachedIn(viewModelScope)

fun deletePost(postId: String) {
Log.e("GalleryItem", "postId: $postId")
viewModelScope.launch {
postRepository.deletePost(postId)
.onEach {
Log.e("GalleryItem", "deletePost: $it")
}
.catch {
Log.e("GalleryItem", "deletePost error: $it")
}
.launchIn(viewModelScope)
}
}
}
23 changes: 21 additions & 2 deletions feature/my/src/main/java/com/kolown/my/component/GalleryItem.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.kolown.my.component

import android.util.Log
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
Expand All @@ -15,16 +20,30 @@ import com.kolown.data.mock.MockDataProvider
import com.kolown.model.PostContentModel
import kotlin.random.Random

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GalleryItem(postContentModel: PostContentModel, width: Dp) {
fun GalleryItem(
postContentModel: PostContentModel,
width: Dp,
onLongClickImage: () -> Unit = {}
) {
//비율은 그냥 테스트
val height = if (Random.nextBoolean()) (width.value * 1.4).dp else width + 20.dp

AsyncImage(
modifier = Modifier
.fillMaxWidth()
.height(height)
.clip(RoundedCornerShape(10.dp)),
.clip(RoundedCornerShape(10.dp))
.combinedClickable (
onClick = {
// todo navigateToDetail
},
onLongClick = {
onLongClickImage()
Log.d("GalleryItem", "GalleryItem: LongClick")
}
),
model = postContentModel.imageUrl,
contentDescription = null,
contentScale = ContentScale.Crop
Expand Down

0 comments on commit 2922c0a

Please sign in to comment.