Skip to content

Commit eff74d8

Browse files
committed
fix(fc): properly handle typing updates to support multiple typing
Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 1ca60db commit eff74d8

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,10 @@ class ConversationViewModel @Inject constructor(
15241524
Timber.d("Delete Message => ${event.messageId.uuid.toString()}")
15251525
}
15261526

1527+
is Event.OnOtherUsersTyping -> {
1528+
Timber.d("${event.users.count()} other user(s) typing")
1529+
}
1530+
15271531
else -> Timber.d("event=${event}")
15281532
}
15291533

services/flipchat/chat/src/main/kotlin/xyz/flipchat/services/internal/network/repository/messaging/RealMessagingRepository.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,32 @@ internal class RealMessagingRepository @Inject constructor(
3737

3838
private val typingState = MutableStateFlow<List<IsTyping>>(emptyList())
3939

40+
private fun handleTypingUpdates(updates: List<IsTyping>) {
41+
// Identify users who have stopped typing
42+
val noLongerTyping = updates.filter {
43+
it.state == TypingState.Stopped || it.state == TypingState.TimedOut
44+
}.toSet()
45+
46+
// Get current state
47+
val currently = typingState.value
48+
49+
// Remove users who stopped typing from current state first
50+
val afterRemovals = currently.filter { current ->
51+
noLongerTyping.none { it.userId == current.userId }
52+
}.toSet()
53+
54+
// Process new typing updates (excluding stops/timeouts)
55+
val newTypingUpdates = updates.filter {
56+
it.state != TypingState.Stopped && it.state != TypingState.TimedOut
57+
}.toSet()
58+
59+
// Combine existing state with new updates, favoring new updates in case of conflicts
60+
// Using distinctBy to ensure only one entry per userId, preferring the latest update
61+
typingState.value = (afterRemovals + newTypingUpdates)
62+
.distinctBy { it.userId }
63+
.toList()
64+
}
65+
4066
override suspend fun getMessages(
4167
chatId: ID,
4268
queryOptions: QueryOptions,
@@ -135,7 +161,8 @@ internal class RealMessagingRepository @Inject constructor(
135161
}
136162
is MessageStreamUpdate.Pointers -> Unit
137163
is MessageStreamUpdate.Typing -> {
138-
typingState.value = update.data.map { typingMapper.map(it) }
164+
println("typing update=${update.data}")
165+
handleTypingUpdates(update.data.map { typingMapper.map(it) })
139166
}
140167
}
141168
} else {

services/flipchat/chat/src/main/kotlin/xyz/flipchat/services/internal/network/service/MessagingService.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ internal class MessagingService @Inject constructor(
291291
)
292292
}
293293
MessagingService.StreamMessagesResponse.TypeCase.IS_TYPING_NOTIFICATIONS -> {
294-
println("typing updates yippee")
295294
onEvent(
296295
Result.success(
297296
MessageStreamUpdate.Typing(value.isTypingNotifications.isTypingNotificationsList)

0 commit comments

Comments
 (0)