Timeline: make group id really stable
This commit is contained in:
parent
231f278adb
commit
a07305314f
2 changed files with 36 additions and 10 deletions
|
|
@ -17,10 +17,20 @@
|
||||||
package io.element.android.features.messages.impl.timeline.groups
|
package io.element.android.features.messages.impl.timeline.groups
|
||||||
|
|
||||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
|
import io.element.android.libraries.di.RoomScope
|
||||||
|
import io.element.android.libraries.di.SingleIn
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@SingleIn(RoomScope::class)
|
||||||
class TimelineItemGrouper @Inject constructor() {
|
class TimelineItemGrouper @Inject constructor() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keys are identifier of items in a group, only one by group will be kept.
|
||||||
|
* Values are the actual groupIds.
|
||||||
|
*/
|
||||||
|
private val groupIds = HashMap<String, String>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new list of [TimelineItem] by grouping some of them into [TimelineItem.GroupedEvents].
|
* Create a new list of [TimelineItem] by grouping some of them into [TimelineItem.GroupedEvents].
|
||||||
*/
|
*/
|
||||||
|
|
@ -34,14 +44,14 @@ class TimelineItemGrouper @Inject constructor() {
|
||||||
// timelineItem cannot be grouped
|
// timelineItem cannot be grouped
|
||||||
if (currentGroup.isNotEmpty()) {
|
if (currentGroup.isNotEmpty()) {
|
||||||
// There is a pending group, create a TimelineItem.GroupedEvents if there is more than 1 Event in the pending group.
|
// There is a pending group, create a TimelineItem.GroupedEvents if there is more than 1 Event in the pending group.
|
||||||
result.addGroup(currentGroup)
|
result.addGroup(groupIds, currentGroup)
|
||||||
currentGroup.clear()
|
currentGroup.clear()
|
||||||
}
|
}
|
||||||
result.add(timelineItem)
|
result.add(timelineItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentGroup.isNotEmpty()) {
|
if (currentGroup.isNotEmpty()) {
|
||||||
result.addGroup(currentGroup)
|
result.addGroup(groupIds, currentGroup)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
@ -51,16 +61,33 @@ class TimelineItemGrouper @Inject constructor() {
|
||||||
* Will add a group if there is more than 1 item, else add the item to the list.
|
* Will add a group if there is more than 1 item, else add the item to the list.
|
||||||
*/
|
*/
|
||||||
private fun MutableList<TimelineItem>.addGroup(
|
private fun MutableList<TimelineItem>.addGroup(
|
||||||
group: MutableList<TimelineItem.Event>
|
groupIds: MutableMap<String, String>,
|
||||||
|
groupOfItems: MutableList<TimelineItem.Event>
|
||||||
) {
|
) {
|
||||||
if (group.size == 1) {
|
if (groupOfItems.size == 1) {
|
||||||
// Do not create a group with just 1 item, just add the item to the result
|
// Do not create a group with just 1 item, just add the item to the result
|
||||||
add(group.first())
|
add(groupOfItems.first())
|
||||||
} else {
|
} else {
|
||||||
|
val groupId = groupIds.getOrPutGroupId(groupOfItems)
|
||||||
add(
|
add(
|
||||||
TimelineItem.GroupedEvents(
|
TimelineItem.GroupedEvents(
|
||||||
events = group.toImmutableList()
|
id = groupId,
|
||||||
|
events = groupOfItems.toImmutableList()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun MutableMap<String, String>.getOrPutGroupId(timelineItems: List<TimelineItem>): String {
|
||||||
|
assert(timelineItems.isNotEmpty())
|
||||||
|
for (item in timelineItems) {
|
||||||
|
val itemIdentifier = item.identifier()
|
||||||
|
if (this.contains(itemIdentifier)) {
|
||||||
|
return this[itemIdentifier]!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val itemIdentifier = timelineItems.first().identifier()
|
||||||
|
return "${itemIdentifier}_group".also { groupId ->
|
||||||
|
this[itemIdentifier] = groupId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,8 @@ sealed interface TimelineItem {
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class GroupedEvents(
|
data class GroupedEvents(
|
||||||
|
val id: String,
|
||||||
val events: ImmutableList<Event>,
|
val events: ImmutableList<Event>,
|
||||||
) : TimelineItem {
|
) : TimelineItem
|
||||||
// use last id with a suffix. Last will not change in cas of new event from backpagination.
|
|
||||||
val id = "${events.last().id}_group"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue