Skip to content

Commit 43781d2

Browse files
committed
✨ GroupDataSource 추상화
1 parent c191e9e commit 43781d2

File tree

3 files changed

+187
-152
lines changed

3 files changed

+187
-152
lines changed

data/src/main/java/com/whyranoid/data/di/GroupModule.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.whyranoid.data.di
22

3+
import com.whyranoid.data.group.GroupDataSource
4+
import com.whyranoid.data.group.GroupDataSourceImpl
35
import com.whyranoid.data.group.GroupRepositoryImpl
46
import com.whyranoid.domain.repository.GroupRepository
57
import dagger.Binds
@@ -11,6 +13,9 @@ import dagger.hilt.components.SingletonComponent
1113
@InstallIn(SingletonComponent::class)
1214
abstract class GroupModule {
1315

16+
@Binds
17+
abstract fun bindGroupDataSource(groupDataSourceImpl: GroupDataSourceImpl): GroupDataSource
18+
1419
@Binds
1520
abstract fun bindGroupRepository(groupRepositoryImpl: GroupRepositoryImpl): GroupRepository
1621
}
Lines changed: 7 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,30 @@
11
package com.whyranoid.data.group
22

3-
import com.google.firebase.firestore.FieldValue
4-
import com.google.firebase.firestore.FirebaseFirestore
5-
import com.whyranoid.data.constant.CollectionId.GROUPS_COLLECTION
6-
import com.whyranoid.data.constant.CollectionId.USERS_COLLECTION
7-
import com.whyranoid.data.constant.FieldId.GROUP_INTRODUCE
8-
import com.whyranoid.data.constant.FieldId.GROUP_MEMBERS_ID
9-
import com.whyranoid.data.constant.FieldId.GROUP_NAME
10-
import com.whyranoid.data.constant.FieldId.JOINED_GROUP_LIST
11-
import com.whyranoid.data.constant.FieldId.RULES
12-
import com.whyranoid.data.model.GroupInfoResponse
13-
import com.whyranoid.data.model.UserResponse
14-
import com.whyranoid.data.model.toGroupInfo
15-
import com.whyranoid.data.model.toUser
163
import com.whyranoid.domain.model.GroupInfo
174
import com.whyranoid.domain.model.Rule
18-
import com.whyranoid.domain.model.toRule
19-
import kotlinx.coroutines.channels.awaitClose
205
import kotlinx.coroutines.flow.Flow
21-
import kotlinx.coroutines.flow.callbackFlow
22-
import kotlinx.coroutines.suspendCancellableCoroutine
23-
import kotlinx.coroutines.tasks.await
24-
import java.util.UUID
25-
import javax.inject.Inject
26-
import kotlin.coroutines.resume
276

28-
class GroupDataSource @Inject constructor(
29-
private val db: FirebaseFirestore
30-
) {
7+
interface GroupDataSource {
318

329
suspend fun updateGroupInfo(
3310
groupId: String,
3411
groupName: String,
3512
groupIntroduce: String,
3613
rules: List<Rule>
37-
): Boolean {
38-
return suspendCancellableCoroutine { cancellableContinuation ->
39-
db.collection(GROUPS_COLLECTION)
40-
.document(groupId)
41-
.update(
42-
mapOf(
43-
GROUP_NAME to groupName,
44-
GROUP_INTRODUCE to groupIntroduce,
45-
RULES to rules.map { rule ->
46-
rule.toString()
47-
}
48-
)
49-
)
50-
.addOnSuccessListener {
51-
cancellableContinuation.resume(true)
52-
}
53-
.addOnFailureListener {
54-
cancellableContinuation.resume(false)
55-
}
56-
}
57-
}
14+
): Boolean
5815

59-
suspend fun joinGroup(uid: String, groupId: String): Boolean {
60-
return suspendCancellableCoroutine { cancellableContinuation ->
16+
suspend fun joinGroup(uid: String, groupId: String): Boolean
6117

62-
db.collection(USERS_COLLECTION)
63-
.document(uid)
64-
.update(
65-
JOINED_GROUP_LIST,
66-
FieldValue.arrayUnion(groupId)
67-
).addOnSuccessListener {
68-
db.collection(GROUPS_COLLECTION)
69-
.document(groupId)
70-
.update(
71-
GROUP_MEMBERS_ID,
72-
FieldValue.arrayUnion(uid)
73-
).addOnSuccessListener {
74-
cancellableContinuation.resume(true)
75-
}.addOnFailureListener {
76-
cancellableContinuation.resume(false)
77-
}
78-
}.addOnFailureListener {
79-
cancellableContinuation.resume(false)
80-
}
81-
}
82-
}
83-
84-
suspend fun exitGroup(uid: String, groupId: String): Boolean {
85-
return suspendCancellableCoroutine { cancellableContinuation ->
86-
db.collection(GROUPS_COLLECTION)
87-
.document(groupId)
88-
.update(
89-
mapOf(
90-
GROUP_MEMBERS_ID to FieldValue.arrayRemove(uid)
91-
)
92-
).addOnSuccessListener {
93-
db.collection(USERS_COLLECTION)
94-
.document(uid)
95-
.update(
96-
mapOf(
97-
JOINED_GROUP_LIST to FieldValue.arrayRemove(groupId)
98-
)
99-
)
100-
.addOnSuccessListener {
101-
cancellableContinuation.resume(true)
102-
}
103-
.addOnFailureListener {
104-
cancellableContinuation.resume(false)
105-
}
106-
}.addOnFailureListener {
107-
cancellableContinuation.resume(false)
108-
}
109-
}
110-
}
18+
suspend fun exitGroup(uid: String, groupId: String): Boolean
11119

11220
suspend fun createGroup(
11321
groupName: String,
11422
introduce: String,
11523
rules: List<String>,
11624
uid: String
117-
): Boolean {
118-
return suspendCancellableCoroutine { cancellableContinuation ->
119-
val newGroupId = UUID.randomUUID().toString()
120-
db.collection(GROUPS_COLLECTION)
121-
.document(newGroupId)
122-
.set(
123-
GroupInfoResponse(
124-
groupId = newGroupId,
125-
groupName = groupName,
126-
introduce = introduce,
127-
leaderId = uid,
128-
membersId = listOf(uid),
129-
rules = rules
130-
)
131-
).addOnSuccessListener {
132-
cancellableContinuation.resume(true)
133-
}.addOnFailureListener {
134-
cancellableContinuation.resume(false)
135-
}
136-
}
137-
}
138-
139-
fun getGroupInfoFlow(uid: String, groupId: String): Flow<GroupInfo> = callbackFlow {
140-
db.collection(GROUPS_COLLECTION)
141-
.document(groupId)
142-
.addSnapshotListener { documentSnapshot, _ ->
143-
val groupInfoResponse = documentSnapshot?.toObject(GroupInfoResponse::class.java)
144-
145-
groupInfoResponse?.let {
146-
db.collection(USERS_COLLECTION)
147-
.document(uid)
148-
.addSnapshotListener { documentSnapshot, _ ->
149-
val userResponse = documentSnapshot?.toObject(UserResponse::class.java)
25+
): Boolean
15026

151-
userResponse?.let {
152-
trySend(
153-
groupInfoResponse.toGroupInfo(
154-
leader = userResponse.toUser(),
155-
rules = groupInfoResponse.rules.map {
156-
it.toRule()
157-
}
158-
)
159-
)
160-
}
161-
}
162-
}
163-
}
164-
awaitClose()
165-
}
27+
fun getGroupInfoFlow(uid: String, groupId: String): Flow<GroupInfo>
16628

167-
suspend fun isDuplicatedGroupName(groupName: String): Boolean {
168-
return db.collection(GROUPS_COLLECTION)
169-
.whereEqualTo(GROUP_NAME, groupName)
170-
.get()
171-
.await()
172-
.isEmpty
173-
.not()
174-
}
29+
suspend fun isDuplicatedGroupName(groupName: String): Boolean
17530
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package com.whyranoid.data.group
2+
3+
import com.google.firebase.firestore.FieldValue
4+
import com.google.firebase.firestore.FirebaseFirestore
5+
import com.whyranoid.data.constant.CollectionId.GROUPS_COLLECTION
6+
import com.whyranoid.data.constant.CollectionId.USERS_COLLECTION
7+
import com.whyranoid.data.constant.FieldId.GROUP_INTRODUCE
8+
import com.whyranoid.data.constant.FieldId.GROUP_MEMBERS_ID
9+
import com.whyranoid.data.constant.FieldId.GROUP_NAME
10+
import com.whyranoid.data.constant.FieldId.JOINED_GROUP_LIST
11+
import com.whyranoid.data.constant.FieldId.RULES
12+
import com.whyranoid.data.model.GroupInfoResponse
13+
import com.whyranoid.data.model.UserResponse
14+
import com.whyranoid.data.model.toGroupInfo
15+
import com.whyranoid.data.model.toUser
16+
import com.whyranoid.domain.model.GroupInfo
17+
import com.whyranoid.domain.model.Rule
18+
import com.whyranoid.domain.model.toRule
19+
import kotlinx.coroutines.channels.awaitClose
20+
import kotlinx.coroutines.flow.Flow
21+
import kotlinx.coroutines.flow.callbackFlow
22+
import kotlinx.coroutines.suspendCancellableCoroutine
23+
import kotlinx.coroutines.tasks.await
24+
import java.util.UUID
25+
import javax.inject.Inject
26+
import kotlin.coroutines.resume
27+
28+
class GroupDataSourceImpl @Inject constructor(
29+
private val db: FirebaseFirestore
30+
) : GroupDataSource {
31+
32+
override suspend fun updateGroupInfo(
33+
groupId: String,
34+
groupName: String,
35+
groupIntroduce: String,
36+
rules: List<Rule>
37+
): Boolean {
38+
return suspendCancellableCoroutine { cancellableContinuation ->
39+
db.collection(GROUPS_COLLECTION)
40+
.document(groupId)
41+
.update(
42+
mapOf(
43+
GROUP_NAME to groupName,
44+
GROUP_INTRODUCE to groupIntroduce,
45+
RULES to rules.map { rule ->
46+
rule.toString()
47+
}
48+
)
49+
)
50+
.addOnSuccessListener {
51+
cancellableContinuation.resume(true)
52+
}
53+
.addOnFailureListener {
54+
cancellableContinuation.resume(false)
55+
}
56+
}
57+
}
58+
59+
override suspend fun joinGroup(uid: String, groupId: String): Boolean {
60+
return suspendCancellableCoroutine { cancellableContinuation ->
61+
62+
db.collection(USERS_COLLECTION)
63+
.document(uid)
64+
.update(
65+
JOINED_GROUP_LIST,
66+
FieldValue.arrayUnion(groupId)
67+
).addOnSuccessListener {
68+
db.collection(GROUPS_COLLECTION)
69+
.document(groupId)
70+
.update(
71+
GROUP_MEMBERS_ID,
72+
FieldValue.arrayUnion(uid)
73+
).addOnSuccessListener {
74+
cancellableContinuation.resume(true)
75+
}.addOnFailureListener {
76+
cancellableContinuation.resume(false)
77+
}
78+
}.addOnFailureListener {
79+
cancellableContinuation.resume(false)
80+
}
81+
}
82+
}
83+
84+
override suspend fun exitGroup(uid: String, groupId: String): Boolean {
85+
return suspendCancellableCoroutine { cancellableContinuation ->
86+
db.collection(GROUPS_COLLECTION)
87+
.document(groupId)
88+
.update(
89+
mapOf(
90+
GROUP_MEMBERS_ID to FieldValue.arrayRemove(uid)
91+
)
92+
).addOnSuccessListener {
93+
db.collection(USERS_COLLECTION)
94+
.document(uid)
95+
.update(
96+
mapOf(
97+
JOINED_GROUP_LIST to FieldValue.arrayRemove(groupId)
98+
)
99+
)
100+
.addOnSuccessListener {
101+
cancellableContinuation.resume(true)
102+
}
103+
.addOnFailureListener {
104+
cancellableContinuation.resume(false)
105+
}
106+
}.addOnFailureListener {
107+
cancellableContinuation.resume(false)
108+
}
109+
}
110+
}
111+
112+
override suspend fun createGroup(
113+
groupName: String,
114+
introduce: String,
115+
rules: List<String>,
116+
uid: String
117+
): Boolean {
118+
return suspendCancellableCoroutine { cancellableContinuation ->
119+
val newGroupId = UUID.randomUUID().toString()
120+
db.collection(GROUPS_COLLECTION)
121+
.document(newGroupId)
122+
.set(
123+
GroupInfoResponse(
124+
groupId = newGroupId,
125+
groupName = groupName,
126+
introduce = introduce,
127+
leaderId = uid,
128+
membersId = listOf(uid),
129+
rules = rules
130+
)
131+
).addOnSuccessListener {
132+
cancellableContinuation.resume(true)
133+
}.addOnFailureListener {
134+
cancellableContinuation.resume(false)
135+
}
136+
}
137+
}
138+
139+
override fun getGroupInfoFlow(uid: String, groupId: String): Flow<GroupInfo> = callbackFlow {
140+
db.collection(GROUPS_COLLECTION)
141+
.document(groupId)
142+
.addSnapshotListener { documentSnapshot, _ ->
143+
val groupInfoResponse = documentSnapshot?.toObject(GroupInfoResponse::class.java)
144+
145+
groupInfoResponse?.let {
146+
db.collection(USERS_COLLECTION)
147+
.document(uid)
148+
.addSnapshotListener { documentSnapshot, _ ->
149+
val userResponse = documentSnapshot?.toObject(UserResponse::class.java)
150+
151+
userResponse?.let {
152+
trySend(
153+
groupInfoResponse.toGroupInfo(
154+
leader = userResponse.toUser(),
155+
rules = groupInfoResponse.rules.map {
156+
it.toRule()
157+
}
158+
)
159+
)
160+
}
161+
}
162+
}
163+
}
164+
awaitClose()
165+
}
166+
167+
override suspend fun isDuplicatedGroupName(groupName: String): Boolean {
168+
return db.collection(GROUPS_COLLECTION)
169+
.whereEqualTo(GROUP_NAME, groupName)
170+
.get()
171+
.await()
172+
.isEmpty
173+
.not()
174+
}
175+
}

0 commit comments

Comments
 (0)