-
Notifications
You must be signed in to change notification settings - Fork 781
saving sync filter changed #7627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
7d3e82d
eb7d15f
a3620b3
64a80b3
4560635
8ba7d9e
b6c4102
97abe52
795afc8
69b106e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Sync Filter now taking in account homeserver capabilities to not pass unsupported parameters. | ||
Sync Filter is now configured by providing SyncFilterBuilder class instance, instead of Filter to identify Filter changes related to homeserver capabilities |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Copyright 2020 The Matrix.org Foundation C.I.C. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.matrix.android.sdk.api.session.sync.filter | ||
|
||
internal data class SyncFilterParams( | ||
val lazyLoadMembersForStateEvents: Boolean? = null, | ||
val lazyLoadMembersForMessageEvents: Boolean? = null, | ||
val useThreadNotifications: Boolean? = null, | ||
val listOfSupportedEventTypes: List<String>? = null, | ||
val listOfSupportedStateEventTypes: List<String>? = null, | ||
) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,61 @@ | ||||||
/* | ||||||
* Copyright 2022 The Matrix.org Foundation C.I.C. | ||||||
* | ||||||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
* you may not use this file except in compliance with the License. | ||||||
* You may obtain a copy of the License at | ||||||
* | ||||||
* http://www.apache.org/licenses/LICENSE-2.0 | ||||||
* | ||||||
* Unless required by applicable law or agreed to in writing, software | ||||||
* distributed under the License is distributed on an "AS IS" BASIS, | ||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
* See the License for the specific language governing permissions and | ||||||
* limitations under the License. | ||||||
*/ | ||||||
|
||||||
package org.matrix.android.sdk.internal.database.mapper | ||||||
|
||||||
import io.realm.RealmList | ||||||
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterParams | ||||||
import org.matrix.android.sdk.internal.database.model.SyncFilterParamsEntity | ||||||
import javax.inject.Inject | ||||||
|
||||||
internal class FilterParamsMapper @Inject constructor() { | ||||||
|
||||||
fun map(entity: SyncFilterParamsEntity): SyncFilterParams { | ||||||
val eventTypes = if (entity.listOfSupportedEventTypesHasSet) { | ||||||
entity.listOfSupportedEventTypes?.toList() | ||||||
} else { | ||||||
null | ||||||
} | ||||||
val stateEventTypes = if (entity.listOfSupportedStateEventTypesHasSet) { | ||||||
entity.listOfSupportedStateEventTypes?.toList() | ||||||
} else { | ||||||
null | ||||||
} | ||||||
return SyncFilterParams( | ||||||
useThreadNotifications = entity.useThreadNotifications, | ||||||
lazyLoadMembersForMessageEvents = entity.lazyLoadMembersForMessageEvents, | ||||||
lazyLoadMembersForStateEvents = entity.lazyLoadMembersForStateEvents, | ||||||
listOfSupportedEventTypes = eventTypes, | ||||||
listOfSupportedStateEventTypes = stateEventTypes, | ||||||
) | ||||||
} | ||||||
|
||||||
fun map(params: SyncFilterParams): SyncFilterParamsEntity { | ||||||
return SyncFilterParamsEntity( | ||||||
useThreadNotifications = params.useThreadNotifications, | ||||||
lazyLoadMembersForMessageEvents = params.lazyLoadMembersForMessageEvents, | ||||||
lazyLoadMembersForStateEvents = params.lazyLoadMembersForStateEvents, | ||||||
listOfSupportedEventTypes = params.listOfSupportedEventTypes.toRealmList(), | ||||||
listOfSupportedEventTypesHasSet = params.listOfSupportedEventTypes != null, | ||||||
listOfSupportedStateEventTypes = params.listOfSupportedStateEventTypes.toRealmList(), | ||||||
listOfSupportedStateEventTypesHasSet = params.listOfSupportedEventTypes != null, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copy paste bug here:
Suggested change
|
||||||
) | ||||||
} | ||||||
|
||||||
private fun List<String>?.toRealmList(): RealmList<String>? { | ||||||
return this?.toTypedArray()?.let { RealmList(*it) } | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.matrix.android.sdk.internal.database.migration | ||
|
||
import io.realm.DynamicRealm | ||
import org.matrix.android.sdk.internal.database.model.SyncFilterParamsEntityFields | ||
import org.matrix.android.sdk.internal.util.database.RealmMigrator | ||
|
||
internal class MigrateSessionTo043(realm: DynamicRealm) : RealmMigrator(realm, 43) { | ||
|
||
override fun doMigrate(realm: DynamicRealm) { | ||
realm.schema.create("SyncFilterParamsEntity") | ||
.addField(SyncFilterParamsEntityFields.LAZY_LOAD_MEMBERS_FOR_STATE_EVENTS, Boolean::class.java) | ||
.addField(SyncFilterParamsEntityFields.LAZY_LOAD_MEMBERS_FOR_MESSAGE_EVENTS, Boolean::class.java) | ||
.addField(SyncFilterParamsEntityFields.LIST_OF_SUPPORTED_EVENT_TYPES_HAS_SET, Boolean::class.java) | ||
.addField(SyncFilterParamsEntityFields.LIST_OF_SUPPORTED_STATE_EVENT_TYPES_HAS_SET, Boolean::class.java) | ||
.addField(SyncFilterParamsEntityFields.USE_THREAD_NOTIFICATIONS, Boolean::class.java) | ||
.addRealmListField(SyncFilterParamsEntityFields.LIST_OF_SUPPORTED_EVENT_TYPES.`$`, String::class.java) | ||
.addRealmListField(SyncFilterParamsEntityFields.LIST_OF_SUPPORTED_STATE_EVENT_TYPES.`$`, String::class.java) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,36 @@ | ||||||
/* | ||||||
* Copyright 2020 The Matrix.org Foundation C.I.C. | ||||||
* | ||||||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
* you may not use this file except in compliance with the License. | ||||||
* You may obtain a copy of the License at | ||||||
* | ||||||
* http://www.apache.org/licenses/LICENSE-2.0 | ||||||
* | ||||||
* Unless required by applicable law or agreed to in writing, software | ||||||
* distributed under the License is distributed on an "AS IS" BASIS, | ||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
* See the License for the specific language governing permissions and | ||||||
* limitations under the License. | ||||||
*/ | ||||||
|
||||||
package org.matrix.android.sdk.internal.database.model | ||||||
|
||||||
import io.realm.RealmList | ||||||
import io.realm.RealmObject | ||||||
|
||||||
/** | ||||||
* This entity stores Sync Filter configuration data, provided by the client | ||||||
*/ | ||||||
internal open class SyncFilterParamsEntity( | ||||||
var lazyLoadMembersForStateEvents: Boolean? = null, | ||||||
var lazyLoadMembersForMessageEvents: Boolean? = null, | ||||||
var useThreadNotifications: Boolean? = null, | ||||||
var listOfSupportedEventTypes: RealmList<String>? = null, | ||||||
var listOfSupportedEventTypesHasSet: Boolean = false, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe rename to
Suggested change
|
||||||
var listOfSupportedStateEventTypes: RealmList<String>? = null, | ||||||
var listOfSupportedStateEventTypesHasSet: Boolean = false, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe rename to
Suggested change
|
||||||
) : RealmObject() { | ||||||
|
||||||
companion object | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,74 +17,71 @@ | |
package org.matrix.android.sdk.internal.session.filter | ||
|
||
import com.zhuinden.monarchy.Monarchy | ||
import io.realm.Realm | ||
import io.realm.kotlin.where | ||
import org.matrix.android.sdk.api.session.sync.filter.SyncFilterParams | ||
import org.matrix.android.sdk.internal.database.mapper.FilterParamsMapper | ||
import org.matrix.android.sdk.internal.database.model.FilterEntity | ||
import org.matrix.android.sdk.internal.database.model.FilterEntityFields | ||
import org.matrix.android.sdk.internal.database.model.SyncFilterParamsEntity | ||
import org.matrix.android.sdk.internal.database.query.get | ||
import org.matrix.android.sdk.internal.database.query.getOrCreate | ||
import org.matrix.android.sdk.internal.di.SessionDatabase | ||
import org.matrix.android.sdk.internal.util.awaitTransaction | ||
import javax.inject.Inject | ||
|
||
internal class DefaultFilterRepository @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : FilterRepository { | ||
internal class DefaultFilterRepository @Inject constructor( | ||
@SessionDatabase private val monarchy: Monarchy, | ||
) : FilterRepository { | ||
|
||
override suspend fun storeFilter(filter: Filter, roomEventFilter: RoomEventFilter): Boolean { | ||
return Realm.getInstance(monarchy.realmConfiguration).use { realm -> | ||
val filterEntity = FilterEntity.get(realm) | ||
// Filter has changed, or no filter Id yet | ||
filterEntity == null || | ||
filterEntity.filterBodyJson != filter.toJSONString() || | ||
filterEntity.filterId.isBlank() | ||
}.also { hasChanged -> | ||
if (hasChanged) { | ||
// Filter is new or has changed, store it and reset the filter Id. | ||
// This has to be done outside of the Realm.use(), because awaitTransaction change the current thread | ||
monarchy.awaitTransaction { realm -> | ||
// We manage only one filter for now | ||
val filterJson = filter.toJSONString() | ||
val roomEventFilterJson = roomEventFilter.toJSONString() | ||
override suspend fun storeSyncFilter(filter: Filter, filterId: String, roomEventFilter: RoomEventFilter) { | ||
monarchy.awaitTransaction { realm -> | ||
// We manage only one filter for now | ||
val filterJson = filter.toJSONString() | ||
val roomEventFilterJson = roomEventFilter.toJSONString() | ||
|
||
val filterEntity = FilterEntity.getOrCreate(realm) | ||
val filterEntity = FilterEntity.getOrCreate(realm) | ||
|
||
filterEntity.filterBodyJson = filterJson | ||
filterEntity.roomEventFilterJson = roomEventFilterJson | ||
// Reset filterId | ||
filterEntity.filterId = "" | ||
} | ||
} | ||
filterEntity.filterBodyJson = filterJson | ||
filterEntity.roomEventFilterJson = roomEventFilterJson | ||
filterEntity.filterId = filterId | ||
} | ||
} | ||
|
||
override suspend fun storeFilterId(filter: Filter, filterId: String) { | ||
monarchy.awaitTransaction { | ||
// We manage only one filter for now | ||
val filterJson = filter.toJSONString() | ||
|
||
// Update the filter id, only if the filter body matches | ||
it.where<FilterEntity>() | ||
.equalTo(FilterEntityFields.FILTER_BODY_JSON, filterJson) | ||
?.findFirst() | ||
?.filterId = filterId | ||
override suspend fun getStoredSyncFilterBody(): String { | ||
return monarchy.awaitTransaction { | ||
FilterEntity.getOrCreate(it).filterBodyJson | ||
} | ||
} | ||
|
||
override suspend fun getFilter(): String { | ||
override suspend fun getStoredSyncFilterId(): String? { | ||
return monarchy.awaitTransaction { | ||
val filter = FilterEntity.getOrCreate(it) | ||
if (filter.filterId.isBlank()) { | ||
// Use the Json format | ||
filter.filterBodyJson | ||
val id = FilterEntity.get(it)?.filterId | ||
if (id.isNullOrBlank()) { | ||
null | ||
} else { | ||
// Use FilterId | ||
filter.filterId | ||
id | ||
} | ||
} | ||
} | ||
|
||
override suspend fun getRoomFilter(): String { | ||
override suspend fun getRoomFilterBody(): String { | ||
return monarchy.awaitTransaction { | ||
FilterEntity.getOrCreate(it).roomEventFilterJson | ||
} | ||
} | ||
|
||
override suspend fun getStoredFilterParams(): SyncFilterParams? { | ||
return monarchy.awaitTransaction { realm -> | ||
realm.where<SyncFilterParamsEntity>().findFirst()?.let { | ||
val params = FilterParamsMapper().map(it) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
params | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe simplify those two lines to
(will also remove the indentation issue) |
||
} | ||
} | ||
} | ||
|
||
override suspend fun storeFilterParams(params: SyncFilterParams) { | ||
return monarchy.awaitTransaction { realm -> | ||
val entity = FilterParamsMapper().map(params) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use injected |
||
realm.insertOrUpdate(entity) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,20 +16,36 @@ | |
|
||
package org.matrix.android.sdk.internal.session.filter | ||
|
||
import kotlinx.coroutines.launch | ||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities | ||
import org.matrix.android.sdk.api.session.sync.FilterService | ||
import org.matrix.android.sdk.internal.session.homeserver.HomeServerCapabilitiesDataSource | ||
import org.matrix.android.sdk.internal.task.TaskExecutor | ||
import org.matrix.android.sdk.internal.task.configureWith | ||
import javax.inject.Inject | ||
|
||
internal class DefaultFilterService @Inject constructor( | ||
private val saveFilterTask: SaveFilterTask, | ||
private val taskExecutor: TaskExecutor | ||
private val taskExecutor: TaskExecutor, | ||
private val filterRepository: FilterRepository, | ||
private val homeServerCapabilitiesDataSource: HomeServerCapabilitiesDataSource, | ||
) : FilterService { | ||
|
||
// TODO Pass a list of support events instead | ||
override fun setFilter(filterPreset: FilterService.FilterPreset) { | ||
saveFilterTask | ||
.configureWith(SaveFilterTask.Params(filterPreset)) | ||
.executeBy(taskExecutor) | ||
override fun setSyncFilter(filterBuilder: SyncFilterBuilder) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe take the opportunity to make this fun suspendable? |
||
taskExecutor.executorScope.launch { | ||
filterRepository.storeFilterParams(filterBuilder.extractParams()) | ||
} | ||
|
||
// don't upload/store filter until homeserver capabilities are fetched | ||
homeServerCapabilitiesDataSource.getHomeServerCapabilities()?.let { homeServerCapabilities -> | ||
saveFilterTask | ||
.configureWith( | ||
SaveFilterTask.Params( | ||
filter = filterBuilder.build(homeServerCapabilities) | ||
) | ||
) | ||
.executeBy(taskExecutor) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you are in a suspend fun, I think you do not need to use the taskExecutor (it can be removed from the constructor). saveFilterTask.execute(
SaveFilterTask.Params(
filter = filterBuilder.build(homeServerCapabilities)
)
) Should be fine |
||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it's
internal
it should be moved to theinternal
package.