Skip to content

Commit 53e4a1c

Browse files
committed
chore(fc): split members table into members and users - store pii (name, image) in users
Signed-off-by: Brandon McAnsh <[email protected]>
1 parent dbd726c commit 53e4a1c

File tree

19 files changed

+768
-134
lines changed

19 files changed

+768
-134
lines changed

flipchatApp/src/main/kotlin/xyz/flipchat/app/features/chat/conversation/ConversationViewModel.kt

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ import xyz.flipchat.services.data.metadata.SendMessageAsListenerPaymentMetadata
7777
import xyz.flipchat.services.data.metadata.SendTipMessagePaymentMetadata
7878
import xyz.flipchat.services.data.metadata.erased
7979
import xyz.flipchat.services.data.metadata.typeUrl
80-
import xyz.flipchat.services.domain.model.chat.ConversationMember
80+
import xyz.flipchat.services.domain.model.chat.ConversationMemberWithPersonalInfo
8181
import xyz.flipchat.services.domain.model.chat.ConversationMessage
8282
import xyz.flipchat.services.domain.model.chat.ConversationWithMembersAndLastPointers
8383
import xyz.flipchat.services.extensions.titleOrFallback
@@ -1004,13 +1004,13 @@ class ConversationViewModel @Inject constructor(
10041004
},
10051005
sender = Sender(
10061006
id = reply.message.senderId,
1007-
profileImage = reply.member?.imageUri.takeIf {
1007+
profileImage = reply.personalInfo?.imageUri.takeIf {
10081008
it.orEmpty().isNotEmpty()
10091009
},
10101010
isFullMember = reply.member?.isFullMember == true,
1011-
displayName = reply.member?.memberName ?: "Deleted",
1011+
displayName = reply.personalInfo?.memberName.orEmpty().ifEmpty { "Member" },
10121012
isSelf = reply.contentEntity.isFromSelf,
1013-
isBlocked = reply.member?.isBlocked == true,
1013+
isBlocked = reply.personalInfo?.isBlocked == true,
10141014
isHost = reply.message.senderId == currentState.hostId && !contents.isFromSelf,
10151015
)
10161016
)
@@ -1022,16 +1022,16 @@ class ConversationViewModel @Inject constructor(
10221022
currentState.isTippingEnabled && !userManager.isSelf(message.senderId)
10231023

10241024
val tips = if (currentState.isTippingEnabled && tipInfo.isNotEmpty()) {
1025-
tipInfo.map { (tip, member) ->
1025+
tipInfo.map { (tip, member, user) ->
10261026
MessageTip(
10271027
amount = tip.kin,
10281028
tipper = Sender(
10291029
id = member?.id,
1030-
profileImage = member?.imageUri.nullIfEmpty(),
1031-
displayName = member?.memberName,
1030+
profileImage = user?.imageUri.nullIfEmpty(),
1031+
displayName = user?.memberName,
10321032
isHost = member?.isHost ?: false,
10331033
isSelf = userManager.isSelf(member?.id),
1034-
isBlocked = member?.isBlocked ?: false,
1034+
isBlocked = user?.isBlocked ?: false,
10351035
)
10361036
)
10371037
}
@@ -1063,7 +1063,7 @@ class ConversationViewModel @Inject constructor(
10631063
sender = Sender(
10641064
id = message.senderId,
10651065
profileImage = member?.imageUri.takeIf { it.orEmpty().isNotEmpty() },
1066-
displayName = member?.memberName ?: "Deleted",
1066+
displayName = member?.displayName.orEmpty().ifEmpty { "Member" },
10671067
isSelf = contents.isFromSelf,
10681068
isFullMember = member?.isFullMember == true,
10691069
isHost = message.senderId == currentState.hostId,
@@ -1119,20 +1119,20 @@ class ConversationViewModel @Inject constructor(
11191119

11201120
private fun buildMessageActions(
11211121
message: ConversationMessage,
1122-
member: ConversationMember?,
1122+
member: ConversationMemberWithPersonalInfo?,
11231123
contents: MessageContent,
11241124
enableReply: Boolean,
11251125
enableTip: Boolean,
11261126
): List<MessageControlAction> {
11271127
return mutableListOf<MessageControlAction>().apply {
11281128
if (stateFlow.value.isHost) {
1129-
if (member?.memberName?.isNotEmpty() == true && !contents.isFromSelf) {
1129+
if (member?.displayName?.isNotEmpty() == true && !contents.isFromSelf) {
11301130
if (member.isFullMember) {
11311131
add(
11321132
MessageControlAction.DemoteUser {
11331133
confirmUserDemote(
11341134
conversationId = message.conversationId,
1135-
user = member.memberName,
1135+
user = member.displayName,
11361136
userId = message.senderId
11371137
)
11381138
}
@@ -1142,7 +1142,7 @@ class ConversationViewModel @Inject constructor(
11421142
MessageControlAction.PromoteUser {
11431143
confirmUserPromote(
11441144
conversationId = message.conversationId,
1145-
user = member.memberName,
1145+
user = member.displayName,
11461146
userId = message.senderId
11471147
)
11481148
}
@@ -1157,7 +1157,7 @@ class ConversationViewModel @Inject constructor(
11571157
val sender = Sender(
11581158
id = message.senderId,
11591159
profileImage = member?.imageUri.takeIf { it.orEmpty().isNotEmpty() },
1160-
displayName = member?.memberName ?: "Deleted",
1160+
displayName = member?.displayName ?: "Deleted",
11611161
isSelf = contents.isFromSelf,
11621162
isHost = message.senderId == stateFlow.value.hostId && !contents.isFromSelf,
11631163
isBlocked = member?.isBlocked == true
@@ -1193,7 +1193,7 @@ class ConversationViewModel @Inject constructor(
11931193

11941194
private fun buildSelfDefenseControls(
11951195
message: ConversationMessage,
1196-
member: ConversationMember?,
1196+
member: ConversationMemberWithPersonalInfo?,
11971197
contents: MessageContent
11981198
): List<MessageControlAction> {
11991199
return mutableListOf<MessageControlAction>().apply {
@@ -1211,7 +1211,7 @@ class ConversationViewModel @Inject constructor(
12111211

12121212

12131213
if (stateFlow.value.isHost) {
1214-
if (member?.memberName?.isNotEmpty() == true && !contents.isFromSelf) {
1214+
if (member?.displayName?.isNotEmpty() == true && !contents.isFromSelf) {
12151215
// add(
12161216
// MessageControlAction.RemoveUser(member.memberName.orEmpty()) {
12171217
// confirmUserRemoval(
@@ -1225,7 +1225,7 @@ class ConversationViewModel @Inject constructor(
12251225
MessageControlAction.MuteUser {
12261226
confirmUserMute(
12271227
conversationId = message.conversationId,
1228-
user = member.memberName,
1228+
user = member.displayName,
12291229
userId = message.senderId,
12301230
)
12311231
}
@@ -1238,14 +1238,14 @@ class ConversationViewModel @Inject constructor(
12381238
if (member.isBlocked) {
12391239
add(
12401240
MessageControlAction.UnblockUser {
1241-
dispatchEvent(Event.UnblockUser(member.id))
1241+
dispatchEvent(Event.UnblockUser(message.senderId))
12421242
}
12431243
)
12441244
} else {
12451245
add(
12461246
MessageControlAction.BlockUser {
12471247
confirmUserBlock(
1248-
user = member.memberName,
1248+
user = member.displayName,
12491249
userId = message.senderId,
12501250
)
12511251
}
@@ -1254,9 +1254,9 @@ class ConversationViewModel @Inject constructor(
12541254
}
12551255

12561256
add(
1257-
MessageControlAction.ReportUserForMessage(member?.memberName.orEmpty()) {
1257+
MessageControlAction.ReportUserForMessage(member?.displayName.orEmpty()) {
12581258
confirmUserReport(
1259-
user = member?.memberName,
1259+
user = member?.displayName,
12601260
userId = message.senderId,
12611261
messageId = message.id
12621262
)
@@ -1487,7 +1487,7 @@ class ConversationViewModel @Inject constructor(
14871487
roomId = conversation.id,
14881488
roomNumber = conversation.roomNumber,
14891489
ownerId = conversation.ownerId,
1490-
hostName = host?.memberName,
1490+
hostName = host?.displayName,
14911491
memberCount = members.count(),
14921492
messagingFeeQuarks = conversation.coverCharge.quarks
14931493
)

flipchatApp/src/main/kotlin/xyz/flipchat/app/features/chat/info/ChatInfoViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class ChatInfoViewModel @Inject constructor(
151151
members.map { m ->
152152
MinimalMember(
153153
id = m.id,
154-
displayName = m.memberName.nullIfEmpty(),
154+
displayName = m.displayName.nullIfEmpty(),
155155
profileImageUrl = m.imageUri,
156156
isHost = m.isHost,
157157
canSpeak = m.isFullMember,

services/flipchat/chat/src/main/kotlin/xyz/flipchat/services/domain/model/chat/Conversation.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ data class Conversation(
4848
val coverCharge: Kin = messagingFee?.let { Kin.fromQuarks(messagingFee) } ?: Kin.fromQuarks(0)
4949
}
5050

51-
@Serializable
5251
data class ConversationWithMembersAndLastPointers(
5352
@Embedded val conversation: Conversation,
5453
@Relation(
5554
parentColumn = "idBase58",
56-
entityColumn = "conversationIdBase58"
55+
entityColumn = "conversationIdBase58",
56+
entity = ConversationMember::class
5757
)
58-
val members: List<ConversationMember>,
58+
val members: List<ConversationMemberWithPersonalInfo>,
5959
@Relation(
6060
parentColumn = "idBase58",
6161
entityColumn = "conversationIdBase58",

services/flipchat/chat/src/main/kotlin/xyz/flipchat/services/domain/model/chat/ConversationMember.kt

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package xyz.flipchat.services.domain.model.chat
22

33
import androidx.room.ColumnInfo
4+
import androidx.room.DatabaseView
5+
import androidx.room.Embedded
46
import androidx.room.Entity
57
import androidx.room.Ignore
68
import androidx.room.Index
9+
import androidx.room.Relation
710
import com.getcode.model.ID
811
import com.getcode.vendor.Base58
912
import kotlinx.serialization.Serializable
13+
import xyz.flipchat.services.domain.model.people.FlipchatUser
14+
import xyz.flipchat.services.domain.model.people.MemberPersonalInfo
1015

1116
@Serializable
1217
@Entity(
@@ -20,20 +25,41 @@ import kotlinx.serialization.Serializable
2025
data class ConversationMember(
2126
val memberIdBase58: String,
2227
val conversationIdBase58: String,
23-
val memberName: String?,
24-
val imageUri: String?,
2528
@ColumnInfo(defaultValue = "false")
2629
val isHost: Boolean, // isModerator
2730
@ColumnInfo(defaultValue = "false")
2831
val isMuted: Boolean,
2932
@ColumnInfo(defaultValue = "false")
3033
val isFullMember: Boolean,
31-
@ColumnInfo(defaultValue = "false")
32-
val isBlocked: Boolean
3334
) {
3435
@Ignore
3536
val id: ID = Base58.decode(memberIdBase58).toList()
3637

3738
@Ignore
3839
val conversationId: ID = Base58.decode(conversationIdBase58).toList()
40+
}
41+
42+
data class ConversationMemberWithPersonalInfo(
43+
@Embedded val member: ConversationMember?,
44+
@Relation(
45+
parentColumn = "memberIdBase58",
46+
entityColumn = "userIdBase58",
47+
projection = ["memberName", "imageUri", "isBlocked"],
48+
entity = FlipchatUser::class
49+
)
50+
private val personalInfo: MemberPersonalInfo?,
51+
) {
52+
val id: ID? get() = member?.memberIdBase58?.let { Base58.decode(it).toList() }
53+
54+
val isHost: Boolean get() = member?.isHost == true
55+
56+
val isMuted: Boolean get() = member?.isMuted == true
57+
58+
val isFullMember: Boolean get() = member?.isFullMember == true
59+
60+
val displayName: String? get() = personalInfo?.memberName
61+
62+
val imageUri: String? get() = personalInfo?.imageUri
63+
64+
val isBlocked: Boolean get() = personalInfo?.isBlocked == true
3965
}

services/flipchat/chat/src/main/kotlin/xyz/flipchat/services/domain/model/chat/ConversationMessage.kt

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ import androidx.room.Ignore
77
import androidx.room.Index
88
import androidx.room.Junction
99
import androidx.room.PrimaryKey
10+
import androidx.room.Query
1011
import androidx.room.Relation
1112
import com.getcode.model.ID
1213
import com.getcode.model.KinAmount
1314
import com.getcode.model.chat.MessageContent
1415
import com.getcode.vendor.Base58
1516
import kotlinx.serialization.Serializable
17+
import xyz.flipchat.services.domain.model.people.FlipchatUser
18+
import xyz.flipchat.services.domain.model.people.MemberPersonalInfo
1619

1720
@Serializable
1821
@Entity(
@@ -72,28 +75,27 @@ data class ConversationMessageWithMemberAndReply(
7275
entity = ConversationMember::class,
7376
)
7477
val member: ConversationMember?,
75-
@Relation(
76-
parentColumn = "inReplyToBase58",
77-
entityColumn = "idBase58",
78-
entity = ConversationMessage::class,
79-
)
80-
val inReplyTo: ConversationMessageWithMemberAndContent? = null,
81-
@Relation(
82-
parentColumn = "idBase58",
83-
entityColumn = "messageIdBase58",
84-
entity = ConversationMessageTip::class,
85-
)
86-
val tips: List<MessageTipInfo>
8778
)
8879

80+
8981
data class ConversationMessageWithMemberAndContent(
9082
@Embedded val message: ConversationMessage,
83+
84+
// Member information from members table
9185
@Relation(
9286
parentColumn = "senderIdBase58",
9387
entityColumn = "memberIdBase58",
94-
entity = ConversationMember::class,
88+
entity = ConversationMember::class
9589
)
9690
val member: ConversationMember?,
91+
92+
@Relation(
93+
parentColumn = "senderIdBase58",
94+
entityColumn = "userIdBase58",
95+
projection = ["memberName", "imageUri", "isBlocked"],
96+
entity = FlipchatUser::class,
97+
)
98+
val personalInfo: MemberPersonalInfo?
9799
) {
98100
@Ignore
99101
var contentEntity: MessageContent = MessageContent.Unknown(false)
@@ -102,7 +104,7 @@ data class ConversationMessageWithMemberAndContent(
102104
data class InflatedConversationMessage(
103105
val pageIndex: Int = 0, // tracking for [PagingSource] refresh eky
104106
val message: ConversationMessage,
105-
val member: ConversationMember?,
107+
val member: ConversationMemberWithPersonalInfo?,
106108
val content: MessageContent,
107109
val reply: ConversationMessageWithMemberAndContent?,
108110
val tips: List<MessageTipInfo>
@@ -115,5 +117,12 @@ data class MessageTipInfo(
115117
entityColumn = "memberIdBase58",
116118
entity = ConversationMember::class,
117119
)
118-
val tipper: ConversationMember?
120+
val tipper: ConversationMember?,
121+
@Relation(
122+
parentColumn = "tipperIdBase58",
123+
entityColumn = "userIdBase58",
124+
projection = ["memberName", "imageUri", "isBlocked"],
125+
entity = FlipchatUser::class
126+
)
127+
val personalInfo: MemberPersonalInfo?,
119128
)

services/flipchat/chat/src/main/kotlin/xyz/flipchat/services/domain/model/chat/db/ChatUpdate.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package xyz.flipchat.services.domain.model.chat.db
22

33
import com.getcode.model.ID
4+
import xyz.flipchat.services.data.Member
45
import xyz.flipchat.services.domain.model.chat.Conversation
56
import xyz.flipchat.services.domain.model.chat.ConversationMember
67
import xyz.flipchat.services.domain.model.chat.ConversationMessage
@@ -12,9 +13,9 @@ data class ChatUpdate(
1213
)
1314

1415
sealed interface ConversationMemberUpdate {
15-
data class FullRefresh(val members: List<ConversationMember>): ConversationMemberUpdate
16-
data class IndividualRefresh(val member: ConversationMember): ConversationMemberUpdate
17-
data class Joined(val member: ConversationMember): ConversationMemberUpdate
16+
data class FullRefresh(val roomId: ID, val members: List<Member>): ConversationMemberUpdate
17+
data class IndividualRefresh(val roomId: ID, val member: Member): ConversationMemberUpdate
18+
data class Joined(val roomId: ID, val member: Member): ConversationMemberUpdate
1819
data class Left(val roomId: ID, val memberId: ID): ConversationMemberUpdate
1920
data class Removed(val roomId: ID, val memberId: ID, val removedBy: ID): ConversationMemberUpdate
2021
data class Muted(val roomId: ID, val memberId: ID, val mutedBy: ID): ConversationMemberUpdate
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package xyz.flipchat.services.domain.model.people
2+
3+
import androidx.room.Entity
4+
import androidx.room.Ignore
5+
import androidx.room.PrimaryKey
6+
import com.getcode.model.ID
7+
import com.getcode.vendor.Base58
8+
import kotlinx.serialization.Serializable
9+
10+
@Serializable
11+
@Entity(tableName = "users",)
12+
data class FlipchatUser(
13+
@PrimaryKey
14+
val userIdBase58: String,
15+
val memberName: String?,
16+
val imageUri: String?,
17+
val isBlocked: Boolean? = null
18+
) {
19+
@Ignore
20+
val id: ID = Base58.decode(userIdBase58).toList()
21+
}
22+
23+
data class MemberPersonalInfo(
24+
val memberName: String?,
25+
val imageUri: String?,
26+
val isBlocked: Boolean
27+
)

services/flipchat/chat/src/main/kotlin/xyz/flipchat/services/internal/data/mapper/ConversationMemberMapper.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,9 @@ class ConversationMemberMapper @Inject constructor(): Mapper<Pair<ID, Member>, C
1313
return ConversationMember(
1414
memberIdBase58 = member.id.base58,
1515
conversationIdBase58 = conversationId.base58,
16-
memberName = member.identity?.displayName,
17-
imageUri = member.identity?.imageUrl,
1816
isHost = member.isModerator,
1917
isMuted = member.isMuted,
2018
isFullMember = !member.isSpectator,
21-
isBlocked = false // local set only right now
2219
)
2320
}
2421
}

0 commit comments

Comments
 (0)