mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-2966 Chats | Fix | Fix visibility range detection logic (#2396)
This commit is contained in:
parent
70219cce56
commit
71f4e03524
3 changed files with 33 additions and 14 deletions
|
@ -66,7 +66,7 @@ class ChatContainer @Inject constructor(
|
|||
}
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.map { wrappers -> wrappers.associate { it.id to it } }
|
||||
.map { wrappers -> wrappers.associateBy { it.id } }
|
||||
}
|
||||
|
||||
// TODO Naive implementation. Add caching logic
|
||||
|
@ -115,18 +115,18 @@ class ChatContainer @Inject constructor(
|
|||
cacheLastMessages(result.messages)
|
||||
}
|
||||
|
||||
val state = response.chatState ?: Chat.State()
|
||||
val initialState = response.chatState ?: Chat.State()
|
||||
|
||||
var intent: Intent = Intent.None
|
||||
|
||||
val initial = buildList<Chat.Message> {
|
||||
if (state.hasUnReadMessages && !state.oldestMessageOrderId.isNullOrEmpty()) {
|
||||
if (initialState.hasUnReadMessages && !initialState.oldestMessageOrderId.isNullOrEmpty()) {
|
||||
// Starting from the unread-messages window.
|
||||
val aroundUnread = loadAroundMessageOrder(
|
||||
chat = chat,
|
||||
order = state.oldestMessageOrderId.orEmpty()
|
||||
order = initialState.oldestMessageOrderId.orEmpty()
|
||||
).also {
|
||||
val target = it.find { it.order == state.oldestMessageOrderId }
|
||||
val target = it.find { it.order == initialState.oldestMessageOrderId }
|
||||
if (target != null) {
|
||||
intent = Intent.ScrollToMessage(target.id)
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ class ChatContainer @Inject constructor(
|
|||
inputs.scan(
|
||||
initial = ChatStreamState(
|
||||
messages = initial,
|
||||
state = state,
|
||||
state = initialState,
|
||||
intent = intent
|
||||
)
|
||||
) { state, transform ->
|
||||
|
@ -184,6 +184,7 @@ class ChatContainer @Inject constructor(
|
|||
)
|
||||
}
|
||||
is Transformation.Commands.LoadEnd -> {
|
||||
logger.logInfo("DROID-2966 intent while load end: $intent")
|
||||
if (state.messages.isNotEmpty()) {
|
||||
if (state.state.hasUnReadMessages) {
|
||||
// Check if above the unread messages
|
||||
|
@ -238,6 +239,7 @@ class ChatContainer @Inject constructor(
|
|||
)
|
||||
}
|
||||
} else {
|
||||
// TODO optimise by checking last message and last message in state
|
||||
if (lastMessages.contains(transform.lastVisibleMessage)) {
|
||||
// No need to paginate, just scroll to bottom.
|
||||
state.copy(
|
||||
|
@ -245,12 +247,15 @@ class ChatContainer @Inject constructor(
|
|||
)
|
||||
} else {
|
||||
val messages = try {
|
||||
loadToEnd(chat)
|
||||
loadToEnd(chat).also {
|
||||
logger.logInfo("DROID-2966 Loaded chat tail because last message did not contained last visible message")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
state.messages.also {
|
||||
logger.logException(e, "DROID-2966 Error while scrolling to bottom")
|
||||
}
|
||||
}
|
||||
|
||||
ChatStreamState(
|
||||
messages = messages,
|
||||
intent = Intent.ScrollToBottom,
|
||||
|
@ -262,6 +267,11 @@ class ChatContainer @Inject constructor(
|
|||
state
|
||||
}
|
||||
}
|
||||
is Transformation.Commands.ClearIntent -> {
|
||||
state.copy(
|
||||
intent = Intent.None
|
||||
)
|
||||
}
|
||||
is Transformation.Commands.UpdateVisibleRange -> {
|
||||
val unread = state.state
|
||||
val readFrom = state.messages.find { it.id == transform.from }
|
||||
|
@ -280,9 +290,9 @@ class ChatContainer @Inject constructor(
|
|||
)
|
||||
)
|
||||
}.onFailure {
|
||||
logger.logException(it, "Error while reading messages")
|
||||
logger.logException(it, "DROID-2966 Error while reading messages")
|
||||
}.onSuccess {
|
||||
logger.logInfo("Read messages with success")
|
||||
logger.logInfo("DROID-2966 Read messages with success")
|
||||
}
|
||||
}
|
||||
state
|
||||
|
@ -291,6 +301,8 @@ class ChatContainer @Inject constructor(
|
|||
state.reduce(transform.events)
|
||||
}
|
||||
}
|
||||
}.onEach {
|
||||
logger.logInfo("DROID-2966 New emission with intent: ${it.intent}")
|
||||
}.distinctUntilChanged()
|
||||
)
|
||||
}.catch { e ->
|
||||
|
@ -557,6 +569,11 @@ class ChatContainer @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun onClearIntent() {
|
||||
logger.logInfo("DROID-2966 onClearIntent called")
|
||||
commands.emit(Transformation.Commands.ClearIntent)
|
||||
}
|
||||
|
||||
internal sealed class Transformation {
|
||||
sealed class Events : Transformation() {
|
||||
data class Payload(val events: List<Event.Command.Chats>) : Events()
|
||||
|
@ -585,6 +602,8 @@ class ChatContainer @Inject constructor(
|
|||
data class LoadEnd(val lastVisibleMessage: Id?): Commands()
|
||||
|
||||
data class UpdateVisibleRange(val from: Id, val to: Id) : Commands()
|
||||
|
||||
data object ClearIntent : Commands()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -949,9 +949,7 @@ class ChatViewModel @Inject constructor(
|
|||
fun onClearChatViewStateIntent() {
|
||||
Timber.d("DROID-2966 onClearChatViewStateIntent")
|
||||
viewModelScope.launch {
|
||||
uiState.update { current ->
|
||||
current.copy(intent = ChatContainer.Intent.None)
|
||||
}
|
||||
chatContainer.onClearIntent()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ fun ChatScreen(
|
|||
|
||||
// Applying view model intents
|
||||
LaunchedEffect(intent) {
|
||||
when (val intent = intent) {
|
||||
when (intent) {
|
||||
is ChatContainer.Intent.ScrollToMessage -> {
|
||||
isPerformingScrollIntent.value = true
|
||||
val index = messages.indexOfFirst {
|
||||
|
@ -404,9 +404,10 @@ fun ChatScreen(
|
|||
}
|
||||
|
||||
// Tracking visible range
|
||||
LaunchedEffect(lazyListState) {
|
||||
LaunchedEffect(lazyListState, messages) {
|
||||
snapshotFlow { lazyListState.layoutInfo }
|
||||
.mapNotNull { layoutInfo ->
|
||||
// TODO optimise by only sending event when scrolling towards bottom
|
||||
val viewportHeight = layoutInfo.viewportSize.height
|
||||
val visibleMessages = layoutInfo.visibleItemsInfo
|
||||
.filter { item ->
|
||||
|
@ -899,6 +900,7 @@ fun TopDiscussionToolbar(
|
|||
}
|
||||
|
||||
suspend fun smoothScrollToBottom(lazyListState: LazyListState) {
|
||||
Timber.d("DROID-2966 Performing scroll-to-bottom")
|
||||
lazyListState.scrollToItem(0)
|
||||
|
||||
// Wait for the layout to settle after scrolling
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue