mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-17 15:09:31 +02:00
Merge pull request #7809 from element-hq/mauroromito/room_retention_implementation
Room retention event implementation
This commit is contained in:
12
Podfile.lock
12
Podfile.lock
@@ -39,9 +39,9 @@ PODS:
|
||||
- LoggerAPI (1.9.200):
|
||||
- Logging (~> 1.1)
|
||||
- Logging (1.4.0)
|
||||
- MatrixSDK (0.27.8):
|
||||
- MatrixSDK/Core (= 0.27.8)
|
||||
- MatrixSDK/Core (0.27.8):
|
||||
- MatrixSDK (0.27.9):
|
||||
- MatrixSDK/Core (= 0.27.9)
|
||||
- MatrixSDK/Core (0.27.9):
|
||||
- AFNetworking (~> 4.0.0)
|
||||
- GZIP (~> 1.3.0)
|
||||
- libbase58 (~> 0.1.4)
|
||||
@@ -49,7 +49,7 @@ PODS:
|
||||
- OLMKit (~> 3.2.5)
|
||||
- Realm (= 10.27.0)
|
||||
- SwiftyBeaver (= 1.9.5)
|
||||
- MatrixSDK/JingleCallStack (0.27.8):
|
||||
- MatrixSDK/JingleCallStack (0.27.9):
|
||||
- JitsiMeetSDKLite (= 8.1.2-lite)
|
||||
- MatrixSDK/Core
|
||||
- MatrixSDKCrypto (0.4.2)
|
||||
@@ -187,7 +187,7 @@ SPEC CHECKSUMS:
|
||||
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
||||
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
|
||||
Logging: beeb016c9c80cf77042d62e83495816847ef108b
|
||||
MatrixSDK: 4c5a8572a481340ab233451ad36c1322d371fae5
|
||||
MatrixSDK: 246fd1d3620afcbf8cb76794e9343ebf3cbf881b
|
||||
MatrixSDKCrypto: 736069ee0a5ec12852ab3498bf2242acecc443fc
|
||||
OLMKit: da115f16582e47626616874e20f7bb92222c7a51
|
||||
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
|
||||
@@ -209,4 +209,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: b622ffadc1a0fe5442787bd9023ca3d110384814
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
COCOAPODS: 1.14.3
|
||||
|
||||
58
Riot/Categories/MXRoomSummary.swift
Normal file
58
Riot/Categories/MXRoomSummary.swift
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Copyright 2024 New Vector Ltd
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Notification.Name {
|
||||
static let roomSummaryDidRemoveExpiredDataFromStore = Notification.Name(MXRoomSummary.roomSummaryDidRemoveExpiredDataFromStore)
|
||||
}
|
||||
|
||||
extension MXRoomSummary {
|
||||
@objc static let roomSummaryDidRemoveExpiredDataFromStore = "roomSummaryDidRemoveExpiredDataFromStore"
|
||||
@objc static let roomRetentionStateEventType = "m.room.retention"
|
||||
|
||||
private enum Constants {
|
||||
static let roomRetentionInDaysKey = "roomRetentionInDays"
|
||||
}
|
||||
/// Get the room messages retention period in days
|
||||
func roomRetentionPeriodInDays() -> uint {
|
||||
if let period = self.others[Constants.roomRetentionInDaysKey] as? uint {
|
||||
return period
|
||||
} else {
|
||||
return 365
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the timestamp below which the received messages must be removed from the store, and the display
|
||||
@objc func minimumTimestamp() -> UInt64 {
|
||||
let periodInMs = Tools.durationInMs(fromDays: self.roomRetentionPeriodInDays())
|
||||
let currentTs = (UInt64)(Date().timeIntervalSince1970 * 1000)
|
||||
return (currentTs - periodInMs)
|
||||
}
|
||||
|
||||
/// Remove the expired messages from the store.
|
||||
/// If some data are removed, this operation posts the notification: roomSummaryDidRemoveExpiredDataFromStore.
|
||||
/// This operation does not commit the potential change. We let the caller trigger the commit when this is the more suitable.
|
||||
///
|
||||
/// Provide a boolean telling whether some data have been removed.
|
||||
@objc func removeExpiredRoomContentsFromStore() -> Bool {
|
||||
let ret = self.mxSession.store.removeAllMessagesSent(before: self.minimumTimestamp(), inRoom: roomId)
|
||||
if ret {
|
||||
NotificationCenter.default.post(name: .roomSummaryDidRemoveExpiredDataFromStore, object: self)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
}
|
||||
@@ -25,4 +25,16 @@ extension MXSession {
|
||||
matrixItemId: userId,
|
||||
displayName: user?.displayname)
|
||||
}
|
||||
|
||||
/// Clean the storage of a session by removing the expired contents.
|
||||
@objc func removeExpiredMessages() {
|
||||
var hasStoreChanged = false
|
||||
for room in self.rooms {
|
||||
hasStoreChanged = hasStoreChanged || room.summary.removeExpiredRoomContentsFromStore()
|
||||
}
|
||||
|
||||
if hasStoreChanged {
|
||||
self.store.commit?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1826,6 +1826,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
[self registerNewRequestNotificationForSession:mxSession];
|
||||
|
||||
[self.pushNotificationService checkPushKitPushersInSession:mxSession];
|
||||
|
||||
// Clean the storage by removing expired data
|
||||
[mxSession removeExpiredMessages];
|
||||
}
|
||||
else if (mxSession.state == MXSessionStateRunning)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,9 @@ const CGFloat kTypingCellHeight = 24;
|
||||
{
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
// The listener to the room retention changes.
|
||||
id retentionListener;
|
||||
}
|
||||
|
||||
// Observe key verification request changes
|
||||
@@ -167,6 +170,31 @@ const CGFloat kTypingCellHeight = 24;
|
||||
self.eventFormatter.eventTypesFilterForMessages = [MXKAppSettings standardAppSettings].eventsFilterForMessages;
|
||||
}
|
||||
|
||||
- (void)setDelegate:(id<MXKDataSourceDelegate>)delegate
|
||||
{
|
||||
[self unregisterRoomSummaryDidRemoveExpiredDataFromStoreNotifications];
|
||||
[self removeRoomRetentionEventListener];
|
||||
|
||||
if (delegate && self.isLive)
|
||||
{
|
||||
if (self.room)
|
||||
{
|
||||
// Remove the potential expired messages from the store
|
||||
if ([self.room.summary removeExpiredRoomContentsFromStore])
|
||||
{
|
||||
[self.mxSession.store commit];
|
||||
}
|
||||
[self addRoomRetentionEventListener];
|
||||
}
|
||||
|
||||
// Observe room history flush (expired content data)
|
||||
[self registerRoomSummaryDidRemoveExpiredDataFromStoreNotifications];
|
||||
[self roomSummaryDidRemoveExpiredDataFromStore];
|
||||
}
|
||||
|
||||
[super setDelegate:delegate];
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
if (kThemeServiceDidChangeThemeNotificationObserver)
|
||||
@@ -197,6 +225,9 @@ const CGFloat kTypingCellHeight = 24;
|
||||
[self.mxSession.aggregations.beaconAggregations removeListener:self.beaconInfoSummaryDeletionListener];
|
||||
}
|
||||
|
||||
[self unregisterRoomSummaryDidRemoveExpiredDataFromStoreNotifications];
|
||||
[self removeRoomRetentionEventListener];
|
||||
|
||||
[super destroy];
|
||||
}
|
||||
|
||||
@@ -1242,4 +1273,79 @@ const CGFloat kTypingCellHeight = 24;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - roomSummaryDidRemoveExpiredDataFromStore notifications
|
||||
|
||||
- (void)registerRoomSummaryDidRemoveExpiredDataFromStoreNotifications
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(roomSummaryDidRemoveExpiredDataFromStore:) name:MXRoomSummary.roomSummaryDidRemoveExpiredDataFromStore object:nil];
|
||||
}
|
||||
|
||||
- (void)unregisterRoomSummaryDidRemoveExpiredDataFromStoreNotifications
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:MXRoomSummary.roomSummaryDidRemoveExpiredDataFromStore object:nil];
|
||||
}
|
||||
|
||||
- (void)roomSummaryDidRemoveExpiredDataFromStore:(NSNotification*)notification
|
||||
{
|
||||
MXRoomSummary *roomSummary = notification.object;
|
||||
if (self.mxSession == roomSummary.mxSession && [self.roomId isEqualToString:roomSummary.roomId])
|
||||
{
|
||||
[self roomSummaryDidRemoveExpiredDataFromStore];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)roomSummaryDidRemoveExpiredDataFromStore
|
||||
{
|
||||
// Check whether the first cell data refers to an expired event (this may be a state event
|
||||
MXEvent *firstMessageEvent;
|
||||
for (id<MXKRoomBubbleCellDataStoring> cellData in bubbles)
|
||||
{
|
||||
for (MXEvent *event in cellData.events)
|
||||
{
|
||||
if (!event.isState) {
|
||||
firstMessageEvent = event;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstMessageEvent)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstMessageEvent && firstMessageEvent.originServerTs < self.room.summary.minimumTimestamp)
|
||||
{
|
||||
[self reload];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - room retention event listener
|
||||
|
||||
- (void)addRoomRetentionEventListener
|
||||
{
|
||||
// Register a listener to handle the room retention in live timelines
|
||||
retentionListener = [self.timeline listenToEventsOfTypes:@[MXRoomSummary.roomRetentionStateEventType] onEvent:^(MXEvent *redactionEvent, MXTimelineDirection direction, MXRoomState *roomState) {
|
||||
|
||||
// Consider only live events
|
||||
if (direction == MXTimelineDirectionForwards)
|
||||
{
|
||||
// Remove the potential expired messages from the store
|
||||
if ([self.room.summary removeExpiredRoomContentsFromStore])
|
||||
{
|
||||
[self.mxSession.store commit];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)removeRoomRetentionEventListener
|
||||
{
|
||||
if (retentionListener)
|
||||
{
|
||||
[self.timeline removeListener:retentionListener];
|
||||
retentionListener = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -48,4 +48,17 @@
|
||||
*/
|
||||
+ (NSURL*)fixURLWithSeveralHashKeys:(NSURL*)url;
|
||||
|
||||
#pragma mark - Time utilities
|
||||
|
||||
/**
|
||||
* Convert a number of days to a duration in ms.
|
||||
*/
|
||||
+ (uint64_t)durationInMsFromDays:(uint)days;
|
||||
|
||||
/**
|
||||
* Convert a duration in ms to a number of days.
|
||||
*/
|
||||
+ (uint)numberOfDaysFromDurationInMs:(uint64_t)duration;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -117,4 +117,16 @@
|
||||
return fixedURL;
|
||||
}
|
||||
|
||||
#pragma mark - Time utilities
|
||||
|
||||
+ (uint64_t)durationInMsFromDays:(uint)days
|
||||
{
|
||||
return days * (uint64_t)(86400000);
|
||||
}
|
||||
|
||||
+ (uint)numberOfDaysFromDurationInMs:(uint64_t)duration
|
||||
{
|
||||
return (uint)(duration / 86400000);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Submodule matrix-ios-sdk updated: 3052a396b8...fcfbb67182
Reference in New Issue
Block a user