Skip to content

Commit 3ab465e

Browse files
authored
Merge pull request #8003 from vector-im/feature/mna/fetch-poll-history-timeline
[Poll] Unmock poll history timeline (PSG-1045, PSG-1095)
2 parents 00c90c1 + b6f77ac commit 3ab465e

File tree

57 files changed

+2775
-528
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2775
-528
lines changed

changelog.d/7864.sdk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[Poll] Adding PollHistoryService

changelog.d/7864.wip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[Poll] History list: unmock data

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
2828
import org.matrix.android.sdk.api.session.room.model.RoomSummary
2929
import org.matrix.android.sdk.api.session.room.model.relation.RelationService
3030
import org.matrix.android.sdk.api.session.room.notification.RoomPushRuleService
31+
import org.matrix.android.sdk.api.session.room.poll.PollHistoryService
3132
import org.matrix.android.sdk.api.session.room.read.ReadService
3233
import org.matrix.android.sdk.api.session.room.reporting.ReportingService
3334
import org.matrix.android.sdk.api.session.room.send.DraftService
@@ -181,4 +182,9 @@ interface Room {
181182
* Get the LocationSharingService associated to this Room.
182183
*/
183184
fun locationSharingService(): LocationSharingService
185+
186+
/**
187+
* Get the PollHistoryService associated to this Room.
188+
*/
189+
fun pollHistoryService(): PollHistoryService
184190
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2023 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.api.session.room.poll
18+
19+
/**
20+
* Represent the status of the loaded polls for a room.
21+
*/
22+
data class LoadedPollsStatus(
23+
/**
24+
* Indicate whether more polls can be loaded from timeline.
25+
* A false value would mean the start of the timeline has been reached.
26+
*/
27+
val canLoadMore: Boolean,
28+
29+
/**
30+
* Number of days of timeline events currently synced (fetched and stored in local).
31+
*/
32+
val daysSynced: Int,
33+
34+
/**
35+
* Indicate whether a sync of timeline events has been completely done in backward. It would
36+
* mean timeline events have been synced for at least a number of days defined by [PollHistoryService.loadingPeriodInDays].
37+
*/
38+
val hasCompletedASyncBackward: Boolean,
39+
)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2023 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.api.session.room.poll
18+
19+
import androidx.lifecycle.LiveData
20+
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
21+
22+
/**
23+
* Expose methods to get history of polls in rooms.
24+
*/
25+
interface PollHistoryService {
26+
27+
/**
28+
* The number of days covered when requesting to load more polls.
29+
*/
30+
val loadingPeriodInDays: Int
31+
32+
/**
33+
* This must be called when you don't need the service anymore.
34+
* It ensures the underlying database get closed.
35+
*/
36+
fun dispose()
37+
38+
/**
39+
* Ask to load more polls starting from last loaded polls for a period defined by
40+
* [loadingPeriodInDays].
41+
*/
42+
suspend fun loadMore(): LoadedPollsStatus
43+
44+
/**
45+
* Get the current status of the loaded polls.
46+
*/
47+
suspend fun getLoadedPollsStatus(): LoadedPollsStatus
48+
49+
/**
50+
* Sync polls from last loaded polls until now.
51+
*/
52+
suspend fun syncPolls()
53+
54+
/**
55+
* Get currently loaded list of poll events. See [loadMore].
56+
*/
57+
fun getPollEvents(): LiveData<List<TimelineEvent>>
58+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo046
6666
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo047
6767
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo048
6868
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo049
69+
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo050
6970
import org.matrix.android.sdk.internal.util.Normalizer
7071
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
7172
import javax.inject.Inject
@@ -74,7 +75,7 @@ internal class RealmSessionStoreMigration @Inject constructor(
7475
private val normalizer: Normalizer
7576
) : MatrixRealmMigration(
7677
dbName = "Session",
77-
schemaVersion = 49L,
78+
schemaVersion = 50L,
7879
) {
7980
/**
8081
* Forces all RealmSessionStoreMigration instances to be equal.
@@ -133,5 +134,6 @@ internal class RealmSessionStoreMigration @Inject constructor(
133134
if (oldVersion < 47) MigrateSessionTo047(realm).perform()
134135
if (oldVersion < 48) MigrateSessionTo048(realm).perform()
135136
if (oldVersion < 49) MigrateSessionTo049(realm).perform()
137+
if (oldVersion < 50) MigrateSessionTo050(realm).perform()
136138
}
137139
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2023 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.internal.database.migration
18+
19+
import io.realm.DynamicRealm
20+
import org.matrix.android.sdk.internal.database.model.PollHistoryStatusEntityFields
21+
import org.matrix.android.sdk.internal.util.database.RealmMigrator
22+
23+
/**
24+
* Adding new entity PollHistoryStatusEntity.
25+
*/
26+
internal class MigrateSessionTo050(realm: DynamicRealm) : RealmMigrator(realm, 50) {
27+
28+
override fun doMigrate(realm: DynamicRealm) {
29+
realm.schema.create("PollHistoryStatusEntity")
30+
.addField(PollHistoryStatusEntityFields.ROOM_ID, String::class.java)
31+
.addPrimaryKey(PollHistoryStatusEntityFields.ROOM_ID)
32+
.setRequired(PollHistoryStatusEntityFields.ROOM_ID, true)
33+
.addField(PollHistoryStatusEntityFields.CURRENT_TIMESTAMP_TARGET_BACKWARD_MS, Long::class.java)
34+
.setNullable(PollHistoryStatusEntityFields.CURRENT_TIMESTAMP_TARGET_BACKWARD_MS, true)
35+
.addField(PollHistoryStatusEntityFields.OLDEST_TIMESTAMP_TARGET_REACHED_MS, Long::class.java)
36+
.setNullable(PollHistoryStatusEntityFields.OLDEST_TIMESTAMP_TARGET_REACHED_MS, true)
37+
.addField(PollHistoryStatusEntityFields.OLDEST_EVENT_ID_REACHED, String::class.java)
38+
.addField(PollHistoryStatusEntityFields.MOST_RECENT_EVENT_ID_REACHED, String::class.java)
39+
.addField(PollHistoryStatusEntityFields.IS_END_OF_POLLS_BACKWARD, Boolean::class.java)
40+
}
41+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright (c) 2023 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.internal.database.model
18+
19+
import io.realm.RealmObject
20+
import io.realm.annotations.PrimaryKey
21+
import org.matrix.android.sdk.internal.session.room.poll.PollConstants
22+
23+
/**
24+
* Keeps track of the loading process of the poll history.
25+
*/
26+
internal open class PollHistoryStatusEntity(
27+
/**
28+
* The related room id.
29+
*/
30+
@PrimaryKey
31+
var roomId: String = "",
32+
33+
/**
34+
* Timestamp of the in progress poll sync target in backward direction in milliseconds.
35+
*/
36+
var currentTimestampTargetBackwardMs: Long? = null,
37+
38+
/**
39+
* Timestamp of the oldest event synced once target has been reached in milliseconds.
40+
*/
41+
var oldestTimestampTargetReachedMs: Long? = null,
42+
43+
/**
44+
* Id of the oldest event synced.
45+
*/
46+
var oldestEventIdReached: String? = null,
47+
48+
/**
49+
* Id of the most recent event synced.
50+
*/
51+
var mostRecentEventIdReached: String? = null,
52+
53+
/**
54+
* Indicate whether all polls in a room have been synced in backward direction.
55+
*/
56+
var isEndOfPollsBackward: Boolean = false,
57+
) : RealmObject() {
58+
59+
companion object
60+
61+
/**
62+
* Create a new instance of the entity with the same content.
63+
*/
64+
fun copy(): PollHistoryStatusEntity {
65+
return PollHistoryStatusEntity(
66+
roomId = roomId,
67+
currentTimestampTargetBackwardMs = currentTimestampTargetBackwardMs,
68+
oldestTimestampTargetReachedMs = oldestTimestampTargetReachedMs,
69+
oldestEventIdReached = oldestEventIdReached,
70+
mostRecentEventIdReached = mostRecentEventIdReached,
71+
isEndOfPollsBackward = isEndOfPollsBackward,
72+
)
73+
}
74+
75+
/**
76+
* Indicate whether at least one poll sync has been fully completed backward for the given room.
77+
*/
78+
val hasCompletedASyncBackward: Boolean
79+
get() = oldestTimestampTargetReachedMs != null
80+
81+
/**
82+
* Indicate whether all polls in a room have been synced for the current timestamp target in backward direction.
83+
*/
84+
val currentTimestampTargetBackwardReached: Boolean
85+
get() = checkIfCurrentTimestampTargetBackwardIsReached()
86+
87+
private fun checkIfCurrentTimestampTargetBackwardIsReached(): Boolean {
88+
val currentTarget = currentTimestampTargetBackwardMs
89+
val lastTarget = oldestTimestampTargetReachedMs
90+
// last timestamp target should be older or equal to the current target
91+
return currentTarget != null && lastTarget != null && lastTarget <= currentTarget
92+
}
93+
94+
/**
95+
* Compute the number of days of history currently synced.
96+
*/
97+
fun getNbSyncedDays(currentMs: Long): Int {
98+
val oldestTimestamp = oldestTimestampTargetReachedMs
99+
return if (oldestTimestamp == null) {
100+
0
101+
} else {
102+
((currentMs - oldestTimestamp).coerceAtLeast(0) / PollConstants.MILLISECONDS_PER_DAY).toInt()
103+
}
104+
}
105+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PollResponseAggregatedSummaryEntity.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,4 @@ internal open class PollResponseAggregatedSummaryEntity(
3636
var sourceLocalEchoEvents: RealmList<String> = RealmList(),
3737
// list of related event ids which are encrypted due to decryption failure
3838
var encryptedRelatedEventIds: RealmList<String> = RealmList(),
39-
) : RealmObject() {
40-
41-
companion object
42-
}
39+
) : RealmObject()

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntit
7373
UserPresenceEntity::class,
7474
ThreadSummaryEntity::class,
7575
ThreadListPageEntity::class,
76+
PollHistoryStatusEntity::class,
7677
]
7778
)
7879
internal class SessionRealmModule

0 commit comments

Comments
 (0)