From 208ea79de16d74e6e962e279209175cf579ffb48 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 30 May 2024 14:23:21 +0100 Subject: [PATCH 01/39] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index c4af686bf..281e714ad 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.11.12 -CURRENT_PROJECT_VERSION = 1.11.12 +MARKETING_VERSION = 1.11.13 +CURRENT_PROJECT_VERSION = 1.11.13 From 67efa74d65b21e3efcc6740c8721673a78a19199 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 21 May 2024 16:02:46 +0200 Subject: [PATCH 02/39] Bump posthog version to 3.25 --- Podfile | 2 - Podfile.lock | 6 +-- .../xcshareddata/swiftpm/Package.resolved | 17 ++++++-- Riot/Modules/Analytics/Analytics.swift | 1 - .../Analytics/PHGPostHogConfiguration.swift | 12 +++--- .../Analytics/PostHogAnalyticsClient.swift | 40 ++++++------------- Riot/target.yml | 1 + RiotNSE/target.yml | 1 + RiotTests/AnalyticsTests.swift | 3 +- project.yml | 3 ++ 10 files changed, 41 insertions(+), 45 deletions(-) diff --git a/Podfile b/Podfile index a2e54f0e9..3fb43f417 100644 --- a/Podfile +++ b/Podfile @@ -69,8 +69,6 @@ abstract_target 'RiotPods' do pod 'KeychainAccess', '~> 4.2.2' pod 'WeakDictionary', '~> 2.0' - # PostHog for analytics - pod 'PostHog', '~> 2.0.0' pod 'Sentry', '~> 7.15.0' pod 'OLMKit' diff --git a/Podfile.lock b/Podfile.lock index 99552b321..92be4cf9c 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -58,7 +58,6 @@ PODS: - OLMKit/olmcpp (= 3.2.12) - OLMKit/olmc (3.2.12) - OLMKit/olmcpp (3.2.12) - - PostHog (2.0.0) - ReadMoreTextView (3.0.1) - Realm (10.27.0): - Realm/Headers (= 10.27.0) @@ -105,7 +104,6 @@ DEPENDENCIES: - MatrixSDK (= 0.27.8) - MatrixSDK/JingleCallStack (= 0.27.8) - OLMKit - - PostHog (~> 2.0.0) - ReadMoreTextView (~> 3.0.1) - Reusable (~> 4.1) - Sentry (~> 7.15.0) @@ -147,7 +145,6 @@ SPEC REPOS: - MatrixSDK - MatrixSDKCrypto - OLMKit - - PostHog - ReadMoreTextView - Realm - Reusable @@ -190,7 +187,6 @@ SPEC CHECKSUMS: MatrixSDK: 4c5a8572a481340ab233451ad36c1322d371fae5 MatrixSDKCrypto: 736069ee0a5ec12852ab3498bf2242acecc443fc OLMKit: da115f16582e47626616874e20f7bb92222c7a51 - PostHog: 660ec6c9d80cec17b685e148f17f6785a88b597d ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d Realm: 9ca328bd7e700cc19703799785e37f77d1a130f2 Reusable: 6bae6a5e8aa793c9c441db0213c863a64bce9136 @@ -210,4 +206,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: b6073389caf93d20d47c9e511f4b9c3e1ad6dc5d -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2d8489845..bb13eadb2 100644 --- a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/devicekit/DeviceKit", "state" : { - "revision" : "20e0991f3975916ab0f6d58db84d8bc64f883537", - "version" : "4.7.0" + "revision" : "d37e70cb2646666dcf276d7d3d4a9760a41ff8a6", + "version" : "4.9.0" } }, { @@ -72,13 +72,22 @@ "version" : "0.8.4" } }, + { + "identity" : "posthog-ios", + "kind" : "remoteSourceControl", + "location" : "https://github.com/PostHog/posthog-ios", + "state" : { + "revision" : "8b2508444962d67aa5f8770074f32d493383dafd", + "version" : "3.2.5" + } + }, { "identity" : "swift-collections", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections", "state" : { - "revision" : "48254824bb4248676bf7ce56014ff57b142b77eb", - "version" : "1.0.2" + "revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb", + "version" : "1.1.0" } }, { diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index d9d68e2f8..270f1b3ef 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -14,7 +14,6 @@ // limitations under the License. // -import PostHog import AnalyticsEvents /// A class responsible for managing a variety of analytics clients diff --git a/Riot/Modules/Analytics/PHGPostHogConfiguration.swift b/Riot/Modules/Analytics/PHGPostHogConfiguration.swift index 8bed04920..875de74e4 100644 --- a/Riot/Modules/Analytics/PHGPostHogConfiguration.swift +++ b/Riot/Modules/Analytics/PHGPostHogConfiguration.swift @@ -16,14 +16,16 @@ import PostHog -extension PHGPostHogConfiguration { - static var standard: PHGPostHogConfiguration? { +extension PostHogConfig { + static var standard: PostHogConfig? { let analyticsConfiguration = BuildSettings.analyticsConfiguration guard analyticsConfiguration.isEnabled else { return nil } - let postHogConfiguration = PHGPostHogConfiguration(apiKey: analyticsConfiguration.apiKey, host: analyticsConfiguration.host) - postHogConfiguration.shouldSendDeviceID = false - + let postHogConfiguration = PostHogConfig(apiKey: analyticsConfiguration.apiKey, host: analyticsConfiguration.host) + // We capture screens manually + postHogConfiguration.captureScreenViews = false + + return postHogConfiguration } } diff --git a/Riot/Modules/Analytics/PostHogAnalyticsClient.swift b/Riot/Modules/Analytics/PostHogAnalyticsClient.swift index ec49716be..4df8f5d41 100644 --- a/Riot/Modules/Analytics/PostHogAnalyticsClient.swift +++ b/Riot/Modules/Analytics/PostHogAnalyticsClient.swift @@ -20,30 +20,31 @@ import AnalyticsEvents /// An analytics client that reports events to a PostHog server. class PostHogAnalyticsClient: AnalyticsClientProtocol { /// The PHGPostHog object used to report events. - private var postHog: PHGPostHog? + private var postHog: PostHogSDK? /// Any user properties to be included with the next captured event. private(set) var pendingUserProperties: AnalyticsEvent.UserProperties? static let shared = PostHogAnalyticsClient() - var isRunning: Bool { postHog?.enabled ?? false } + var isRunning: Bool { postHog != nil } func start() { // Only start if analytics have been configured in BuildSettings - guard let configuration = PHGPostHogConfiguration.standard else { return } + guard let configuration = PostHogConfig.standard else { return } if postHog == nil { - postHog = PHGPostHog(configuration: configuration) + PostHogSDK.shared.setup(configuration) + postHog = PostHogSDK.shared } - postHog?.enable() + postHog?.optIn() } func identify(id: String) { if let userProperties = pendingUserProperties { // As user properties overwrite old ones, compactMap the dictionary to avoid resetting any missing properties - postHog?.identify(id, properties: userProperties.properties.compactMapValues { $0 }) + postHog?.identify(id, userProperties: userProperties.properties.compactMapValues { $0 }) pendingUserProperties = nil } else { postHog?.identify(id) @@ -56,10 +57,9 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol { } func stop() { - postHog?.disable() + postHog?.optOut() - // As of PostHog 1.4.4, setting the client to nil here doesn't release - // it. Keep it around to avoid having multiple instances if the user re-enables + self.postHog = nil } func flush() { @@ -67,11 +67,13 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol { } func capture(_ event: AnalyticsEventProtocol) { - postHog?.capture(event.eventName, properties: attachUserProperties(to: event.properties)) + postHog?.capture(event.eventName, properties: event.properties, userProperties: pendingUserProperties?.properties.compactMapValues { $0 }) + // Pending user properties have been added + self.pendingUserProperties = nil } func screen(_ event: AnalyticsScreenProtocol) { - postHog?.screen(event.screenName.rawValue, properties: attachUserProperties(to: event.properties)) + postHog?.screen(event.screenName.rawValue, properties: event.properties) } func updateUserProperties(_ userProperties: AnalyticsEvent.UserProperties) { @@ -87,22 +89,6 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol { numSpaces: userProperties.numSpaces ?? pendingUserProperties.numSpaces) } - // MARK: - Private - - /// Given a dictionary containing properties from an event, this method will return those properties - /// with any pending user properties included under the `$set` key. - /// - Parameter properties: A dictionary of properties from an event. - /// - Returns: The `properties` dictionary with any user properties included. - private func attachUserProperties(to properties: [String: Any]) -> [String: Any] { - guard isRunning, let userProperties = pendingUserProperties else { return properties } - - var properties = properties - - // As user properties overwrite old ones via $set, compactMap the dictionary to avoid resetting any missing properties - properties["$set"] = userProperties.properties.compactMapValues { $0 } - pendingUserProperties = nil - return properties - } } extension PostHogAnalyticsClient: RemoteFeaturesClientProtocol { diff --git a/Riot/target.yml b/Riot/target.yml index 352988bf3..c95d3cb3a 100644 --- a/Riot/target.yml +++ b/Riot/target.yml @@ -49,6 +49,7 @@ targets: - package: WysiwygComposer - package: DeviceKit - package: DTCoreText + - package: PostHog configFiles: Debug: Debug.xcconfig diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml index 6bc5a474d..f046bc0fd 100644 --- a/RiotNSE/target.yml +++ b/RiotNSE/target.yml @@ -35,6 +35,7 @@ targets: - package: AnalyticsEvents - package: DeviceKit - package: DTCoreText + - package: PostHog configFiles: Debug: Debug.xcconfig diff --git a/RiotTests/AnalyticsTests.swift b/RiotTests/AnalyticsTests.swift index 33ed28389..73f3f66b1 100644 --- a/RiotTests/AnalyticsTests.swift +++ b/RiotTests/AnalyticsTests.swift @@ -127,7 +127,8 @@ class AnalyticsTests: XCTestCase { XCTAssertEqual(client.pendingUserProperties?.ftueUseCaseSelection, .PersonalMessaging, "The use case selection should match.") // When sending an event (tests run under Debug configuration so this is sent to the development instance) - client.screen(AnalyticsEvent.MobileScreen(durationMs: nil, screenName: .Home)) + let event = AnalyticsEvent.Signup(authenticationType: .Other) + client.capture(event) // Then the properties should be cleared XCTAssertNil(client.pendingUserProperties, "The user properties should be cleared.") diff --git a/project.yml b/project.yml index c44219382..a666fb1b7 100644 --- a/project.yml +++ b/project.yml @@ -66,3 +66,6 @@ packages: DTCoreText: url: https://github.com/Cocoanetics/DTCoreText version: 1.6.26 + PostHog: + url: https://github.com/PostHog/posthog-ios + minorVersion: 3.2.5 From b664de479eb428b5d42acfbf087089ba6670ff4e Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 27 May 2024 16:06:25 +0200 Subject: [PATCH 03/39] Review: use optout for isrunning --- Riot/Modules/Analytics/PostHogAnalyticsClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Analytics/PostHogAnalyticsClient.swift b/Riot/Modules/Analytics/PostHogAnalyticsClient.swift index 4df8f5d41..ac22db68f 100644 --- a/Riot/Modules/Analytics/PostHogAnalyticsClient.swift +++ b/Riot/Modules/Analytics/PostHogAnalyticsClient.swift @@ -27,7 +27,7 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol { static let shared = PostHogAnalyticsClient() - var isRunning: Bool { postHog != nil } + var isRunning: Bool { postHog != nil && !postHog!.isOptOut() } func start() { // Only start if analytics have been configured in BuildSettings From e1b9bbbab8961c581f384e11d3c996b4a440c367 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 31 May 2024 15:54:21 +0200 Subject: [PATCH 04/39] post rebase fix --- Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podfile.lock b/Podfile.lock index 92be4cf9c..b830adadb 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -204,6 +204,6 @@ SPEC CHECKSUMS: zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -PODFILE CHECKSUM: b6073389caf93d20d47c9e511f4b9c3e1ad6dc5d +PODFILE CHECKSUM: 3bbda8faf037705f421dad839d6f5b1aef399f99 COCOAPODS: 1.15.2 From a4a73b1a927cf584d9f84f2de92faf31906b4fae Mon Sep 17 00:00:00 2001 From: Valere Date: Sat, 1 Jun 2024 13:05:04 +0200 Subject: [PATCH 05/39] Analytics | Add support for super properties and appPlatform --- .../xcshareddata/swiftpm/Package.resolved | 4 +- Riot/Modules/Analytics/Analytics.swift | 17 ++- .../Analytics/AnalyticsClientProtocol.swift | 7 + .../Analytics/PostHogAnalyticsClient.swift | 56 +++++++- Riot/Modules/Analytics/PosthogProtocol.swift | 53 +++++++ RiotTests/AnalyticsTests.swift | 12 +- RiotTests/FakeUtils.swift | 133 ++++++++++++++++++ RiotTests/PostHogAnalyticsClientTests.swift | 113 +++++++++++++++ project.yml | 2 +- 9 files changed, 380 insertions(+), 17 deletions(-) create mode 100644 Riot/Modules/Analytics/PosthogProtocol.swift create mode 100644 RiotTests/PostHogAnalyticsClientTests.swift diff --git a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved index bb13eadb2..c90d47d46 100644 --- a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/matrix-org/matrix-analytics-events", "state" : { - "revision" : "44d5a0e898a71f8abbbe12afe9d73e82d370a9a1", - "version" : "0.15.0" + "revision" : "de0cac487e5e7f607ee17045882204c91585461f", + "version" : "0.23.1" } }, { diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index 270f1b3ef..f284c2aa4 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -94,6 +94,13 @@ import AnalyticsEvents guard let session = session else { return } useAnalyticsSettings(from: session) + self.client.updateSuperProperties( + AnalyticsEvent.SuperProperties( + appPlatform: .EI, + cryptoSDK: .Rust, + cryptoSDKVersion: session.crypto.version + ) + ) } /// Stops analytics tracking and calls `reset` to clear any IDs and event queues. @@ -148,6 +155,13 @@ import AnalyticsEvents switch result { case .success(let settings): self.identify(with: settings) + self.client.updateSuperProperties( + AnalyticsEvent.SuperProperties( + appPlatform: .EI, + cryptoSDK: .Rust, + cryptoSDKVersion: session.crypto.version + ) + ) self.service = nil case .failure: MXLog.error("[Analytics] Failed to use analytics settings. Will continue to run without analytics ID.") @@ -242,7 +256,8 @@ extension Analytics { let userProperties = AnalyticsEvent.UserProperties(allChatsActiveFilter: allChatsActiveFilter?.analyticsName, ftueUseCaseSelection: ftueUseCase?.analyticsName, numFavouriteRooms: numFavouriteRooms, - numSpaces: numSpaces) + numSpaces: numSpaces, + recoveryState: nil, verificationState: nil) client.updateUserProperties(userProperties) } diff --git a/Riot/Modules/Analytics/AnalyticsClientProtocol.swift b/Riot/Modules/Analytics/AnalyticsClientProtocol.swift index e16b962e5..1e0acc54e 100644 --- a/Riot/Modules/Analytics/AnalyticsClientProtocol.swift +++ b/Riot/Modules/Analytics/AnalyticsClientProtocol.swift @@ -53,4 +53,11 @@ protocol AnalyticsClientProtocol { /// be a delay when updating user properties as these are cached to be included /// as part of the next event that gets captured. func updateUserProperties(_ userProperties: AnalyticsEvent.UserProperties) + + + /// Updates the user properties. + /// Super properties added to all captured events and screen. + /// - Parameter superProperties: The properties event to capture. + func updateSuperProperties(_ event: AnalyticsEvent.SuperProperties) + } diff --git a/Riot/Modules/Analytics/PostHogAnalyticsClient.swift b/Riot/Modules/Analytics/PostHogAnalyticsClient.swift index ac22db68f..5a70c5837 100644 --- a/Riot/Modules/Analytics/PostHogAnalyticsClient.swift +++ b/Riot/Modules/Analytics/PostHogAnalyticsClient.swift @@ -19,23 +19,39 @@ import AnalyticsEvents /// An analytics client that reports events to a PostHog server. class PostHogAnalyticsClient: AnalyticsClientProtocol { + + private var posthogFactory: PostHogFactory = DefaultPostHogFactory() + + init(posthogFactory: PostHogFactory? = nil) { + if let factory = posthogFactory { + self.posthogFactory = factory + } + } + /// The PHGPostHog object used to report events. - private var postHog: PostHogSDK? + private var postHog: PostHogProtocol? /// Any user properties to be included with the next captured event. private(set) var pendingUserProperties: AnalyticsEvent.UserProperties? + /// Super Properties are properties associated with events that are set once and then sent with every capture call, be it a $screen, an autocaptured button click, or anything else. + /// It is different from user properties that will be attached to the user and not events. + /// Not persisted for now, should be set on start. + private var superProperties: AnalyticsEvent.SuperProperties? + static let shared = PostHogAnalyticsClient() - var isRunning: Bool { postHog != nil && !postHog!.isOptOut() } + var isRunning: Bool { + guard let postHog else { return false } + return !postHog.isOptOut() + } func start() { // Only start if analytics have been configured in BuildSettings guard let configuration = PostHogConfig.standard else { return } if postHog == nil { - PostHogSDK.shared.setup(configuration) - postHog = PostHogSDK.shared + postHog = posthogFactory.createPostHog(config: configuration) } postHog?.optIn() @@ -67,13 +83,13 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol { } func capture(_ event: AnalyticsEventProtocol) { - postHog?.capture(event.eventName, properties: event.properties, userProperties: pendingUserProperties?.properties.compactMapValues { $0 }) + postHog?.capture(event.eventName, properties: attachSuperProperties(to: event.properties), userProperties: pendingUserProperties?.properties.compactMapValues { $0 }) // Pending user properties have been added self.pendingUserProperties = nil } func screen(_ event: AnalyticsScreenProtocol) { - postHog?.screen(event.screenName.rawValue, properties: event.properties) + postHog?.screen(event.screenName.rawValue, properties: attachSuperProperties(to: event.properties)) } func updateUserProperties(_ userProperties: AnalyticsEvent.UserProperties) { @@ -86,9 +102,35 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol { self.pendingUserProperties = AnalyticsEvent.UserProperties(allChatsActiveFilter: userProperties.allChatsActiveFilter ?? pendingUserProperties.allChatsActiveFilter, ftueUseCaseSelection: userProperties.ftueUseCaseSelection ?? pendingUserProperties.ftueUseCaseSelection, numFavouriteRooms: userProperties.numFavouriteRooms ?? pendingUserProperties.numFavouriteRooms, - numSpaces: userProperties.numSpaces ?? pendingUserProperties.numSpaces) + numSpaces: userProperties.numSpaces ?? pendingUserProperties.numSpaces, + // Not yet supported + recoveryState: nil, verificationState: nil) } + func updateSuperProperties(_ updatedProperties: AnalyticsEvent.SuperProperties) { + self.superProperties = AnalyticsEvent.SuperProperties( + appPlatform: updatedProperties.appPlatform ?? superProperties?.appPlatform, + cryptoSDK: updatedProperties.cryptoSDK ?? superProperties?.cryptoSDK, + cryptoSDKVersion: updatedProperties.cryptoSDKVersion ?? superProperties?.cryptoSDKVersion + ) + } + + /// Attach super properties to events. + /// If the property is already set on the event, the already set value will be kept. + private func attachSuperProperties(to properties: [String: Any]) -> [String: Any] { + guard isRunning, let superProperties else { return properties } + + var properties = properties + + superProperties.properties.forEach { (key: String, value: Any) in + if properties[key] == nil { + properties[key] = value + } + } + return properties + } + + } extension PostHogAnalyticsClient: RemoteFeaturesClientProtocol { diff --git a/Riot/Modules/Analytics/PosthogProtocol.swift b/Riot/Modules/Analytics/PosthogProtocol.swift new file mode 100644 index 000000000..d24d19e17 --- /dev/null +++ b/Riot/Modules/Analytics/PosthogProtocol.swift @@ -0,0 +1,53 @@ +// +// 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 +import PostHog + +protocol PostHogProtocol { + func optIn() + + func optOut() + + func reset() + + func flush() + + func capture(_ event: String, properties: [String: Any]?, userProperties: [String: Any]?) + + func screen(_ screenTitle: String, properties: [String: Any]?) + + func isFeatureEnabled(_ feature: String) -> Bool + + func identify(_ distinctId: String) + + func identify(_ distinctId: String, userProperties: [String: Any]?) + + func isOptOut() -> Bool +} + +protocol PostHogFactory { + func createPostHog(config: PostHogConfig) -> PostHogProtocol +} + +class DefaultPostHogFactory: PostHogFactory { + func createPostHog(config: PostHogConfig) -> PostHogProtocol { + PostHogSDK.shared.setup(config) + return PostHogSDK.shared + } +} + +extension PostHogSDK: PostHogProtocol { } diff --git a/RiotTests/AnalyticsTests.swift b/RiotTests/AnalyticsTests.swift index 73f3f66b1..a8759c017 100644 --- a/RiotTests/AnalyticsTests.swift +++ b/RiotTests/AnalyticsTests.swift @@ -78,7 +78,7 @@ class AnalyticsTests: XCTestCase { XCTAssertNil(client.pendingUserProperties, "No user properties should have been set yet.") // When updating the user properties - client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging, numFavouriteRooms: 4, numSpaces: 5)) + client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging, numFavouriteRooms: 4, numSpaces: 5, recoveryState: nil, verificationState: nil)) // Then the properties should be cached XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") @@ -90,7 +90,7 @@ class AnalyticsTests: XCTestCase { func testMergingUserProperties() { // Given a client with a cached use case user properties let client = PostHogAnalyticsClient() - client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging, numFavouriteRooms: nil, numSpaces: nil)) + client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging, numFavouriteRooms: nil, numSpaces: nil, recoveryState: nil, verificationState: nil)) XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") XCTAssertEqual(client.pendingUserProperties?.ftueUseCaseSelection, .PersonalMessaging, "The use case selection should match.") @@ -98,7 +98,7 @@ class AnalyticsTests: XCTestCase { XCTAssertNil(client.pendingUserProperties?.numSpaces, "The number of spaces should not be set.") // When updating the number of spaces - client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: nil, numFavouriteRooms: 4, numSpaces: 5)) + client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: nil, numFavouriteRooms: 4, numSpaces: 5, recoveryState: nil, verificationState: nil)) // Then the new properties should be updated and the existing properties should remain unchanged XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") @@ -107,7 +107,7 @@ class AnalyticsTests: XCTestCase { XCTAssertEqual(client.pendingUserProperties?.numSpaces, 5, "The number of spaces should have been updated.") // When updating the number of spaces - client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: .Favourites, ftueUseCaseSelection: nil, numFavouriteRooms: nil, numSpaces: nil)) + client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: .Favourites, ftueUseCaseSelection: nil, numFavouriteRooms: nil, numSpaces: nil, recoveryState: nil, verificationState: nil)) // Then the new properties should be updated and the existing properties should remain unchanged XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") @@ -120,7 +120,7 @@ class AnalyticsTests: XCTestCase { func testSendingUserProperties() { // Given a client with user properties set let client = PostHogAnalyticsClient() - client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging, numFavouriteRooms: nil, numSpaces: nil)) + client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging, numFavouriteRooms: nil, numSpaces: nil, recoveryState: nil, verificationState: nil)) client.start() XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") @@ -137,7 +137,7 @@ class AnalyticsTests: XCTestCase { func testSendingUserPropertiesWithIdentify() { // Given a client with user properties set let client = PostHogAnalyticsClient() - client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging, numFavouriteRooms: nil, numSpaces: nil)) + client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging, numFavouriteRooms: nil, numSpaces: nil, recoveryState: nil, verificationState: nil)) client.start() XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.") diff --git a/RiotTests/FakeUtils.swift b/RiotTests/FakeUtils.swift index 6077a449e..2f2ad4e63 100644 --- a/RiotTests/FakeUtils.swift +++ b/RiotTests/FakeUtils.swift @@ -15,6 +15,8 @@ // import Foundation +import PostHog +@testable import Element class FakeEvent: MXEvent { @@ -346,3 +348,134 @@ class FakeKeyVerificationManager: NSObject, MXKeyVerificationManager { } } + +class MockPostHog: PostHogProtocol { + + private var enabled = false + + func optIn() { + enabled = true + } + + func optOut() { + enabled = false + } + + func reset() { + + } + + func flush() { + + } + + var capturePropertiesUserPropertiesUnderlyingCallsCount = 0 + var capturePropertiesUserPropertiesCallsCount: Int { + get { + if Thread.isMainThread { + return capturePropertiesUserPropertiesUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = capturePropertiesUserPropertiesUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + capturePropertiesUserPropertiesUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + capturePropertiesUserPropertiesUnderlyingCallsCount = newValue + } + } + } + } + var capturePropertiesUserPropertiesCalled: Bool { + return capturePropertiesUserPropertiesCallsCount > 0 + } + var capturePropertiesUserPropertiesReceivedArguments: (event: String, properties: [String: Any]?, userProperties: [String: Any]?)? + var capturePropertiesUserPropertiesReceivedInvocations: [(event: String, properties: [String: Any]?, userProperties: [String: Any]?)] = [] + var capturePropertiesUserPropertiesClosure: ((String, [String: Any]?, [String: Any]?) -> Void)? + + func capture(_ event: String, properties: [String: Any]?, userProperties: [String: Any]?) { + if !enabled { return } + capturePropertiesUserPropertiesCallsCount += 1 + capturePropertiesUserPropertiesReceivedArguments = (event: event, properties: properties, userProperties: userProperties) + capturePropertiesUserPropertiesReceivedInvocations.append((event: event, properties: properties, userProperties: userProperties)) + capturePropertiesUserPropertiesClosure?(event, properties, userProperties) + } + + var screenPropertiesUnderlyingCallsCount = 0 + var screenPropertiesCallsCount: Int { + get { + if Thread.isMainThread { + return screenPropertiesUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = screenPropertiesUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + screenPropertiesUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + screenPropertiesUnderlyingCallsCount = newValue + } + } + } + } + + var screenPropertiesCalled: Bool { + return screenPropertiesCallsCount > 0 + } + var screenPropertiesReceivedArguments: (screenTitle: String, properties: [String: Any]?)? + var screenPropertiesReceivedInvocations: [(screenTitle: String, properties: [String: Any]?)] = [] + var screenPropertiesClosure: ((String, [String: Any]?) -> Void)? + + func screen(_ screenTitle: String, properties: [String: Any]?) { + if !enabled { return } + screenPropertiesCallsCount += 1 + screenPropertiesReceivedArguments = (screenTitle: screenTitle, properties: properties) + screenPropertiesReceivedInvocations.append((screenTitle: screenTitle, properties: properties)) + screenPropertiesClosure?(screenTitle, properties) + } + + func isFeatureEnabled(_ feature: String) -> Bool { + return true + } + + func identify(_ distinctId: String) { + + } + + func identify(_ distinctId: String, userProperties: [String : Any]?) { + + } + + func isOptOut() -> Bool { + !enabled + } + + +} + +class MockPostHogFactory: PostHogFactory { + var mock: PostHogProtocol! + + init(mock: PostHogProtocol) { + self.mock = mock + } + + func createPostHog(config: PostHogConfig) -> PostHogProtocol { + mock + } +} + diff --git a/RiotTests/PostHogAnalyticsClientTests.swift b/RiotTests/PostHogAnalyticsClientTests.swift new file mode 100644 index 000000000..081c54688 --- /dev/null +++ b/RiotTests/PostHogAnalyticsClientTests.swift @@ -0,0 +1,113 @@ +// +// 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 XCTest +@testable import Element +import AnalyticsEvents + +class PostHogAnalyticsClientTests: XCTestCase { + + private var posthogMock: MockPostHog! + + override func setUp() { + posthogMock = MockPostHog() + } + + func testSuperPropertiesAddedToAllCaptured() { + let analyticsClient = PostHogAnalyticsClient(posthogFactory: MockPostHogFactory(mock: posthogMock)) + analyticsClient.start() + + let superProperties = AnalyticsEvent.SuperProperties(appPlatform: .EI, cryptoSDK: .Rust, cryptoSDKVersion: "0.0") + + analyticsClient.updateSuperProperties(superProperties) + // It should be the same for any event + let someEvent = AnalyticsEvent.CallEnded(durationMs: 0, isVideo: false, numParticipants: 1, placed: true) + analyticsClient.capture(someEvent) + + let capturedEvent = posthogMock.capturePropertiesUserPropertiesReceivedArguments + + // All the super properties should have been added + XCTAssertEqual(capturedEvent?.properties?["cryptoSDK"] as? String, AnalyticsEvent.SuperProperties.CryptoSDK.Rust.rawValue) + XCTAssertEqual(capturedEvent?.properties?["appPlatform"] as? String, AnalyticsEvent.SuperProperties.AppPlatform.EI.rawValue) + XCTAssertEqual(capturedEvent?.properties?["cryptoSDKVersion"] as? String, "0.0") + + // Other properties should be there + XCTAssertEqual(capturedEvent?.properties?["isVideo"] as? Bool, false) + + // Should also work for screens + + analyticsClient.screen(AnalyticsEvent.MobileScreen.init(durationMs: 0, screenName: .Home)) + + + let capturedScreen = posthogMock.screenPropertiesReceivedArguments + + + XCTAssertEqual(capturedScreen?.properties?["cryptoSDK"] as? String, AnalyticsEvent.SuperProperties.CryptoSDK.Rust.rawValue) + XCTAssertEqual(capturedScreen?.properties?["appPlatform"] as? String, AnalyticsEvent.SuperProperties.AppPlatform.EI.rawValue) + XCTAssertEqual(capturedScreen?.properties?["cryptoSDKVersion"] as? String, "0.0") + + + XCTAssertEqual(capturedScreen?.screenTitle, AnalyticsEvent.MobileScreen.ScreenName.Home.rawValue) + + + } + + func testSuperPropertiesCanBeUdpated() { + let analyticsClient = PostHogAnalyticsClient(posthogFactory: MockPostHogFactory(mock: posthogMock)) + analyticsClient.start() + + let superProperties = AnalyticsEvent.SuperProperties(appPlatform: .EI, cryptoSDK: .Rust, cryptoSDKVersion: "0.0") + + analyticsClient.updateSuperProperties(superProperties) + // It should be the same for any event + let someEvent = AnalyticsEvent.CallEnded(durationMs: 0, isVideo: false, numParticipants: 1, placed: true) + analyticsClient.capture(someEvent) + + let capturedEvent = posthogMock.capturePropertiesUserPropertiesReceivedArguments + + // + XCTAssertEqual(capturedEvent?.properties?["cryptoSDKVersion"] as? String, "0.0") + + analyticsClient.updateSuperProperties(AnalyticsEvent.SuperProperties(appPlatform: .EI, cryptoSDK: .Rust, cryptoSDKVersion: "1.0")) + + + analyticsClient.capture(someEvent) + + let secondCapturedEvent = posthogMock.capturePropertiesUserPropertiesReceivedArguments + + XCTAssertEqual(secondCapturedEvent?.properties?["cryptoSDKVersion"] as? String, "1.0") + } + + func testSuperPropertiesDontOverrideEventProperties() { + let analyticsClient = PostHogAnalyticsClient(posthogFactory: MockPostHogFactory(mock: posthogMock)) + analyticsClient.start() + + // Super property for cryptoSDK is rust + let superProperties = AnalyticsEvent.SuperProperties(appPlatform: nil, cryptoSDK: .Rust, cryptoSDKVersion: nil) + + analyticsClient.updateSuperProperties(superProperties) + + // This event as a similar named property `cryptoSDK` with Legacy value + let someEvent = AnalyticsEvent.Error(context: nil, cryptoModule: nil, cryptoSDK: .Legacy, domain: .E2EE, eventLocalAgeMillis: nil, isFederated: nil, isMatrixDotOrg: nil, name: .OlmKeysNotSentError, timeToDecryptMillis: nil, userTrustsOwnIdentity: nil, wasVisibleToUser: nil) + + analyticsClient.capture(someEvent) + + let capturedEvent = posthogMock.capturePropertiesUserPropertiesReceivedArguments + + XCTAssertEqual(capturedEvent?.properties?["cryptoSDK"] as? String, AnalyticsEvent.Error.CryptoSDK.Legacy.rawValue) + } + +} diff --git a/project.yml b/project.yml index a666fb1b7..f72c75b5a 100644 --- a/project.yml +++ b/project.yml @@ -45,7 +45,7 @@ include: packages: AnalyticsEvents: url: https://github.com/matrix-org/matrix-analytics-events - exactVersion: 0.15.0 + exactVersion: 0.23.1 Mapbox: url: https://github.com/maplibre/maplibre-gl-native-distribution minVersion: 5.12.2 From 4f960fa4b7a3a9a249c9be85c31a3b7086bbf110 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 3 Jun 2024 10:58:28 +0200 Subject: [PATCH 06/39] Add changelog --- changelog.d/7801.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7801.misc diff --git a/changelog.d/7801.misc b/changelog.d/7801.misc new file mode 100644 index 000000000..5fbecd9d3 --- /dev/null +++ b/changelog.d/7801.misc @@ -0,0 +1 @@ +Analytics | Add support for super properties and appPlatform From adc486d616c2cb7c49870b3ad5573d08e2721642 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 3 Jun 2024 16:09:50 +0200 Subject: [PATCH 07/39] Review: doc fix typo Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> --- Riot/Modules/Analytics/AnalyticsClientProtocol.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Analytics/AnalyticsClientProtocol.swift b/Riot/Modules/Analytics/AnalyticsClientProtocol.swift index 1e0acc54e..cfc90fadb 100644 --- a/Riot/Modules/Analytics/AnalyticsClientProtocol.swift +++ b/Riot/Modules/Analytics/AnalyticsClientProtocol.swift @@ -55,7 +55,7 @@ protocol AnalyticsClientProtocol { func updateUserProperties(_ userProperties: AnalyticsEvent.UserProperties) - /// Updates the user properties. + /// Updates the super properties. /// Super properties added to all captured events and screen. /// - Parameter superProperties: The properties event to capture. func updateSuperProperties(_ event: AnalyticsEvent.SuperProperties) From 657e18caf3ccda49fc03b0ee893fbd3b4ac66e41 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 3 Jun 2024 16:10:09 +0200 Subject: [PATCH 08/39] Review: quick format Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> --- RiotTests/FakeUtils.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/RiotTests/FakeUtils.swift b/RiotTests/FakeUtils.swift index 2f2ad4e63..f4649e9d8 100644 --- a/RiotTests/FakeUtils.swift +++ b/RiotTests/FakeUtils.swift @@ -361,9 +361,7 @@ class MockPostHog: PostHogProtocol { enabled = false } - func reset() { - - } + func reset() { } func flush() { From 07d4c838d4b4c2931bf380507ebb1263121242dd Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 3 Jun 2024 16:10:40 +0200 Subject: [PATCH 09/39] Review: cleaning Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> --- Riot/Modules/Analytics/Analytics.swift | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index f284c2aa4..45a4611a5 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -94,13 +94,9 @@ import AnalyticsEvents guard let session = session else { return } useAnalyticsSettings(from: session) - self.client.updateSuperProperties( - AnalyticsEvent.SuperProperties( - appPlatform: .EI, - cryptoSDK: .Rust, - cryptoSDKVersion: session.crypto.version - ) - ) + client.updateSuperProperties(.init(appPlatform: .EI, + cryptoSDK: .Rust, + cryptoSDKVersion: session.crypto.version)) } /// Stops analytics tracking and calls `reset` to clear any IDs and event queues. From fb60f879420b5f6fb3e8902caf1e7057e052e1f4 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 3 Jun 2024 16:10:51 +0200 Subject: [PATCH 10/39] Review: quick format Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> --- Riot/Modules/Analytics/Analytics.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index 45a4611a5..3b19c9809 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -253,7 +253,8 @@ extension Analytics { ftueUseCaseSelection: ftueUseCase?.analyticsName, numFavouriteRooms: numFavouriteRooms, numSpaces: numSpaces, - recoveryState: nil, verificationState: nil) + recoveryState: nil, + verificationState: nil) client.updateUserProperties(userProperties) } From 72d7ca79d78576cf07d62e7203abe4fce01b0eff Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 10 Jun 2024 13:35:11 +0300 Subject: [PATCH 11/39] Remove NSFW advanced settings option --- Config/BuildSettings.swift | 1 - Riot/Managers/Settings/RiotSettings.swift | 9 +----- .../Recents/DataSources/RecentsDataSource.m | 1 - .../UnifiedSearchViewController.m | 2 -- .../PublicRoomsDirectoryDataSource.h | 5 ---- .../PublicRoomsDirectoryDataSource.m | 19 +------------ .../Modules/Settings/SettingsViewController.m | 28 ++----------------- 7 files changed, 4 insertions(+), 61 deletions(-) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index e3e3e55e8..48a4deed8 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -297,7 +297,6 @@ final class BuildSettings: NSObject { static let settingsScreenShowChangePassword:Bool = true static let settingsScreenShowEnableStunServerFallback: Bool = true static let settingsScreenShowNotificationDecodedContentOption: Bool = true - static let settingsScreenShowNsfwRoomsOption: Bool = true static let settingsSecurityScreenShowSessions:Bool = true static let settingsSecurityScreenShowSetupBackup:Bool = true static let settingsSecurityScreenShowRestoreBackup:Bool = true diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift index 06746801c..4710eba63 100644 --- a/Riot/Managers/Settings/RiotSettings.swift +++ b/Riot/Managers/Settings/RiotSettings.swift @@ -97,10 +97,6 @@ final class RiotSettings: NSObject { @UserDefault(key: UserDefaultsKeys.pinRoomsWithUnreadMessagesOnHome, defaultValue: false, storage: defaults) var pinRoomsWithUnreadMessagesOnHome - /// Indicate to show Not Safe For Work public rooms. - @UserDefault(key: "showNSFWPublicRooms", defaultValue: false, storage: defaults) - var showNSFWPublicRooms - // MARK: User interface @UserDefault(key: "userInterfaceTheme", defaultValue: nil, storage: defaults) @@ -329,10 +325,7 @@ final class RiotSettings: NSObject { @UserDefault(key: "settingsScreenShowNotificationDecodedContentOption", defaultValue: BuildSettings.settingsScreenShowNotificationDecodedContentOption, storage: defaults) var settingsScreenShowNotificationDecodedContentOption - - @UserDefault(key: "settingsScreenShowNsfwRoomsOption", defaultValue: BuildSettings.settingsScreenShowNsfwRoomsOption, storage: defaults) - var settingsScreenShowNsfwRoomsOption - + @UserDefault(key: "settingsSecurityScreenShowSessions", defaultValue: BuildSettings.settingsSecurityScreenShowSessions, storage: defaults) var settingsSecurityScreenShowSessions diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m index 85393a2d0..edf05bedc 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m @@ -471,7 +471,6 @@ - (MXKSessionRecentsDataSource *)addMatrixSession:(MXSession *)mxSession if (!_publicRoomsDirectoryDataSource) { _publicRoomsDirectoryDataSource = [[PublicRoomsDirectoryDataSource alloc] initWithMatrixSession:mxSession]; - _publicRoomsDirectoryDataSource.showNSFWRooms = RiotSettings.shared.showNSFWPublicRooms; _publicRoomsDirectoryDataSource.delegate = self; } diff --git a/Riot/Modules/GlobalSearch/UnifiedSearchViewController.m b/Riot/Modules/GlobalSearch/UnifiedSearchViewController.m index 8703623bb..94ae50f5a 100644 --- a/Riot/Modules/GlobalSearch/UnifiedSearchViewController.m +++ b/Riot/Modules/GlobalSearch/UnifiedSearchViewController.m @@ -141,8 +141,6 @@ - (void)viewWillAppear:(BOOL)animated // Reset searches [recentsDataSource searchWithPatterns:nil]; - // TODO: Notify RiotSettings.shared.showNSFWPublicRooms change for iPad as viewWillAppear may not be called - recentsDataSource.publicRoomsDirectoryDataSource.showNSFWRooms = RiotSettings.shared.showNSFWPublicRooms; [self updateSearch]; diff --git a/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.h b/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.h index 6fce1d92b..121722ed4 100644 --- a/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.h +++ b/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.h @@ -45,11 +45,6 @@ */ @property (nonatomic) BOOL includeAllNetworks; -/** - Flag to indicate to show Not Safe For Work rooms in the public room list. - */ -@property (nonatomic) BOOL showNSFWRooms; - /** List public rooms from a third party protocol. Default is nil. diff --git a/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.m b/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.m index cad856012..257f68d2e 100644 --- a/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.m +++ b/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.m @@ -155,16 +155,6 @@ - (void)setSearchPattern:(NSString *)searchPattern } } -- (void)setShowNSFWRooms:(BOOL)showNSFWRooms -{ - if (showNSFWRooms != _showNSFWRooms) - { - _showNSFWRooms = showNSFWRooms; - - [self resetPagination]; - } -} - - (NSUInteger)roomsCount { return rooms.count; @@ -254,14 +244,7 @@ - (MXHTTPOperation *)paginate:(void (^)(NSUInteger))complete failure:(void (^)(N NSArray *publicRooms; - if (self.showNSFWRooms) - { - publicRooms = publicRoomsResponse.chunk; - } - else - { - publicRooms = [self filterPublicRooms:publicRoomsResponse.chunk containingKeyword:kNSFWKeyword]; - } + publicRooms = [self filterPublicRooms:publicRoomsResponse.chunk containingKeyword:kNSFWKeyword]; [self->rooms addObjectsFromArray:publicRooms]; self->nextBatch = publicRoomsResponse.nextBatch; diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 39698f765..41372d2e0 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -152,8 +152,7 @@ typedef NS_ENUM(NSUInteger, PRESENCE) typedef NS_ENUM(NSUInteger, ADVANCED) { - ADVANCED_SHOW_NSFW_ROOMS_INDEX = 0, - ADVANCED_CRASH_REPORT_INDEX, + ADVANCED_CRASH_REPORT_INDEX = 0, ADVANCED_ENABLE_RAGESHAKE_INDEX, ADVANCED_MARK_ALL_AS_READ_INDEX, ADVANCED_CLEAR_CACHE_INDEX, @@ -567,11 +566,6 @@ - (void)updateSections Section *sectionAdvanced = [Section sectionWithTag:SECTION_TAG_ADVANCED]; sectionAdvanced.headerTitle = [VectorL10n settingsAdvanced]; - if (RiotSettings.shared.settingsScreenShowNsfwRoomsOption) - { - [sectionAdvanced addRowWithTag:ADVANCED_SHOW_NSFW_ROOMS_INDEX]; - } - if (BuildSettings.settingsScreenAllowChangingCrashUsageDataSettings) { [sectionAdvanced addRowWithTag:ADVANCED_CRASH_REPORT_INDEX]; @@ -2372,20 +2366,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } else if (section == SECTION_TAG_ADVANCED) { - if (row == ADVANCED_SHOW_NSFW_ROOMS_INDEX) - { - MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; - - labelAndSwitchCell.mxkLabel.text = [VectorL10n settingsShowNSFWPublicRooms]; - - labelAndSwitchCell.mxkSwitch.on = RiotSettings.shared.showNSFWPublicRooms; - labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor; - labelAndSwitchCell.mxkSwitch.enabled = YES; - [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleNSFWPublicRoomsFiltering:) forControlEvents:UIControlEventTouchUpInside]; - - cell = labelAndSwitchCell; - } - else if (row == ADVANCED_CRASH_REPORT_INDEX) + if (row == ADVANCED_CRASH_REPORT_INDEX) { MXKTableViewCellWithLabelAndSwitch* sendCrashReportCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; @@ -4082,11 +4063,6 @@ - (void)togglePresenceOfflineMode:(UISwitch *)sender } } -- (void)toggleNSFWPublicRoomsFiltering:(UISwitch *)sender -{ - RiotSettings.shared.showNSFWPublicRooms = sender.isOn; -} - - (void)toggleEnableRoomMessageBubbles:(UISwitch *)sender { RiotSettings.shared.roomScreenEnableMessageBubbles = sender.isOn; From ae271f202f0f235b36618e4761d44c34b49c18c4 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 10 Jun 2024 14:53:09 +0300 Subject: [PATCH 12/39] Adopt the EXA forbidden terms list when searching for public rooms --- .../PublicRoomsDirectoryDataSource.m | 29 ++++++-- Riot/SupportingFiles/forbidden_terms.txt | 68 +++++++++++++++++++ 2 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 Riot/SupportingFiles/forbidden_terms.txt diff --git a/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.m b/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.m index 257f68d2e..5ae737549 100644 --- a/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.m +++ b/Riot/Modules/PublicRoomList/DataSources/PublicRoomsDirectoryDataSource.m @@ -46,6 +46,8 @@ @interface PublicRoomsDirectoryDataSource () NSString *nextBatch; } +@property (nonatomic, strong) NSRegularExpression *forbiddenTermsRegex; + @end @implementation PublicRoomsDirectoryDataSource @@ -57,6 +59,15 @@ - (instancetype)init { rooms = [NSMutableArray array]; _paginationLimit = 20; + + NSString *path = [[NSBundle mainBundle] pathForResource:@"forbidden_terms" ofType:@"txt"]; + NSString *fileContents = [NSString stringWithContentsOfFile:path encoding: NSUTF8StringEncoding error:nil]; + NSArray *forbiddenTerms = [fileContents componentsSeparatedByCharactersInSet: NSCharacterSet.whitespaceAndNewlineCharacterSet]; + + NSString *pattern = [NSString stringWithFormat:@"\\b(%@)\\b", [forbiddenTerms componentsJoinedByString:@"|"]]; + pattern = [pattern stringByAppendingString:@"|(\\b18\\+)"]; // Special case "18+" + + _forbiddenTermsRegex = [[NSRegularExpression alloc] initWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil]; } return self; } @@ -244,7 +255,7 @@ - (MXHTTPOperation *)paginate:(void (^)(NSUInteger))complete failure:(void (^)(N NSArray *publicRooms; - publicRooms = [self filterPublicRooms:publicRoomsResponse.chunk containingKeyword:kNSFWKeyword]; + publicRooms = [self filterPublicRooms:publicRoomsResponse.chunk]; [self->rooms addObjectsFromArray:publicRooms]; self->nextBatch = publicRoomsResponse.nextBatch; @@ -321,15 +332,23 @@ - (void)setState:(MXKDataSourceState)newState } } -- (NSArray*)filterPublicRooms:(NSArray*)publicRooms containingKeyword:(NSString*)keyword +- (NSArray*)filterPublicRooms:(NSArray*)publicRooms { NSMutableArray *filteredRooms = [NSMutableArray new]; for (MXPublicRoom *publicRoom in publicRooms) { - if (NO == [[publicRoom.name lowercaseString] containsString:keyword] - && NO == [[publicRoom.topic lowercaseString] containsString:keyword]) - { + BOOL shouldAllow = YES; + + if (publicRoom.name != nil) { + shouldAllow &= [self.forbiddenTermsRegex numberOfMatchesInString:publicRoom.name options:0 range:NSMakeRange(0, publicRoom.name.length)] == 0; + } + + if (publicRoom.topic != nil) { + shouldAllow &= [self.forbiddenTermsRegex numberOfMatchesInString:publicRoom.topic options:0 range:NSMakeRange(0, publicRoom.topic.length)] == 0; + } + + if (shouldAllow) { [filteredRooms addObject:publicRoom]; } } diff --git a/Riot/SupportingFiles/forbidden_terms.txt b/Riot/SupportingFiles/forbidden_terms.txt new file mode 100644 index 000000000..ff22aa40f --- /dev/null +++ b/Riot/SupportingFiles/forbidden_terms.txt @@ -0,0 +1,68 @@ +anal +bbw +bdsm +beast +bestiality +blowjob +bondage +boobs +clit +cock +cuck +cum +cunt +daddy +dick +dildo +erotic +exhibitionism +faggot +femboy +fisting +flogging +fmf +foursome +futa +gangbang +gore +h3ntai +handjob +hentai +incest +jizz +kink +loli +m4f +masturbate +masturbation +mfm +milf +moresome +naked +neet +nsfw +nude +nudity +orgy +pedo +pegging +penis +petplay +porn +pussy +rape +rimming +sadism +sadomasochism +sexy +shota +spank +squirt +strap-on +threesome +vagina +vibrator +voyeur +watersports +xxx +zoo \ No newline at end of file From de993c20fd04cea24dd9fe59dd43a796d4d383c2 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 10 Jun 2024 15:18:16 +0300 Subject: [PATCH 13/39] Make the `matrix-ios-sdk` a submodule and use it as a local pod instead of a published one. --- .github/workflows/ci-build.yml | 6 +-- .github/workflows/ci-tests.yml | 6 +-- .github/workflows/ci-ui-tests.yml | 6 +-- .github/workflows/release-alpha.yml | 6 +-- .gitmodules | 3 ++ Gemfile.lock | 58 +++++++++++++++-------------- Podfile | 38 +------------------ Podfile.lock | 11 ++++-- fastlane/Fastfile | 40 -------------------- matrix-ios-sdk | 1 + 10 files changed, 55 insertions(+), 120 deletions(-) create mode 100644 .gitmodules create mode 160000 matrix-ios-sdk diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 6cac438d5..ccb11123a 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -20,7 +20,9 @@ jobs: # Concurrency group not needed as this workflow only runs on develop which we always want to test. steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + submodules: 'true' # Common cache # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job @@ -49,8 +51,6 @@ jobs: run: | bundle config path vendor/bundle bundle install --jobs 4 --retry 3 - - name: Use right MatrixSDK versions - run: bundle exec fastlane point_dependencies_to_related_branches # Main step - name: Build iOS simulator diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index f78a5aba9..e71d7b99b 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -25,7 +25,9 @@ jobs: cancel-in-progress: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + submodules: 'true' # Common cache # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job @@ -54,8 +56,6 @@ jobs: run: | bundle config path vendor/bundle bundle install --jobs 4 --retry 3 - - name: Use right MatrixSDK versions - run: bundle exec fastlane point_dependencies_to_related_branches # Main step - name: Unit tests diff --git a/.github/workflows/ci-ui-tests.yml b/.github/workflows/ci-ui-tests.yml index b13272947..322323739 100644 --- a/.github/workflows/ci-ui-tests.yml +++ b/.github/workflows/ci-ui-tests.yml @@ -20,7 +20,9 @@ jobs: cancel-in-progress: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + submodules: 'true' # Common cache # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job @@ -49,8 +51,6 @@ jobs: run: | bundle config path vendor/bundle bundle install --jobs 4 --retry 3 - - name: Use right MatrixSDK versions - run: bundle exec fastlane point_dependencies_to_related_branches # Main step - name: UI tests diff --git a/.github/workflows/release-alpha.yml b/.github/workflows/release-alpha.yml index e610628b4..aa90ef5ba 100644 --- a/.github/workflows/release-alpha.yml +++ b/.github/workflows/release-alpha.yml @@ -25,7 +25,9 @@ jobs: cancel-in-progress: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + submodules: 'true' # Common cache # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job @@ -57,8 +59,6 @@ jobs: run: | bundle config path vendor/bundle bundle install --jobs 4 --retry 3 - - name: Use right MatrixSDK versions - run: bundle exec fastlane point_dependencies_to_related_branches # Import alpha release private signing certificate - name: Import signing certificate diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..90f7f83cb --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "matrix-ios-sdk"] + path = matrix-ios-sdk + url = git@github.com:matrix-org/matrix-ios-sdk.git diff --git a/Gemfile.lock b/Gemfile.lock index 519e1f087..bacf716b3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GEM base64 nkf rexml - activesupport (7.1.3.2) + activesupport (7.1.3.4) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -29,24 +29,24 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.899.0) - aws-sdk-core (3.191.4) + aws-partitions (1.941.0) + aws-sdk-core (3.197.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.78.0) - aws-sdk-core (~> 3, >= 3.191.0) + aws-sdk-kms (1.83.0) + aws-sdk-core (~> 3, >= 3.197.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.146.0) - aws-sdk-core (~> 3, >= 3.191.0) + aws-sdk-s3 (1.152.0) + aws-sdk-core (~> 3, >= 3.197.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) base64 (0.2.0) - bigdecimal (3.1.7) + bigdecimal (3.1.8) claide (1.1.0) clamp (1.3.2) cocoapods (1.14.3) @@ -90,7 +90,7 @@ GEM colored2 (3.1.2) commander (4.6.0) highline (~> 2.0.0) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.3) connection_pool (2.4.1) declarative (0.0.20) digest-crc (0.6.5) @@ -131,15 +131,15 @@ GEM faraday-retry (1.0.3) faraday_middleware (1.2.0) faraday (~> 1.0) - fastimage (2.3.0) - fastlane (2.219.0) + fastimage (2.3.1) + fastlane (2.220.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) aws-sdk-s3 (~> 1.0) babosa (>= 1.0.3, < 2.0.0) bundler (>= 1.12.0, < 3.0.0) - colored + colored (~> 1.2) commander (~> 4.6) dotenv (>= 2.1.1, < 3.0.0) emoji_regex (>= 0.1, < 4.0) @@ -160,10 +160,10 @@ GEM mini_magick (>= 4.9.4, < 5.0.0) multipart-post (>= 2.0.0, < 3.0.0) naturally (~> 2.2) - optparse (>= 0.1.1) + optparse (>= 0.1.1, < 1.0.0) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) - security (= 0.1.3) + security (= 0.1.5) simctl (~> 1.6.3) terminal-notifier (>= 2.0.0, < 3.0.0) terminal-table (~> 3) @@ -172,14 +172,14 @@ GEM word_wrap (~> 1.0.0) xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) - xcpretty-travis-formatter (>= 0.0.3) + xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) fastlane-plugin-brew (0.1.1) - fastlane-plugin-sentry (1.20.0) + fastlane-plugin-sentry (1.23.0) os (~> 1.1, >= 1.1.4) fastlane-plugin-versioning (0.5.2) fastlane-plugin-xcodegen (1.1.0) fastlane-plugin-brew (~> 0.1.1) - ffi (1.16.3) + ffi (1.17.0) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) @@ -220,22 +220,22 @@ GEM os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.5) + http-cookie (1.0.6) domain_name (~> 0.5) httpclient (2.8.3) - i18n (1.14.4) + i18n (1.14.5) concurrent-ruby (~> 1.0) jmespath (1.6.2) - json (2.7.1) + json (2.7.2) jwt (2.8.1) base64 mini_magick (4.12.0) mini_mime (1.1.5) - mini_portile2 (2.8.5) - minitest (5.22.3) + mini_portile2 (2.8.7) + minitest (5.23.1) molinillo (0.8.0) multi_json (1.15.0) - multipart-post (2.4.0) + multipart-post (2.4.1) mutex_m (0.2.0) nanaimo (0.3.0) nap (1.1.0) @@ -245,23 +245,24 @@ GEM nokogiri (1.15.6) mini_portile2 (~> 2.8.2) racc (~> 1.4) - optparse (0.4.0) + optparse (0.5.0) os (1.1.4) plist (3.7.1) public_suffix (4.0.7) - racc (1.7.3) - rake (13.1.0) + racc (1.8.0) + rake (13.2.1) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) retriable (3.1.2) - rexml (3.2.6) + rexml (3.2.9) + strscan rouge (2.0.7) ruby-macho (2.5.1) ruby2_keywords (0.0.5) rubyzip (2.3.2) - security (0.1.3) + security (0.1.5) signet (0.19.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) @@ -276,6 +277,7 @@ GEM clamp (~> 1.3) nokogiri (>= 1.14.3) xcodeproj (~> 1.21) + strscan (3.1.0) terminal-notifier (2.0.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) diff --git a/Podfile b/Podfile index 3fb43f417..f6f26f61c 100644 --- a/Podfile +++ b/Podfile @@ -9,44 +9,10 @@ inhibit_all_warnings! # Use frameworks to allow usage of pods written in Swift use_frameworks! -# Different flavours of pods to MatrixSDK. Can be one of: -# - a String indicating an official MatrixSDK released version number -# - `:local` (to use Development Pods) -# - `{ :branch => 'sdk branch name'}` to depend on specific branch of MatrixSDK repo -# - `{ :specHash => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for MatrixSDK repo. Used by Fastfile during CI -# -# Warning: our internal tooling depends on the name of this variable name, so be sure not to change it -$matrixSDKVersion = '= 0.27.8' -# $matrixSDKVersion = :local -# $matrixSDKVersion = { :branch => 'develop'} -# $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } } - -######################################## - -case $matrixSDKVersion -when :local -$matrixSDKVersionSpec = { :path => '../matrix-ios-sdk/MatrixSDK.podspec' } -when Hash -spec_mode, sdk_spec = $matrixSDKVersion.first # extract first and only key/value pair; key is spec_mode, value is sdk_spec - - case spec_mode - when :branch - # :branch => sdk branch name - sdk_spec = { :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => sdk_spec.to_s } unless sdk_spec.is_a?(Hash) - when :specHash - # :specHash => {sdk spec Hash} - sdk_spec = sdk_spec - end - -$matrixSDKVersionSpec = sdk_spec -when String # specific MatrixSDK released version -$matrixSDKVersionSpec = $matrixSDKVersion -end - # Method to import the MatrixSDK def import_MatrixSDK - pod 'MatrixSDK', $matrixSDKVersionSpec, :inhibit_warnings => false - pod 'MatrixSDK/JingleCallStack', $matrixSDKVersionSpec, :inhibit_warnings => false + pod 'MatrixSDK', :path => 'matrix-ios-sdk/MatrixSDK.podspec', :inhibit_warnings => false + pod 'MatrixSDK/JingleCallStack', :path => 'matrix-ios-sdk/MatrixSDK.podspec', :inhibit_warnings => false end ######################################## diff --git a/Podfile.lock b/Podfile.lock index b830adadb..673d4ecc0 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -101,8 +101,8 @@ DEPENDENCIES: - KeychainAccess (~> 4.2.2) - KTCenterFlowLayout (~> 1.3.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.27.8) - - MatrixSDK/JingleCallStack (= 0.27.8) + - MatrixSDK (from `matrix-ios-sdk/MatrixSDK.podspec`) + - MatrixSDK/JingleCallStack (from `matrix-ios-sdk/MatrixSDK.podspec`) - OLMKit - ReadMoreTextView (~> 3.0.1) - Reusable (~> 4.1) @@ -142,7 +142,6 @@ SPEC REPOS: - libPhoneNumber-iOS - LoggerAPI - Logging - - MatrixSDK - MatrixSDKCrypto - OLMKit - ReadMoreTextView @@ -162,6 +161,10 @@ SPEC REPOS: - zxcvbn-ios - ZXingObjC +EXTERNAL SOURCES: + MatrixSDK: + :path: matrix-ios-sdk/MatrixSDK.podspec + SPEC CHECKSUMS: AFNetworking: 3bd23d814e976cd148d7d44c3ab78017b744cd58 BlueCryptor: b0aee3d9b8f367b49b30de11cda90e1735571c24 @@ -204,6 +207,6 @@ SPEC CHECKSUMS: zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -PODFILE CHECKSUM: 3bbda8faf037705f421dad839d6f5b1aef399f99 +PODFILE CHECKSUM: b622ffadc1a0fe5442787bd9023ca3d110384814 COCOAPODS: 1.15.2 diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 51e23fe9d..a2a2dc1c6 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -103,27 +103,6 @@ platform :ios do end - desc "Point MatrixSDK to the related branches if such ones exist" - lane :point_dependencies_to_related_branches do - current_branch = mx_git_branch - UI.message("Current branch: #{current_branch}") - if current_branch.start_with?("release/") - point_dependencies_to_pending_releases - else - point_dependencies_to_same_feature - end - end - - desc "Point MatrixSDK to release/*/release branch if it exists, master otherwise" - lane :point_dependencies_to_pending_releases do - edit_podfile(branch_pattern: "release/*/release", default_branch: "master") - end - - desc "Point MatrixSDK to the branch with the same name as the current branch if such one exist, develop otherwise" - lane :point_dependencies_to_same_feature do - edit_podfile(branch_pattern: mx_git_branch) unless mx_git_branch.to_s.empty? - end - desc "Use an app variant. An app variant overwrite default project configuration or ressource files with custom values" lane :setup_app_variant do |options| appVariantScript = "../Variants/setup_app_variant.sh" @@ -473,25 +452,6 @@ platform :ios do preprocessor_definitions end - desc "Edit the Podfile in order to point MatrixSDK to the appropriate branches." - private_lane :edit_podfile do |options| - require 'net/http' - - branch_pattern = options[:branch_pattern] - sdk_slug = "matrix-org/matrix-ios-sdk" - - default_branch = options[:default_branch] || 'develop' - sdk_branch = find_branch(sdk_slug, branch_pattern) || default_branch - - sdk_spec = { git: 'https://github.com/matrix-org/matrix-ios-sdk.git', branch: sdk_branch } - - UI.message "✏️ Modify Podfile to point `MatrixSDK/*` to \`#{sdk_branch}\` branch..." - podfile_content = File.read('../Podfile') # current dir is 'fastlane/' hence the '../' - podfile_content.gsub!(%r{^\$matrixSDKVersion\s*=\s*.*$}, "$matrixSDKVersion = { :specHash => #{sdk_spec} }") - File.write('../Podfile', podfile_content) - UI.command_output("Content of modified Podfile:\n" + podfile_content) - end - desc "Upload dsym files to Sentry to symbolicate crashes" private_lane :upload_dsyms_to_sentry do UI.user_error!("'SENTRY_AUTH_TOKEN' environment variable should be set to use this lane") unless !ENV["SENTRY_AUTH_TOKEN"].to_s.empty? diff --git a/matrix-ios-sdk b/matrix-ios-sdk new file mode 160000 index 000000000..f03778fdd --- /dev/null +++ b/matrix-ios-sdk @@ -0,0 +1 @@ +Subproject commit f03778fddbaf682173706649ee1412b0143f0449 From 94f187f5c21babd3a74e69db26da6f099b3611d6 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 12 Jun 2024 12:43:25 +0300 Subject: [PATCH 14/39] Add support for reporting rooms on the room preview screen --- Riot/Modules/Room/RoomViewController.m | 48 ++++++++++++++ .../Title/Preview/PreviewRoomTitleView.h | 1 + .../Title/Preview/PreviewRoomTitleView.m | 12 ++++ .../Title/Preview/PreviewRoomTitleView.xib | 64 +++++++++++-------- matrix-ios-sdk | 2 +- 5 files changed, 101 insertions(+), 26 deletions(-) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 37cc5a766..b511bade2 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -5372,6 +5372,50 @@ - (IBAction)onButtonPressed:(id)sender } } +- (void)handleReportRoomButtonPress +{ + // Prompt user to enter a description of the problem content. + UIAlertController *reportReasonAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptReason] + message:nil + preferredStyle:UIAlertControllerStyleAlert]; + + [reportReasonAlert addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.secureTextEntry = NO; + textField.placeholder = nil; + textField.keyboardType = UIKeyboardTypeDefault; + }]; + + MXWeakify(self); + [reportReasonAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n ok] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + MXStrongifyAndReturnIfNil(self); + + NSString *text = [self->currentAlert textFields].firstObject.text; + self->currentAlert = nil; + + [self startActivityIndicator]; + + [self.roomDataSource.mxSession.matrixRestClient reportRoom:self.roomDataSource.roomId reason:text success:^{ + MXStrongifyAndReturnIfNil(self); + [self stopActivityIndicator]; + } failure:^(NSError *error) { + MXStrongifyAndReturnIfNil(self); + [self stopActivityIndicator]; + + MXLogDebug(@"[RoomVC] Report room (%@) failed", self.roomDataSource.roomId); + //Alert user + [self showError:error]; + }]; + }]]; + + [reportReasonAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel] style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { + MXStrongifyAndReturnIfNil(self); + self->currentAlert = nil; + }]]; + + [self presentViewController:reportReasonAlert animated:YES completion:nil]; + self->currentAlert = reportReasonAlert; +} + #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath @@ -5617,6 +5661,10 @@ - (void)roomTitleView:(RoomTitleView*)titleView recognizeTapGesture:(UITapGestur { [self presentDeclineOptionsFromView:tappedView]; } + else if (tappedView == previewHeader.reportButton) + { + [self handleReportRoomButtonPress]; + } } - (void)presentDeclineOptionsFromView:(UIView *)view diff --git a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.h b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.h index 79fdde1bb..d8bcfb086 100644 --- a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.h +++ b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.h @@ -32,6 +32,7 @@ @property (weak, nonatomic) IBOutlet UIView *buttonsContainer; @property (weak, nonatomic) IBOutlet UIButton *leftButton; @property (weak, nonatomic) IBOutlet UIButton *rightButton; +@property (weak, nonatomic) IBOutlet UIButton *reportButton; @property (weak, nonatomic) IBOutlet UILabel *subNoticeLabel; @property (weak, nonatomic) IBOutlet UIView *bottomBorderView; diff --git a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m index 7e8456a5b..48b7d1abf 100644 --- a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m +++ b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m @@ -51,12 +51,22 @@ - (void)awakeFromNib [self.rightButton setTitle:[VectorL10n join] forState:UIControlStateNormal]; [self.rightButton setTitle:[VectorL10n join] forState:UIControlStateHighlighted]; + [self.reportButton setTitle:[VectorL10n roomEventActionReport] forState:UIControlStateNormal]; + [self.reportButton setTitle:[VectorL10n roomEventActionReport] forState:UIControlStateHighlighted]; + tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reportTapGesture:)]; [tap setNumberOfTouchesRequired:1]; [tap setNumberOfTapsRequired:1]; [tap setDelegate:self]; [self.rightButton addGestureRecognizer:tap]; self.rightButton.userInteractionEnabled = YES; + + tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reportTapGesture:)]; + [tap setNumberOfTouchesRequired:1]; + [tap setNumberOfTapsRequired:1]; + [tap setDelegate:self]; + [self.reportButton addGestureRecognizer:tap]; + self.reportButton.userInteractionEnabled = YES; } -(void)customizeViewRendering @@ -86,6 +96,8 @@ -(void)customizeViewRendering [self.rightButton.layer setCornerRadius:5]; self.rightButton.clipsToBounds = YES; self.rightButton.backgroundColor = ThemeService.shared.theme.tintColor; + + [self.reportButton setTitleColor:ThemeService.shared.theme.warningColor forState:UIControlStateNormal]; } - (void)refreshDisplay diff --git a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.xib b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.xib index 31fcca273..873ff88e2 100644 --- a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.xib +++ b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.xib @@ -1,25 +1,21 @@ - - - - + + - - - + - + - + @@ -38,7 +34,7 @@ - + @@ -48,9 +44,9 @@ - + - + @@ -58,11 +54,11 @@ - + - - - + @@ -154,15 +158,17 @@ - + + + @@ -187,6 +193,7 @@ + @@ -194,9 +201,16 @@ + - + + + + + + + diff --git a/matrix-ios-sdk b/matrix-ios-sdk index f03778fdd..eea06ab5f 160000 --- a/matrix-ios-sdk +++ b/matrix-ios-sdk @@ -1 +1 @@ -Subproject commit f03778fddbaf682173706649ee1412b0143f0449 +Subproject commit eea06ab5f2b68223f557abaf04674df7f952ede8 From 249478eb9f5239d7844073ce1b862e62737a7554 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 12 Jun 2024 17:43:35 +0300 Subject: [PATCH 15/39] Add support for reporting rooms on the room details screen too --- Riot/Assets/en.lproj/Vector.strings | 2 ++ Riot/Generated/Strings.swift | 8 ++++++++ Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift | 3 +++ .../RoomInfo/RoomInfoCoordinatorBridgePresenter.swift | 6 ++++++ .../Room/RoomInfo/RoomInfoCoordinatorType.swift | 1 + .../RoomInfoList/RoomInfoListCoordinator.swift | 3 +++ .../RoomInfoList/RoomInfoListCoordinatorType.swift | 1 + .../RoomInfoList/RoomInfoListViewAction.swift | 1 + .../RoomInfoList/RoomInfoListViewController.swift | 8 ++++++++ .../RoomInfo/RoomInfoList/RoomInfoListViewModel.swift | 2 ++ .../RoomInfoList/RoomInfoListViewModelType.swift | 1 + Riot/Modules/Room/RoomViewController.m | 11 ++++++++--- .../Room/Views/Title/Preview/PreviewRoomTitleView.m | 4 ++-- .../Spaces/SpaceRoomList/ExploreRoomCoordinator.swift | 4 ++++ matrix-ios-sdk | 2 +- 15 files changed, 51 insertions(+), 6 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 924bda31c..00fc9a6d1 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -592,6 +592,8 @@ Tap the + to start adding people."; "room_action_send_sticker" = "Send sticker"; "room_action_send_file" = "Send file"; "room_action_reply" = "Reply"; +"room_action_report" = "Report room"; +"room_action_report_prompt_reason" = "Reason for reporting this room"; "room_replacement_information" = "This room has been replaced and is no longer active."; "room_replacement_link" = "The conversation continues here."; "room_predecessor_information" = "This room is a continuation of another conversation."; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index 999f821c3..7826653b2 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -5207,6 +5207,14 @@ public class VectorL10n: NSObject { public static var roomActionReply: String { return VectorL10n.tr("Vector", "room_action_reply") } + /// Report room + public static var roomActionReport: String { + return VectorL10n.tr("Vector", "room_action_report") + } + /// Reason for reporting this room + public static var roomActionReportPromptReason: String { + return VectorL10n.tr("Vector", "room_action_report_prompt_reason") + } /// Send file public static var roomActionSendFile: String { return VectorL10n.tr("Vector", "room_action_send_file") diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift index badc66490..ea2853c62 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift @@ -224,6 +224,9 @@ extension RoomInfoCoordinator: RoomInfoListCoordinatorDelegate { self.delegate?.roomInfoCoordinatorDidLeaveRoom(self) } + func roomInfoListCoordinatorDidRequestReportRoom(_ coordinator: RoomInfoListCoordinatorType) { + self.delegate?.roomInfoCoordinatorDidRequestReportRoom(self) + } } extension RoomInfoCoordinator: RoomParticipantsViewControllerDelegate { diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift index 39e740bfc..4484bd0d6 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift @@ -25,6 +25,7 @@ import MatrixSDK func roomInfoCoordinatorBridgePresenterDelegateDidLeaveRoom(_ coordinatorBridgePresenter: RoomInfoCoordinatorBridgePresenter) func roomInfoCoordinatorBridgePresenter(_ coordinatorBridgePresenter: RoomInfoCoordinatorBridgePresenter, didReplaceRoomWithReplacementId roomId: String) func roomInfoCoordinatorBridgePresenter(_ coordinator: RoomInfoCoordinatorBridgePresenter, viewEventInTimeline event: MXEvent) + func roomInfoCoordinatorBridgePresenterDidRequestReportRoom(_ coordinatorBridgePresenter: RoomInfoCoordinatorBridgePresenter) } /// RoomInfoCoordinatorBridgePresenter enables to start RoomInfoCoordinator from a view controller. @@ -131,9 +132,14 @@ extension RoomInfoCoordinatorBridgePresenter: RoomInfoCoordinatorDelegate { func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, didReplaceRoomWithReplacementId roomId: String) { self.delegate?.roomInfoCoordinatorBridgePresenter(self, didReplaceRoomWithReplacementId: roomId) } + func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, viewEventInTimeline event: MXEvent) { self.delegate?.roomInfoCoordinatorBridgePresenter(self, viewEventInTimeline: event) } + + func roomInfoCoordinatorDidRequestReportRoom(_ coordinator: RoomInfoCoordinatorType) { + self.delegate?.roomInfoCoordinatorBridgePresenterDidRequestReportRoom(self) + } } // MARK: - UIAdaptivePresentationControllerDelegate diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorType.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorType.swift index 2122ddf1d..077ef7b52 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorType.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorType.swift @@ -25,6 +25,7 @@ protocol RoomInfoCoordinatorDelegate: AnyObject { func roomInfoCoordinatorDidLeaveRoom(_ coordinator: RoomInfoCoordinatorType) func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, didReplaceRoomWithReplacementId roomId: String) func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, viewEventInTimeline event: MXEvent) + func roomInfoCoordinatorDidRequestReportRoom(_ coordinator: RoomInfoCoordinatorType) } /// `RoomInfoCoordinatorType` is a protocol describing a Coordinator that handle keybackup setup navigation flow. diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinator.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinator.swift index 6da79ca32..25131222b 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinator.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinator.swift @@ -75,4 +75,7 @@ extension RoomInfoListCoordinator: RoomInfoListViewModelCoordinatorDelegate { self.delegate?.roomInfoListCoordinatorDidLeaveRoom(self) } + func roomInfoListViewModelDidRequestReportRoom(_ viewModel: RoomInfoListViewModelType) { + self.delegate?.roomInfoListCoordinatorDidRequestReportRoom(self) + } } diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinatorType.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinatorType.swift index 592acd67b..f17102c1e 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinatorType.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinatorType.swift @@ -22,6 +22,7 @@ protocol RoomInfoListCoordinatorDelegate: AnyObject { func roomInfoListCoordinator(_ coordinator: RoomInfoListCoordinatorType, wantsToNavigateTo target: RoomInfoListTarget) func roomInfoListCoordinatorDidCancel(_ coordinator: RoomInfoListCoordinatorType) func roomInfoListCoordinatorDidLeaveRoom(_ coordinator: RoomInfoListCoordinatorType) + func roomInfoListCoordinatorDidRequestReportRoom(_ coordinator: RoomInfoListCoordinatorType) } /// `RoomInfoListCoordinatorType` is a protocol describing a Coordinator that handle key backup setup passphrase navigation flow. diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift index 6383d4fb5..e01bfeefc 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift @@ -48,4 +48,5 @@ enum RoomInfoListViewAction { case navigate(target: RoomInfoListTarget) case leave case cancel + case report } diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift index a879eeed0..383beac30 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift @@ -222,8 +222,16 @@ final class RoomInfoListViewController: UIViewController { rows: [rowLeave], footer: nil) + let rowReport = Row(type: .destructive, icon: Asset.Images.error.image, text: VectorL10n.roomEventActionReport, accessoryType: .disclosureIndicator) { + self.viewModel.process(viewAction: .report) + } + let sectionReport = Section(header: nil, + rows: [rowReport], + footer: nil) + tmpSections.append(sectionSettings) tmpSections.append(sectionLeave) + tmpSections.append(sectionReport) sections = tmpSections } diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift index 572754251..bf2c82e9b 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift @@ -79,6 +79,8 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType { self.leave() case .cancel: self.coordinatorDelegate?.roomInfoListViewModelDidCancel(self) + case .report: + self.coordinatorDelegate?.roomInfoListViewModelDidRequestReportRoom(self) } } diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift index 8a5a1b411..460c33d51 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift @@ -26,6 +26,7 @@ protocol RoomInfoListViewModelCoordinatorDelegate: AnyObject { func roomInfoListViewModelDidCancel(_ viewModel: RoomInfoListViewModelType) func roomInfoListViewModelDidLeaveRoom(_ viewModel: RoomInfoListViewModelType) func roomInfoListViewModel(_ viewModel: RoomInfoListViewModelType, wantsToNavigateTo target: RoomInfoListTarget) + func roomInfoListViewModelDidRequestReportRoom(_ viewModel: RoomInfoListViewModelType) } /// Protocol describing the view model used by `RoomInfoListViewController` diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index b511bade2..2eec3ea3d 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -5372,10 +5372,10 @@ - (IBAction)onButtonPressed:(id)sender } } -- (void)handleReportRoomButtonPress +- (void)handleReportRoom { // Prompt user to enter a description of the problem content. - UIAlertController *reportReasonAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomEventActionReportPromptReason] + UIAlertController *reportReasonAlert = [UIAlertController alertControllerWithTitle:[VectorL10n roomActionReportPromptReason] message:nil preferredStyle:UIAlertControllerStyleAlert]; @@ -5663,7 +5663,7 @@ - (void)roomTitleView:(RoomTitleView*)titleView recognizeTapGesture:(UITapGestur } else if (tappedView == previewHeader.reportButton) { - [self handleReportRoomButtonPress]; + [self handleReportRoom]; } } @@ -8032,6 +8032,11 @@ - (void)roomInfoCoordinatorBridgePresenter:(RoomInfoCoordinatorBridgePresenter * [self reloadRoomWihtEventId:event.eventId threadId:event.threadId forceUpdateRoomMarker:NO]; } +- (void)roomInfoCoordinatorBridgePresenterDidRequestReportRoom:(RoomInfoCoordinatorBridgePresenter *)coordinatorBridgePresenter +{ + [self handleReportRoom]; +} + -(void)reloadRoomWihtEventId:(NSString *)eventId threadId:(NSString *)threadId forceUpdateRoomMarker:(BOOL)forceUpdateRoomMarker diff --git a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m index 48b7d1abf..35fdbab12 100644 --- a/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m +++ b/Riot/Modules/Room/Views/Title/Preview/PreviewRoomTitleView.m @@ -51,8 +51,8 @@ - (void)awakeFromNib [self.rightButton setTitle:[VectorL10n join] forState:UIControlStateNormal]; [self.rightButton setTitle:[VectorL10n join] forState:UIControlStateHighlighted]; - [self.reportButton setTitle:[VectorL10n roomEventActionReport] forState:UIControlStateNormal]; - [self.reportButton setTitle:[VectorL10n roomEventActionReport] forState:UIControlStateHighlighted]; + [self.reportButton setTitle:[VectorL10n roomActionReport] forState:UIControlStateNormal]; + [self.reportButton setTitle:[VectorL10n roomActionReport] forState:UIControlStateHighlighted]; tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reportTapGesture:)]; [tap setNumberOfTouchesRequired:1]; diff --git a/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift b/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift index d445f29af..86e1cd5ee 100644 --- a/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift +++ b/Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift @@ -520,8 +520,12 @@ extension ExploreRoomCoordinator: RoomInfoCoordinatorDelegate { self.remove(childCoordinator: coordinator) } } + func roomInfoCoordinator(_ coordinator: RoomInfoCoordinatorType, viewEventInTimeline event: MXEvent) { } + func roomInfoCoordinatorDidRequestReportRoom(_ coordinator: RoomInfoCoordinatorType) { + + } } diff --git a/matrix-ios-sdk b/matrix-ios-sdk index eea06ab5f..3052a396b 160000 --- a/matrix-ios-sdk +++ b/matrix-ios-sdk @@ -1 +1 @@ -Subproject commit eea06ab5f2b68223f557abaf04674df7f952ede8 +Subproject commit 3052a396b88095cbcfe1b4f488127f69e3280cda From 4fc1d4c17a18783b6ae7977a8ed748ad3ddee2f4 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 12 Jun 2024 18:36:35 +0300 Subject: [PATCH 16/39] version++ --- CHANGES.md | 7 +++++++ changelog.d/7801.misc | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) delete mode 100644 changelog.d/7801.misc diff --git a/CHANGES.md b/CHANGES.md index bf6fc003b..27abf6350 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +## Changes in 1.11.13 (2024-06-12) + +Others + +- Analytics | Add support for super properties and appPlatform ([#7801](https://github.com/element-hq/element-ios/issues/7801)) + + ## Changes in 1.11.12 (2024-05-30) 🐛 Bugfixes diff --git a/changelog.d/7801.misc b/changelog.d/7801.misc deleted file mode 100644 index 5fbecd9d3..000000000 --- a/changelog.d/7801.misc +++ /dev/null @@ -1 +0,0 @@ -Analytics | Add support for super properties and appPlatform From 0fbb7456c7065c0c9e4984dd12a873dafb73109a Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 13 Jun 2024 08:33:18 +0300 Subject: [PATCH 17/39] finish version++ From f3e09fa89c116e0896f12a770f4cebb012c78ba5 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 13 Jun 2024 08:33:26 +0300 Subject: [PATCH 18/39] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index 281e714ad..e53ee7842 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.11.13 -CURRENT_PROJECT_VERSION = 1.11.13 +MARKETING_VERSION = 1.11.14 +CURRENT_PROJECT_VERSION = 1.11.14 From 9e24affa301363eaeddb94c981220dac60f55aaf Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 13 Jun 2024 09:25:07 +0300 Subject: [PATCH 19/39] Fix the release script after making the SDK a submodule --- Tools/Release/buildRelease.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Tools/Release/buildRelease.sh b/Tools/Release/buildRelease.sh index 583b00b62..0f925efc1 100755 --- a/Tools/Release/buildRelease.sh +++ b/Tools/Release/buildRelease.sh @@ -42,7 +42,7 @@ cp -R ../../../.. /tmp/$REPO_NAME mv /tmp/$REPO_NAME . else echo "Git clone $REPO_URL with branch/tag $TAG..." -git clone $REPO_URL --depth=1 --branch $TAG +git clone --recursive $REPO_URL --depth=1 --branch $TAG fi cd $REPO_NAME @@ -55,11 +55,6 @@ bundle update # Update fastlane plugins bundle exec fastlane update_plugins -# Use appropriated dependencies according to the current branch -if [ "$LOCAL_SOURCE" != true ]; then -bundle exec fastlane point_dependencies_to_same_feature -fi - # Build bundle exec fastlane app_store build_number:$BUILD_NUMBER git_tag:$TAG From 80147d43453c2422949bede3888cffe397a83f69 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 14 Jun 2024 15:18:57 +0200 Subject: [PATCH 20/39] added functions to remove messages --- Riot/Categories/MXRoomSummary.swift | 57 +++++++++++++++++++++++++++++ Riot/Categories/MXSession.swift | 15 ++++++++ Riot/Utils/Tools.h | 13 +++++++ Riot/Utils/Tools.m | 12 ++++++ 4 files changed, 97 insertions(+) create mode 100644 Riot/Categories/MXRoomSummary.swift diff --git a/Riot/Categories/MXRoomSummary.swift b/Riot/Categories/MXRoomSummary.swift new file mode 100644 index 000000000..691f534d0 --- /dev/null +++ b/Riot/Categories/MXRoomSummary.swift @@ -0,0 +1,57 @@ +// +// 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) +} + +@objc extension MXRoomSummary { + static let roomSummaryDidRemoveExpiredDataFromStore = "roomSummaryDidRemoveExpiredDataFromStore" + + 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 + func mininumTimestamp() -> 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. + func removeExpiredRoomContentsFromStore() -> Bool { + let ret = self.mxSession.store.removeAllMessagesSent(before: self.mininumTimestamp(), inRoom: roomId) + if ret { + NotificationCenter.default.post(name: .roomSummaryDidRemoveExpiredDataFromStore, object: self) + } + return ret + } +} diff --git a/Riot/Categories/MXSession.swift b/Riot/Categories/MXSession.swift index 10df98141..5300c1ec3 100644 --- a/Riot/Categories/MXSession.swift +++ b/Riot/Categories/MXSession.swift @@ -26,3 +26,18 @@ extension MXSession { displayName: user?.displayname) } } + +@objc extension MXSession { + + /// Clean the storage of a session by removing the expired contents. + func removeExpiredMessages() { + var hasStoreChanged = false + for room in self.rooms { + hasStoreChanged = hasStoreChanged || room.summary.removeExpiredRoomContentsFromStore() + } + + if hasStoreChanged { + self.store.commit?() + } + } +} diff --git a/Riot/Utils/Tools.h b/Riot/Utils/Tools.h index 57eacbcdb..8d54e06b1 100644 --- a/Riot/Utils/Tools.h +++ b/Riot/Utils/Tools.h @@ -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 diff --git a/Riot/Utils/Tools.m b/Riot/Utils/Tools.m index 128fe3694..5866273ac 100644 --- a/Riot/Utils/Tools.m +++ b/Riot/Utils/Tools.m @@ -117,4 +117,16 @@ + (NSURL *)fixURLWithSeveralHashKeys:(NSURL *)url 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 From 55ec6f1544f102f89bd47f60d72cacc1749b04d2 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 14 Jun 2024 15:27:08 +0200 Subject: [PATCH 21/39] Revert "added functions to remove messages" This reverts commit 80147d43453c2422949bede3888cffe397a83f69. --- Riot/Categories/MXRoomSummary.swift | 57 ----------------------------- Riot/Categories/MXSession.swift | 15 -------- Riot/Utils/Tools.h | 13 ------- Riot/Utils/Tools.m | 12 ------ 4 files changed, 97 deletions(-) delete mode 100644 Riot/Categories/MXRoomSummary.swift diff --git a/Riot/Categories/MXRoomSummary.swift b/Riot/Categories/MXRoomSummary.swift deleted file mode 100644 index 691f534d0..000000000 --- a/Riot/Categories/MXRoomSummary.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// 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) -} - -@objc extension MXRoomSummary { - static let roomSummaryDidRemoveExpiredDataFromStore = "roomSummaryDidRemoveExpiredDataFromStore" - - 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 - func mininumTimestamp() -> 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. - func removeExpiredRoomContentsFromStore() -> Bool { - let ret = self.mxSession.store.removeAllMessagesSent(before: self.mininumTimestamp(), inRoom: roomId) - if ret { - NotificationCenter.default.post(name: .roomSummaryDidRemoveExpiredDataFromStore, object: self) - } - return ret - } -} diff --git a/Riot/Categories/MXSession.swift b/Riot/Categories/MXSession.swift index 5300c1ec3..10df98141 100644 --- a/Riot/Categories/MXSession.swift +++ b/Riot/Categories/MXSession.swift @@ -26,18 +26,3 @@ extension MXSession { displayName: user?.displayname) } } - -@objc extension MXSession { - - /// Clean the storage of a session by removing the expired contents. - func removeExpiredMessages() { - var hasStoreChanged = false - for room in self.rooms { - hasStoreChanged = hasStoreChanged || room.summary.removeExpiredRoomContentsFromStore() - } - - if hasStoreChanged { - self.store.commit?() - } - } -} diff --git a/Riot/Utils/Tools.h b/Riot/Utils/Tools.h index 8d54e06b1..57eacbcdb 100644 --- a/Riot/Utils/Tools.h +++ b/Riot/Utils/Tools.h @@ -48,17 +48,4 @@ */ + (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 diff --git a/Riot/Utils/Tools.m b/Riot/Utils/Tools.m index 5866273ac..128fe3694 100644 --- a/Riot/Utils/Tools.m +++ b/Riot/Utils/Tools.m @@ -117,16 +117,4 @@ + (NSURL *)fixURLWithSeveralHashKeys:(NSURL *)url 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 From 25c77b6bbe1c366376f0f2a919abf84b3ada39ee Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 14 Jun 2024 15:18:57 +0200 Subject: [PATCH 22/39] added functions to remove messages --- Riot/Categories/MXRoomSummary.swift | 57 +++++++++++++++++++++++++++++ Riot/Categories/MXSession.swift | 15 ++++++++ Riot/Utils/Tools.h | 13 +++++++ Riot/Utils/Tools.m | 12 ++++++ 4 files changed, 97 insertions(+) create mode 100644 Riot/Categories/MXRoomSummary.swift diff --git a/Riot/Categories/MXRoomSummary.swift b/Riot/Categories/MXRoomSummary.swift new file mode 100644 index 000000000..691f534d0 --- /dev/null +++ b/Riot/Categories/MXRoomSummary.swift @@ -0,0 +1,57 @@ +// +// 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) +} + +@objc extension MXRoomSummary { + static let roomSummaryDidRemoveExpiredDataFromStore = "roomSummaryDidRemoveExpiredDataFromStore" + + 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 + func mininumTimestamp() -> 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. + func removeExpiredRoomContentsFromStore() -> Bool { + let ret = self.mxSession.store.removeAllMessagesSent(before: self.mininumTimestamp(), inRoom: roomId) + if ret { + NotificationCenter.default.post(name: .roomSummaryDidRemoveExpiredDataFromStore, object: self) + } + return ret + } +} diff --git a/Riot/Categories/MXSession.swift b/Riot/Categories/MXSession.swift index 10df98141..5300c1ec3 100644 --- a/Riot/Categories/MXSession.swift +++ b/Riot/Categories/MXSession.swift @@ -26,3 +26,18 @@ extension MXSession { displayName: user?.displayname) } } + +@objc extension MXSession { + + /// Clean the storage of a session by removing the expired contents. + func removeExpiredMessages() { + var hasStoreChanged = false + for room in self.rooms { + hasStoreChanged = hasStoreChanged || room.summary.removeExpiredRoomContentsFromStore() + } + + if hasStoreChanged { + self.store.commit?() + } + } +} diff --git a/Riot/Utils/Tools.h b/Riot/Utils/Tools.h index 57eacbcdb..8d54e06b1 100644 --- a/Riot/Utils/Tools.h +++ b/Riot/Utils/Tools.h @@ -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 diff --git a/Riot/Utils/Tools.m b/Riot/Utils/Tools.m index 128fe3694..5866273ac 100644 --- a/Riot/Utils/Tools.m +++ b/Riot/Utils/Tools.m @@ -117,4 +117,16 @@ + (NSURL *)fixURLWithSeveralHashKeys:(NSURL *)url 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 From ddd97be6f3673b1a44159b3dfb7028408c196aec Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 14 Jun 2024 15:58:00 +0200 Subject: [PATCH 23/39] added functions to listen to the event and redact the room accordingly --- Riot/Categories/MXRoomSummary.swift | 11 +- Riot/Categories/MXSession.swift | 7 +- Riot/Modules/Application/LegacyAppDelegate.m | 3 + .../Modules/Room/DataSources/RoomDataSource.m | 106 ++++++++++++++++++ 4 files changed, 117 insertions(+), 10 deletions(-) diff --git a/Riot/Categories/MXRoomSummary.swift b/Riot/Categories/MXRoomSummary.swift index 691f534d0..b48f1a70f 100644 --- a/Riot/Categories/MXRoomSummary.swift +++ b/Riot/Categories/MXRoomSummary.swift @@ -20,8 +20,9 @@ extension Notification.Name { static let roomSummaryDidRemoveExpiredDataFromStore = Notification.Name(MXRoomSummary.roomSummaryDidRemoveExpiredDataFromStore) } -@objc extension MXRoomSummary { - static let roomSummaryDidRemoveExpiredDataFromStore = "roomSummaryDidRemoveExpiredDataFromStore" +extension MXRoomSummary { + @objc static let roomSummaryDidRemoveExpiredDataFromStore = "roomSummaryDidRemoveExpiredDataFromStore" + @objc static let roomRetentionStateEventType = "m.room.retention" private enum Constants { static let roomRetentionInDaysKey = "roomRetentionInDays" @@ -36,7 +37,7 @@ extension Notification.Name { } /// Get the timestamp below which the received messages must be removed from the store, and the display - func mininumTimestamp() -> UInt64 { + @objc func minimumTimestamp() -> UInt64 { let periodInMs = Tools.durationInMs(fromDays: self.roomRetentionPeriodInDays()) let currentTs = (UInt64)(Date().timeIntervalSince1970 * 1000) return (currentTs - periodInMs) @@ -47,8 +48,8 @@ extension Notification.Name { /// 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. - func removeExpiredRoomContentsFromStore() -> Bool { - let ret = self.mxSession.store.removeAllMessagesSent(before: self.mininumTimestamp(), inRoom: roomId) + @objc func removeExpiredRoomContentsFromStore() -> Bool { + let ret = self.mxSession.store.removeAllMessagesSent(before: self.minimumTimestamp(), inRoom: roomId) if ret { NotificationCenter.default.post(name: .roomSummaryDidRemoveExpiredDataFromStore, object: self) } diff --git a/Riot/Categories/MXSession.swift b/Riot/Categories/MXSession.swift index 5300c1ec3..4d7256b62 100644 --- a/Riot/Categories/MXSession.swift +++ b/Riot/Categories/MXSession.swift @@ -25,12 +25,9 @@ extension MXSession { matrixItemId: userId, displayName: user?.displayname) } -} - -@objc extension MXSession { - + /// Clean the storage of a session by removing the expired contents. - func removeExpiredMessages() { + @objc func removeExpiredMessages() { var hasStoreChanged = false for room in self.rooms { hasStoreChanged = hasStoreChanged || room.summary.removeExpiredRoomContentsFromStore() diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index 79d263cef..c5030714d 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -1826,6 +1826,9 @@ - (void)initMatrixSessions [self registerNewRequestNotificationForSession:mxSession]; [self.pushNotificationService checkPushKitPushersInSession:mxSession]; + + // Clean the storage by removing expired data + [mxSession removeExpiredMessages]; } else if (mxSession.state == MXSessionStateRunning) { diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index 16e05c423..55ef184f1 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -33,6 +33,9 @@ @interface RoomDataSource() )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 @@ - (void)destroy [self.mxSession.aggregations.beaconAggregations removeListener:self.beaconInfoSummaryDeletionListener]; } + [self unregisterRoomSummaryDidRemoveExpiredDataFromStoreNotifications]; + [self removeRoomRetentionEventListener]; + [super destroy]; } @@ -1242,4 +1273,79 @@ - (void)updateCurrentUserLocationSharingStatus } } +#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 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 From 05f5519a894c66278858f1c7a3fe17301ab8f165 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Fri, 14 Jun 2024 17:08:07 +0200 Subject: [PATCH 24/39] updating SDK --- Podfile.lock | 12 ++++++------ matrix-ios-sdk | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index 673d4ecc0..979f760d9 100644 --- a/Podfile.lock +++ b/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 diff --git a/matrix-ios-sdk b/matrix-ios-sdk index 3052a396b..fcfbb6718 160000 --- a/matrix-ios-sdk +++ b/matrix-ios-sdk @@ -1 +1 @@ -Subproject commit 3052a396b88095cbcfe1b4f488127f69e3280cda +Subproject commit fcfbb6718224e9819105b93fa9e86a9db1cf04a6 From 098cf97a39e17d71433bea2aa24db830947f35a4 Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 10 May 2024 22:54:12 +0000 Subject: [PATCH 25/39] Translated using Weblate (Portuguese (Brazil)) Currently translated at 97.3% (2351 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ --- Riot/Assets/pt_BR.lproj/Vector.strings | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Riot/Assets/pt_BR.lproj/Vector.strings b/Riot/Assets/pt_BR.lproj/Vector.strings index 991716cd9..edd2cf70e 100644 --- a/Riot/Assets/pt_BR.lproj/Vector.strings +++ b/Riot/Assets/pt_BR.lproj/Vector.strings @@ -1226,7 +1226,7 @@ "secrets_recovery_reset_action_part_2" = "Resettar tudo"; "secrets_setup_recovery_passphrase_summary_information" = "Lembre-se de sua Frase de Segurança. Ela pode ser usada para destrancar suas mensagens & dados encriptados."; "secrets_setup_recovery_passphrase_summary_title" = "Salvar sua Frase de Segurança"; -"home_empty_view_information" = "O app de chat seguro tudo-em-um para equipes, amigas(os) e organizações. Toque no botão + abaixo para adicionar pessoas e salas."; +"home_empty_view_information" = "O app de chat seguro tudo-em-um para equipes, amigos e organizações. Toque no botão + abaixo para adicionar pessoas e salas."; // MARK: - Home @@ -1244,7 +1244,7 @@ // MARK: - Invite friends -"invite_friends_action" = "Convidar amigas(os) para %@"; +"invite_friends_action" = "Convidar amigos para %@"; "pin_protection_settings_change_pin" = "Mudar PIN"; "pin_protection_confirm_pin_to_change" = "Confirme PIN para mudar PIN"; "bug_report_background_mode" = "Continuar em background"; @@ -1348,7 +1348,7 @@ "side_menu_action_feedback" = "Feedback"; "side_menu_action_help" = "Ajuda"; "side_menu_action_settings" = "Ajustes"; -"side_menu_action_invite_friends" = "Convidar amigas(os)"; +"side_menu_action_invite_friends" = "Convidar amigos"; // Mark: - Side menu @@ -1632,7 +1632,7 @@ "onboarding_use_case_not_sure_yet" = "Não tem certeza ainda? %@"; "onboarding_use_case_community_messaging" = "Comunidades"; "onboarding_use_case_work_messaging" = "Times"; -"onboarding_use_case_personal_messaging" = "Amigas(os) e família"; +"onboarding_use_case_personal_messaging" = "Amigos e família"; "onboarding_use_case_message" = "Nós vamos ajudá-la(o) a ficar conectada(o)"; "onboarding_use_case_title" = "Com quem você vai fazer chat mais?"; @@ -2654,3 +2654,20 @@ "user_other_session_security_recommendation_title" = "Outras sessões"; "room_creation_only_one_email_invite" = "Você só pode convidar um e-mail de cada vez"; "accessibility_selected" = "selecionado"; +"room_creation_user_not_found_prompt_title" = "Confirmação"; +"room_creation_user_not_found_prompt_message" = "Não foi possível encontrar perfis para este ID do Matrix. Quer começar uma conversa mesmo assim?"; +"room_creation_user_not_found_prompt_invite_action" = "Começar conversa mesmo assim"; +"room_participants_invite_anyway" = "Convidar mesmo assim"; +"room_command_part_room_description" = "Sair da sala"; +"room_command_kick_user_description" = "Remove o usuário com o ID fornecido desta sala"; +"room_command_unban_user_description" = "Desbane o usuário com o ID fornecido"; +"room_command_set_user_power_level_description" = "Define o nível de poder de um usuário"; +"room_participants_invite_unknown_participant_prompt_to_msg" = "Não foi possível encontrar perfis para este ID do Matrix. Tem certeza que deseja convidar %@ para %@?"; +"room_command_ban_user_description" = "Bane o usuário com o ID fornecido"; + +// Room commands descriptions +"room_command_change_display_name_description" = "Altera o seu nome de exibição"; +"room_command_emote_description" = "Exibe ação"; +"room_command_join_room_description" = "Entra na sala com o endereço fornecido"; +"room_command_invite_user_description" = "Convida o usuário com o ID fornecido para a sala atual"; +"authentication_qr_login_failure_device_not_supported" = "Vincular com este dispositivo não é suportado."; From f82788b75d3df5f1718307259d2eadef1c0f2a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Mesk=C3=B3?= Date: Mon, 13 May 2024 13:55:58 +0000 Subject: [PATCH 26/39] Translated using Weblate (Hungarian) Currently translated at 99.8% (2412 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ --- Riot/Assets/hu.lproj/Vector.strings | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Riot/Assets/hu.lproj/Vector.strings b/Riot/Assets/hu.lproj/Vector.strings index c965d650c..216ab88fd 100644 --- a/Riot/Assets/hu.lproj/Vector.strings +++ b/Riot/Assets/hu.lproj/Vector.strings @@ -1352,7 +1352,7 @@ "event_formatter_call_ringing" = "Hívás…"; "event_formatter_call_connecting" = "Kapcsolás…"; "settings_labs_enable_ringing_for_group_calls" = "Csengetés csoportos hívásokhoz"; -"room_no_privileges_to_create_group_call" = "Adminisztrátornak vagy moderátornak kell lenned a hívás indításához."; +"room_no_privileges_to_create_group_call" = "Adminisztrátornak vagy moderátornak kell lennie a hívás indításához."; "room_join_group_call" = "Csatlakozás"; // Chat @@ -2501,8 +2501,8 @@ "room_first_message_placeholder" = "Küld el az első üzenetedet…"; "authentication_qr_login_confirm_title" = "Biztonságos kapcsolat beállítva"; "room_event_encryption_info_key_authenticity_not_guaranteed" = "A titkosított üzenetek valódiságát ezen az eszközön nem lehet garantálni."; -"wysiwyg_composer_format_action_underline" = "Aláhúzott"; -"wysiwyg_composer_format_action_strikethrough" = "Áthúzott"; +"wysiwyg_composer_format_action_underline" = "Aláhúzott formázás alkalmazása"; +"wysiwyg_composer_format_action_strikethrough" = "Áthúzott formázás alkalmazása"; "wysiwyg_composer_format_action_italic" = "Dőlt"; // Formatting Actions @@ -2755,3 +2755,11 @@ "room_command_kick_user_description" = "Eltávolítja az adott azonosítójú felhasználót ebből a szobából"; "room_command_ban_user_description" = "Kitiltja az adott azonosítójú felhasználót"; "room_command_unban_user_description" = "Feloldja az adott azonosítójú felhasználó kitiltását"; +"notice_display_name_changed_to" = "%@ erre módosította a megjelenítendő nevét: %@"; +"poll_timeline_loading" = "Betöltés..."; +"manage_session_redirect" = "Át lesz irányítva a kiszolgálója hitelesítési szolgáltatójához, hogy befejezze a kijelentkezést."; +"manage_session_redirect_error" = "A funkcionalitás jelenleg nem érhető el. Lépjen kapcsolatba a Matrix-kiszolgáló rendszergazdájával."; +"settings_manage_account_title" = "Fiók"; +"settings_manage_account_action" = "Fiók kezelése"; +"settings_manage_account_description" = "A fiókja kezelése itt: %@"; +"room_command_change_room_topic_description" = "Beállítja a szoba témáját"; From ff468e9e22dd64b3c1e963aaffcee34970d0f2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20I=2ESvindseth?= Date: Wed, 29 May 2024 21:07:58 +0000 Subject: [PATCH 27/39] Translated using Weblate (Norwegian Nynorsk) Currently translated at 2.2% (54 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nn/ --- Riot/Assets/nn.lproj/Vector.strings | 58 +++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Riot/Assets/nn.lproj/Vector.strings b/Riot/Assets/nn.lproj/Vector.strings index 1eec1c558..f1775b985 100644 --- a/Riot/Assets/nn.lproj/Vector.strings +++ b/Riot/Assets/nn.lproj/Vector.strings @@ -9,3 +9,61 @@ "warning" = "Åtvaring"; // String for App Store "store_short_description" = "Sikker desentralisert chat/IP-telefoni"; +"ok" = "OK"; +"callbar_only_single_paused" = "Samtale sett på pause"; +"cancel" = "Avbryt"; +"save" = "Lagra"; +"join" = "Ver med"; +"decline" = "Avslå"; +"accept" = "Godta"; +"preview" = "Førehandsvising"; +"camera" = "Kamera"; +"voice" = "Røyst"; +"video" = "Video"; +"active_call" = "Aktiv samtale"; +"active_call_details" = "Aktiv samtale (%@)"; +"joined" = "Vart med"; +"later" = "Seinare"; +"rename" = "Endre namn"; +"collapse" = "Skjul"; +"send_to" = "Send til %@"; +"sending" = "Sender"; +"close" = "Lat att"; +"skip" = "Hopp over"; +"switch" = "Byt"; +"more" = "Meir"; +"less" = "Mindre"; +"open" = "Opne"; +"done" = "Ferdig"; + +// Call Bar +"callbar_only_single_active" = "Trykk for å gå tilbake til samtalen (%@)"; +"callbar_only_multiple_paused" = "%@ samtalar sett på pause"; +"callbar_return" = "Gå tilbake"; +"callbar_only_single_active_group" = "Trykk for å bli med i konferansesamtalen (%@)"; + +// Accessibility +"accessibility_checkbox_label" = "avkryssingsboks"; +"accessibility_button_label" = "knapp"; +"error" = "Feil"; +"invite_to" = "Inviter til %@"; + +// MARK: Onboarding +"onboarding_splash_register_button_title" = "Opprett konto"; +"accessibility_selected" = "vald"; +"private" = "Privat"; +"public" = "Offentleg"; +"stop" = "Stopp"; +"new_word" = "Ny"; +"existing" = "Eksisterande"; +"add" = "Legg til"; +"suggest" = "Føreslå"; +"edit" = "Rediger"; + +// Activities +"loading" = "Lastar"; +"saving" = "Lagrar"; +"callbar_active_and_single_paused" = "1 aktiv samtale (%@) · 1 samtale sett i pause"; +"callbar_active_and_multiple_paused" = "1 aktiv samtale (%@) · %@ samtalar sett på pause"; +"confirm" = "Stadfest"; +"onboarding_splash_login_button_title" = "Eg har allereie ein konto"; From 3b8f4d71de8763a816be7da5a7553df318a01829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20I=2ESvindseth?= Date: Wed, 12 Jun 2024 03:12:09 +0000 Subject: [PATCH 28/39] Translated using Weblate (Norwegian Nynorsk) Currently translated at 2.7% (67 of 2416 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nn/ --- Riot/Assets/nn.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/nn.lproj/Vector.strings b/Riot/Assets/nn.lproj/Vector.strings index f1775b985..533975c2f 100644 --- a/Riot/Assets/nn.lproj/Vector.strings +++ b/Riot/Assets/nn.lproj/Vector.strings @@ -67,3 +67,16 @@ "callbar_active_and_multiple_paused" = "1 aktiv samtale (%@) · %@ samtalar sett på pause"; "confirm" = "Stadfest"; "onboarding_splash_login_button_title" = "Eg har allereie ein konto"; +"authentication_forgot_password_text_field_placeholder" = "E-postadresse"; +"next" = "Neste"; +"back" = "Tilbake"; +"continue" = "Fortset"; +"create" = "Lag"; +"remove" = "Fjern"; +"invite" = "Inviter"; +"retry" = "Prøv på nytt"; +"on" = "På"; +"off" = "Av"; +"authentication_login_username" = "Brukarnamn / e-postadresse / telefonnummer"; +"onboarding_display_name_placeholder" = "Visingsnamn"; +"authentication_login_with_qr" = "Logg inn med QR-kode"; From 2e3ef78e024d475be97a348ddfcaf883177c505c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20I=2ESvindseth?= Date: Wed, 12 Jun 2024 02:57:35 +0000 Subject: [PATCH 29/39] Added translation using Weblate (Norwegian Nynorsk) --- Riot/Assets/nn.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) create mode 100644 Riot/Assets/nn.lproj/InfoPlist.strings diff --git a/Riot/Assets/nn.lproj/InfoPlist.strings b/Riot/Assets/nn.lproj/InfoPlist.strings new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Riot/Assets/nn.lproj/InfoPlist.strings @@ -0,0 +1 @@ + From 9de9b626ae2cee7c204d277acc5ce7e18ed00186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20I=2ESvindseth?= Date: Wed, 12 Jun 2024 03:06:31 +0000 Subject: [PATCH 30/39] Translated using Weblate (Norwegian Nynorsk) Currently translated at 50.0% (4 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/nn/ --- Riot/Assets/nn.lproj/InfoPlist.strings | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Riot/Assets/nn.lproj/InfoPlist.strings b/Riot/Assets/nn.lproj/InfoPlist.strings index 8b1378917..c1f10e5b0 100644 --- a/Riot/Assets/nn.lproj/InfoPlist.strings +++ b/Riot/Assets/nn.lproj/InfoPlist.strings @@ -1 +1,7 @@ + +"NSCalendarsUsageDescription" = "Sjå dei planlagde møta dine i appen."; +"NSFaceIDUsageDescription" = "Face ID vert brukt til å få tilgang til appen din."; +// Permissions usage explanations +"NSCameraUsageDescription" = "Kameraet vert brukt til videosamtalar, og til å ta og laste opp bilde og videoar."; +"NSMicrophoneUsageDescription" = "Appen treng tilgang til mikrofonen for samtalar, og for å spele inn video og lydmeldingar."; From aa86f39c3a4ff380b41c41205f3d6dac64785b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20I=2ESvindseth?= Date: Wed, 29 May 2024 20:59:17 +0000 Subject: [PATCH 31/39] Added translation using Weblate (Norwegian Nynorsk) --- Riot/Assets/nn.lproj/Localizable.strings | 1 + 1 file changed, 1 insertion(+) create mode 100644 Riot/Assets/nn.lproj/Localizable.strings diff --git a/Riot/Assets/nn.lproj/Localizable.strings b/Riot/Assets/nn.lproj/Localizable.strings new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Riot/Assets/nn.lproj/Localizable.strings @@ -0,0 +1 @@ + From 31468bc24d5ef69800eab255f2175becf4df5408 Mon Sep 17 00:00:00 2001 From: Doug Date: Mon, 17 Jun 2024 11:13:53 +0100 Subject: [PATCH 32/39] version++ --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 27abf6350..19854177c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +## Changes in 1.11.14 (2024-06-17) + +No significant changes. + + ## Changes in 1.11.13 (2024-06-12) Others From d07aa71d685db61d3bfc60ce22062b55dba4fa87 Mon Sep 17 00:00:00 2001 From: Doug Date: Mon, 17 Jun 2024 12:28:51 +0100 Subject: [PATCH 33/39] finish version++ From 5e473bffc7104dd8881962b9e89856ddac526205 Mon Sep 17 00:00:00 2001 From: Doug Date: Mon, 17 Jun 2024 12:28:58 +0100 Subject: [PATCH 34/39] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index e53ee7842..716ff33d7 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.11.14 -CURRENT_PROJECT_VERSION = 1.11.14 +MARKETING_VERSION = 1.11.15 +CURRENT_PROJECT_VERSION = 1.11.15 From 43de3eca3b5a9871e46c23352a13c979f24a45f5 Mon Sep 17 00:00:00 2001 From: Doug Date: Mon, 17 Jun 2024 12:31:30 +0100 Subject: [PATCH 35/39] Changelog. --- CHANGES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 19854177c..93a8b1580 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,8 @@ ## Changes in 1.11.14 (2024-06-17) -No significant changes. +🙌 Improvements + +- Room retention event implementation ([#7809](https://github.com/element-hq/element-ios/pull/7809)) ## Changes in 1.11.13 (2024-06-12) From 412f8c9b8d5f425d4f5454a55733f32c33c36ec3 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 18 Jun 2024 15:49:14 +0200 Subject: [PATCH 36/39] fix --- Podfile.lock | 10 +++++----- Riot/Categories/MXRoomSummary.swift | 13 ++++++------- Riot/Utils/EventFormatter.m | 17 +++++++++++++++-- Riot/Utils/Tools.h | 6 ------ Riot/Utils/Tools.m | 5 ----- matrix-ios-sdk | 2 +- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index 979f760d9..ce0165a2b 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -39,9 +39,9 @@ PODS: - LoggerAPI (1.9.200): - Logging (~> 1.1) - Logging (1.4.0) - - MatrixSDK (0.27.9): - - MatrixSDK/Core (= 0.27.9) - - MatrixSDK/Core (0.27.9): + - MatrixSDK (0.27.10): + - MatrixSDK/Core (= 0.27.10) + - MatrixSDK/Core (0.27.10): - 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.9): + - MatrixSDK/JingleCallStack (0.27.10): - 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: 246fd1d3620afcbf8cb76794e9343ebf3cbf881b + MatrixSDK: c805f9306d60955215f4b15043ed0f96fd4867b3 MatrixSDKCrypto: 736069ee0a5ec12852ab3498bf2242acecc443fc OLMKit: da115f16582e47626616874e20f7bb92222c7a51 ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d diff --git a/Riot/Categories/MXRoomSummary.swift b/Riot/Categories/MXRoomSummary.swift index b48f1a70f..4cf55ff6a 100644 --- a/Riot/Categories/MXRoomSummary.swift +++ b/Riot/Categories/MXRoomSummary.swift @@ -23,22 +23,21 @@ extension Notification.Name { extension MXRoomSummary { @objc static let roomSummaryDidRemoveExpiredDataFromStore = "roomSummaryDidRemoveExpiredDataFromStore" @objc static let roomRetentionStateEventType = "m.room.retention" + @objc static let roomRetentionEventMaxLifetimeKey = "max_lifetime" + @objc static let roomRetentionMaxLifetime = "roomRetentionMaxLifetime" - 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 { + private func roomRetentionPeriodInMillis() -> UInt64 { + if let period = self.others[MXRoomSummary.roomRetentionMaxLifetime] as? UInt64 { return period } else { - return 365 + return Tools.durationInMs(fromDays: 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 periodInMs = self.roomRetentionPeriodInMillis() let currentTs = (UInt64)(Date().timeIntervalSince1970 * 1000) return (currentTs - periodInMs) } diff --git a/Riot/Utils/EventFormatter.m b/Riot/Utils/EventFormatter.m index d53a3e19a..2a1b15140 100644 --- a/Riot/Utils/EventFormatter.m +++ b/Riot/Utils/EventFormatter.m @@ -632,7 +632,14 @@ - (MXEvent *)voiceBroadcastInfoStartedEventWithEvent:(MXEvent *)voiceBroadcastIn - (BOOL)session:(MXSession *)session updateRoomSummary:(MXRoomSummary *)summary withStateEvents:(NSArray *)stateEvents roomState:(MXRoomState *)roomState { BOOL updated = [super session:session updateRoomSummary:summary withStateEvents:stateEvents roomState:roomState]; - + + MXEvent* lastRoomRetentionEvent = [self roomRetentionEventFromStateEvents:stateEvents]; + if (lastRoomRetentionEvent) + { + summary.others[MXRoomSummary.roomRetentionMaxLifetime] = lastRoomRetentionEvent.content[MXRoomSummary.roomRetentionEventMaxLifetimeKey]; + updated = YES; + } + // Customisation for EMS Functional Members in direct rooms if (BuildSettings.supportFunctionalMembers && summary.room.isDirect) { @@ -645,7 +652,7 @@ - (BOOL)session:(MXSession *)session updateRoomSummary:(MXRoomSummary *)summary // room name which we'll do twice more in updateRoomSummary:withServerRoomSummary:roomState: anyway. // // So return YES and let that happen there. - return YES; + updated = YES; } } @@ -801,6 +808,12 @@ - (MXEvent *)functionalMembersEventFromStateEvents:(NSArray *)stateEv return [stateEvents filteredArrayUsingPredicate:functionalMembersPredicate].lastObject; } +- (MXEvent *)roomRetentionEventFromStateEvents:(NSArray *)stateEvents +{ + NSPredicate *functionalMembersPredicate = [NSPredicate predicateWithFormat:@"type == %@", kMXEventTypeStringRoomRetention]; + return [stateEvents filteredArrayUsingPredicate:functionalMembersPredicate].lastObject; +} + #pragma mark - Timestamp formatting - (NSString*)dateStringFromDate:(NSDate *)date withTime:(BOOL)time diff --git a/Riot/Utils/Tools.h b/Riot/Utils/Tools.h index 8d54e06b1..f114167b3 100644 --- a/Riot/Utils/Tools.h +++ b/Riot/Utils/Tools.h @@ -55,10 +55,4 @@ */ + (uint64_t)durationInMsFromDays:(uint)days; -/** - * Convert a duration in ms to a number of days. - */ -+ (uint)numberOfDaysFromDurationInMs:(uint64_t)duration; - - @end diff --git a/Riot/Utils/Tools.m b/Riot/Utils/Tools.m index 5866273ac..4094d0223 100644 --- a/Riot/Utils/Tools.m +++ b/Riot/Utils/Tools.m @@ -124,9 +124,4 @@ + (uint64_t)durationInMsFromDays:(uint)days return days * (uint64_t)(86400000); } -+ (uint)numberOfDaysFromDurationInMs:(uint64_t)duration -{ - return (uint)(duration / 86400000); -} - @end diff --git a/matrix-ios-sdk b/matrix-ios-sdk index fcfbb6718..ff2b2a402 160000 --- a/matrix-ios-sdk +++ b/matrix-ios-sdk @@ -1 +1 @@ -Subproject commit fcfbb6718224e9819105b93fa9e86a9db1cf04a6 +Subproject commit ff2b2a4024b48dbeba5d4157d2622161b3034ba4 From ca90f363b181edc465e29c1dc972700b2dc54928 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 18 Jun 2024 16:52:09 +0200 Subject: [PATCH 37/39] version++ --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 93a8b1580..907d69b54 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +## Changes in 1.11.15 (2024-06-18) + +No significant changes. + + ## Changes in 1.11.14 (2024-06-17) 🙌 Improvements From 0c07ae2e9bcf084906ebfa423064eb93cc6c0292 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 18 Jun 2024 16:54:46 +0200 Subject: [PATCH 38/39] finish version++ From 8534e4121eb336b5d3d5583f043808ab441af451 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 25 Jun 2024 18:10:57 +0200 Subject: [PATCH 39/39] Resolve conflicts on Rebase/Element-v1.11.15 into Tchap --- .github/workflows/ci-build.yml | 7 +-- .github/workflows/ci-tests.yml | 7 +-- Config/AppVersion.xcconfig | 5 --- Config/BuildSettings.swift | 10 ----- Podfile | 27 +----------- Podfile.lock | 38 +++++----------- Riot/Managers/Settings/RiotSettings.swift | 7 --- Riot/Utils/EventFormatter.m | 10 ++--- RiotNSE/BuildSettings.swift | 19 +++++++- RiotShareExtension/BuildSettings.swift | 19 +++++++- RiotShareExtension/target.yml | 1 + ...ummary.swift => MXRoomSummary+Tchap.swift} | 0 Tchap/Generated/Strings.swift | 44 +++++++++++++++---- Tchap/Utils/Tools.h | 15 +++---- Tchap/Utils/Tools.m | 17 +++---- Tchap/target.yml | 1 + changelog.d/1066.change | 1 + 17 files changed, 106 insertions(+), 122 deletions(-) rename Tchap/Extensions/{MXRoomSummary.swift => MXRoomSummary+Tchap.swift} (100%) create mode 100644 changelog.d/1066.change diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 42a7afff6..905c36558 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -20,9 +20,7 @@ jobs: # Concurrency group not needed as this workflow only runs on develop which we always want to test. steps: - - uses: actions/checkout@v4 - with: - submodules: 'true' + - uses: actions/checkout@v2 # Common cache # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job @@ -51,13 +49,10 @@ jobs: run: | bundle config path vendor/bundle bundle install --jobs 4 --retry 3 -<<<<<<< HEAD # Disabled for Tchap to avoid MatrixSDK version reset on the main branch (develop), instead of using the DINUM specific one. # - name: Use right MatrixSDK versions # run: bundle exec fastlane point_dependencies_to_related_branches -======= ->>>>>>> v1.11.15 # Main step - name: Build iOS simulator diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 712dd8513..5ffde41ac 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -25,9 +25,7 @@ jobs: cancel-in-progress: true steps: - - uses: actions/checkout@v4 - with: - submodules: 'true' + - uses: actions/checkout@v2 # Common cache # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job @@ -56,13 +54,10 @@ jobs: run: | bundle config path vendor/bundle bundle install --jobs 4 --retry 3 -<<<<<<< HEAD # Disabled for Tchap to avoid MatrixSDK version reset on the main branch (develop), instead of using the DINUM specific one. # - name: Use right MatrixSDK versions # run: bundle exec fastlane point_dependencies_to_related_branches -======= ->>>>>>> v1.11.15 # Main step - name: Unit tests diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index 22cbd11ee..200075ce8 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,10 +15,5 @@ // // Version -<<<<<<< HEAD MARKETING_VERSION = 2.7.9 CURRENT_PROJECT_VERSION = 1 -======= -MARKETING_VERSION = 1.11.15 -CURRENT_PROJECT_VERSION = 1.11.15 ->>>>>>> v1.11.15 diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index a4b6308df..9abdd1f5f 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -304,7 +304,6 @@ final class BuildSettings: NSObject { static let settingsScreenShowChangePassword: Bool = true static let settingsScreenShowEnableStunServerFallback: Bool = true static let settingsScreenShowNotificationDecodedContentOption: Bool = true -<<<<<<< HEAD static let settingsScreenShowNsfwRoomsOption: Bool = false static let settingsSecurityScreenShowSessions: Bool = true static let settingsSecurityScreenShowSetupBackup: Bool = true @@ -313,15 +312,6 @@ final class BuildSettings: NSObject { static let settingsSecurityScreenShowCryptographyInfo: Bool = true static let settingsSecurityScreenShowCryptographyExport: Bool = true static let settingsSecurityScreenShowAdvancedUnverifiedDevices: Bool = false -======= - static let settingsSecurityScreenShowSessions:Bool = true - static let settingsSecurityScreenShowSetupBackup:Bool = true - static let settingsSecurityScreenShowRestoreBackup:Bool = true - static let settingsSecurityScreenShowDeleteBackup:Bool = true - static let settingsSecurityScreenShowCryptographyInfo:Bool = true - static let settingsSecurityScreenShowCryptographyExport:Bool = true - static let settingsSecurityScreenShowAdvancedUnverifiedDevices:Bool = true ->>>>>>> v1.11.15 /// A setting to enable the presence configuration settings section. static let settingsScreenPresenceAllowConfiguration: Bool = false diff --git a/Podfile b/Podfile index 96a87a6d0..d3c1db477 100644 --- a/Podfile +++ b/Podfile @@ -28,33 +28,7 @@ def import_SwiftUI_pods pod 'ZXingObjC', '~> 3.6.9' end -<<<<<<< HEAD def import_Common_pods -======= -abstract_target 'RiotPods' do - - pod 'GBDeviceInfo', '~> 7.1.0' - pod 'Reusable', '~> 4.1' - pod 'KeychainAccess', '~> 4.2.2' - pod 'WeakDictionary', '~> 2.0' - - pod 'Sentry', '~> 7.15.0' - - pod 'OLMKit' - pod 'zxcvbn-ios' - - # Tools - pod 'SwiftGen' - pod 'SwiftLint' - pod 'SwiftFormat/CLI' - - target "Riot" do - import_MatrixSDK - import_MatrixKit_pods - - import_SwiftUI_pods - ->>>>>>> v1.11.15 pod 'UICollectionViewRightAlignedLayout', '~> 0.0.3' pod 'UICollectionViewLeftAlignedLayout', '~> 1.0.2' pod 'KTCenterFlowLayout', '~> 1.3.1' @@ -87,6 +61,7 @@ abstract_target 'TchapPods' do # Tools pod 'SwiftGen', '~> 6.3' pod 'SwiftLint', '~> 0.49.1' + pod 'SwiftFormat/CLI' target "Tchap" do import_MatrixSDK diff --git a/Podfile.lock b/Podfile.lock index 7d3a4aa41..3ea7cb1e5 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -39,35 +39,26 @@ PODS: - LoggerAPI (1.9.200): - Logging (~> 1.1) - Logging (1.4.0) -<<<<<<< HEAD - - MatrixSDK (0.27.7): - - MatrixSDK/Core (= 0.27.7) - - MatrixSDK/Core (0.27.7): -======= - MatrixSDK (0.27.10): - MatrixSDK/Core (= 0.27.10) - MatrixSDK/Core (0.27.10): ->>>>>>> v1.11.15 - AFNetworking (~> 4.0.0) - GZIP (~> 1.3.0) - libbase58 (~> 0.1.4) - - MatrixSDKCrypto (= 0.3.13) + - MatrixSDKCrypto (= 0.4.2) - OLMKit (~> 3.2.5) - Realm (= 10.27.0) - SwiftyBeaver (= 1.9.5) -<<<<<<< HEAD - - MatrixSDK/JingleCallStack (0.27.7): -======= - MatrixSDK/JingleCallStack (0.27.10): ->>>>>>> v1.11.15 - JitsiMeetSDKLite (= 8.1.2-lite) - MatrixSDK/Core - - MatrixSDKCrypto (0.3.13) + - MatrixSDKCrypto (0.4.2) - OLMKit (3.2.12): - OLMKit/olmc (= 3.2.12) - OLMKit/olmcpp (= 3.2.12) - OLMKit/olmc (3.2.12) - OLMKit/olmcpp (3.2.12) + - PostHog (2.0.0) - ReadMoreTextView (3.0.1) - Realm (10.27.0): - Realm/Headers (= 10.27.0) @@ -83,6 +74,7 @@ PODS: - Sentry/Core (7.15.0) - SideMenu (6.5.0) - SwiftBase32 (0.9.0) + - SwiftFormat/CLI (0.54.0) - SwiftGen (6.6.2) - SwiftJWT (3.6.200): - BlueCryptor (~> 1.0) @@ -111,20 +103,17 @@ DEPENDENCIES: - KeychainAccess (~> 4.2.2) - KTCenterFlowLayout (~> 1.3.1) - libPhoneNumber-iOS (~> 0.9.13) -<<<<<<< HEAD - - MatrixSDK (= 0.27.7) - - MatrixSDK/JingleCallStack (= 0.27.7) -======= - MatrixSDK (from `matrix-ios-sdk/MatrixSDK.podspec`) - MatrixSDK/JingleCallStack (from `matrix-ios-sdk/MatrixSDK.podspec`) ->>>>>>> v1.11.15 - OLMKit + - PostHog (~> 2.0.0) - ReadMoreTextView (~> 3.0.1) - Reusable (~> 4.1) - RxSwift (~> 5.1.1) - Sentry (~> 7.15.0) - SideMenu (~> 6.5) - SwiftBase32 (~> 0.9.0) + - SwiftFormat/CLI - SwiftGen (~> 6.3) - SwiftJWT (~> 3.6.200) - SwiftLint (~> 0.49.1) @@ -159,6 +148,7 @@ SPEC REPOS: - Logging - MatrixSDKCrypto - OLMKit + - PostHog - ReadMoreTextView - Realm - Reusable @@ -166,6 +156,7 @@ SPEC REPOS: - Sentry - SideMenu - SwiftBase32 + - SwiftFormat - SwiftGen - SwiftJWT - SwiftLint @@ -202,14 +193,10 @@ SPEC CHECKSUMS: libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75 LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d Logging: beeb016c9c80cf77042d62e83495816847ef108b -<<<<<<< HEAD - MatrixSDK: e07b2309f3c6498c1df987441da7006d099c47a4 - MatrixSDKCrypto: bf08b72f2cd015d8749420a2b8b92fc0536bedf4 -======= MatrixSDK: c805f9306d60955215f4b15043ed0f96fd4867b3 MatrixSDKCrypto: 736069ee0a5ec12852ab3498bf2242acecc443fc ->>>>>>> v1.11.15 OLMKit: da115f16582e47626616874e20f7bb92222c7a51 + PostHog: 660ec6c9d80cec17b685e148f17f6785a88b597d ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d Realm: 9ca328bd7e700cc19703799785e37f77d1a130f2 Reusable: 6bae6a5e8aa793c9c441db0213c863a64bce9136 @@ -217,6 +204,7 @@ SPEC CHECKSUMS: Sentry: 63ca44f5e0c8cea0ee5a07686b02e56104f41ef7 SideMenu: f583187d21c5b1dd04c72002be544b555a2627a2 SwiftBase32: 9399c25a80666dc66b51e10076bf591e3bbb8f17 + SwiftFormat: 0e0b577434e6aa63bc82a8905b40d9597b8452d4 SwiftGen: 1366a7f71aeef49954ca5a63ba4bef6b0f24138c SwiftJWT: 88c412708f58c169d431d344c87bc79a87c830ae SwiftLint: 32ee33ded0636d0905ef6911b2b67bbaeeedafa5 @@ -227,10 +215,6 @@ SPEC CHECKSUMS: zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -<<<<<<< HEAD -PODFILE CHECKSUM: 3db384be27ed06c11b15ee9abc4616afd45428c1 -======= -PODFILE CHECKSUM: b622ffadc1a0fe5442787bd9023ca3d110384814 ->>>>>>> v1.11.15 +PODFILE CHECKSUM: 971cd7529e2d127b237469afa2c18e6dced151ec COCOAPODS: 1.14.3 diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift index 1c921bb41..c2755d956 100644 --- a/Riot/Managers/Settings/RiotSettings.swift +++ b/Riot/Managers/Settings/RiotSettings.swift @@ -97,11 +97,6 @@ final class RiotSettings: NSObject { @UserDefault(key: UserDefaultsKeys.pinRoomsWithUnreadMessagesOnHome, defaultValue: false, storage: defaults) var pinRoomsWithUnreadMessagesOnHome -<<<<<<< HEAD - /// Indicate to show Not Safe For Work public rooms. - @UserDefault(key: "showNSFWPublicRooms", defaultValue: false, storage: defaults) - var showNSFWPublicRooms - /// Indicate if the user wants to display the join and leave events in the room history. /// (No by default) @UserDefault(key: "showJoinLeaveEvents", defaultValue: false, storage: defaults) @@ -112,8 +107,6 @@ final class RiotSettings: NSObject { @UserDefault(key: "showProfileUpdateEvents", defaultValue: false, storage: defaults) var showProfileUpdateEvents -======= ->>>>>>> v1.11.15 // MARK: User interface @UserDefault(key: "userInterfaceTheme", defaultValue: nil, storage: defaults) diff --git a/Riot/Utils/EventFormatter.m b/Riot/Utils/EventFormatter.m index 0f9ee2a79..17ab314fd 100644 --- a/Riot/Utils/EventFormatter.m +++ b/Riot/Utils/EventFormatter.m @@ -659,12 +659,6 @@ - (MXEvent *)voiceBroadcastInfoStartedEventWithEvent:(MXEvent *)voiceBroadcastIn - (BOOL)session:(MXSession *)session updateRoomSummary:(MXRoomSummary *)summary withStateEvents:(NSArray *)stateEvents roomState:(MXRoomState *)roomState { BOOL updated = [super session:session updateRoomSummary:summary withStateEvents:stateEvents roomState:roomState]; -<<<<<<< HEAD - - // Store in the room summary some additional information - updated |= [summary tc_updateWithStateEvents:stateEvents]; - -======= MXEvent* lastRoomRetentionEvent = [self roomRetentionEventFromStateEvents:stateEvents]; if (lastRoomRetentionEvent) @@ -673,7 +667,9 @@ - (BOOL)session:(MXSession *)session updateRoomSummary:(MXRoomSummary *)summary updated = YES; } ->>>>>>> v1.11.15 + // Store in the room summary some additional information + updated |= [summary tc_updateWithStateEvents:stateEvents]; + // Customisation for EMS Functional Members in direct rooms if (BuildSettings.supportFunctionalMembers && summary.room.isDirect) { diff --git a/RiotNSE/BuildSettings.swift b/RiotNSE/BuildSettings.swift index ce637a7d4..2911cd225 100644 --- a/RiotNSE/BuildSettings.swift +++ b/RiotNSE/BuildSettings.swift @@ -272,8 +272,25 @@ final class BuildSettings: NSObject { tchapFeatureNotificationByEmail: [ tchapFeatureAnyHomeServer ], + // Audio calls for all except Finances in Tchap Production. tchapFeatureVoiceOverIP: [ - "agent.dinum.tchap.gouv.fr" + "agent.externe.tchap.gouv.fr", + "agent.collectivites.tchap.gouv.fr", + "agent.tchap.gouv.fr", + "agent.elysee.tchap.gouv.fr", + "agent.pm.tchap.gouv.fr", + "agent.ssi.tchap.gouv.fr", +// "agent.finances.tchap.gouv.fr", + "agent.social.tchap.gouv.fr", + "agent.interieur.tchap.gouv.fr", + "agent.agriculture.tchap.gouv.fr", + "agent.justice.tchap.gouv.fr", + "agent.diplomatie.tchap.gouv.fr", + "agent.intradef.tchap.gouv.fr", + "agent.dinum.tchap.gouv.fr", + "agent.culture.tchap.gouv.fr", + "agent.dev-durable.tchap.gouv.fr", + "agent.education.tchap.gouv.fr" ], // No activation of video calls actually in Tchap Production. // tchapFeatureVideoOverIP: [ diff --git a/RiotShareExtension/BuildSettings.swift b/RiotShareExtension/BuildSettings.swift index ce637a7d4..2911cd225 100644 --- a/RiotShareExtension/BuildSettings.swift +++ b/RiotShareExtension/BuildSettings.swift @@ -272,8 +272,25 @@ final class BuildSettings: NSObject { tchapFeatureNotificationByEmail: [ tchapFeatureAnyHomeServer ], + // Audio calls for all except Finances in Tchap Production. tchapFeatureVoiceOverIP: [ - "agent.dinum.tchap.gouv.fr" + "agent.externe.tchap.gouv.fr", + "agent.collectivites.tchap.gouv.fr", + "agent.tchap.gouv.fr", + "agent.elysee.tchap.gouv.fr", + "agent.pm.tchap.gouv.fr", + "agent.ssi.tchap.gouv.fr", +// "agent.finances.tchap.gouv.fr", + "agent.social.tchap.gouv.fr", + "agent.interieur.tchap.gouv.fr", + "agent.agriculture.tchap.gouv.fr", + "agent.justice.tchap.gouv.fr", + "agent.diplomatie.tchap.gouv.fr", + "agent.intradef.tchap.gouv.fr", + "agent.dinum.tchap.gouv.fr", + "agent.culture.tchap.gouv.fr", + "agent.dev-durable.tchap.gouv.fr", + "agent.education.tchap.gouv.fr" ], // No activation of video calls actually in Tchap Production. // tchapFeatureVideoOverIP: [ diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml index b9399f787..3d8224d84 100644 --- a/RiotShareExtension/target.yml +++ b/RiotShareExtension/target.yml @@ -35,6 +35,7 @@ targets: - package: AnalyticsEvents - package: DeviceKit - package: DTCoreText + - package: PostHog configFiles: Debug: Debug.xcconfig diff --git a/Tchap/Extensions/MXRoomSummary.swift b/Tchap/Extensions/MXRoomSummary+Tchap.swift similarity index 100% rename from Tchap/Extensions/MXRoomSummary.swift rename to Tchap/Extensions/MXRoomSummary+Tchap.swift diff --git a/Tchap/Generated/Strings.swift b/Tchap/Generated/Strings.swift index 9f27d360d..0377110b3 100644 --- a/Tchap/Generated/Strings.swift +++ b/Tchap/Generated/Strings.swift @@ -275,19 +275,31 @@ public class TchapL10n: NSObject { public static var eventFormatterReportIncident: String { return TchapL10n.tr("Tchap", "event_formatter_report_incident") } - /// La durée de validité de votre compte a expiré. Un email vous a été envoyé pour la renouveler. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous. + /// Un email vous a été envoyé pour renouveler votre compte. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous. public static var expiredAccountAlertMessage: String { return TchapL10n.tr("Tchap", "expired_account_alert_message") } - /// Un nouvel email vous a été envoyé pour renouveler la validité de votre compte. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous. - public static var expiredAccountOnNewSentEmailMsg: String { - return TchapL10n.tr("Tchap", "expired_account_on_new_sent_email_msg") + /// Votre compte a expiré + public static var expiredAccountAlertTitle: String { + return TchapL10n.tr("Tchap", "expired_account_alert_title") } - /// Demander l’envoi d’un nouvel email + /// Continuer + public static var expiredAccountOnNewSentEmailButton: String { + return TchapL10n.tr("Tchap", "expired_account_on_new_sent_email_button") + } + /// Un nouvel email vous a été envoyé pour renouveler votre compte. Une fois que vous aurez suivi le lien qu’il contient, cliquez ci-dessous. + public static var expiredAccountOnNewSentEmailMessage: String { + return TchapL10n.tr("Tchap", "expired_account_on_new_sent_email_message") + } + /// Email envoyé + public static var expiredAccountOnNewSentEmailTitle: String { + return TchapL10n.tr("Tchap", "expired_account_on_new_sent_email_title") + } + /// Emvoyer un nouvel email public static var expiredAccountRequestRenewalEmailButton: String { return TchapL10n.tr("Tchap", "expired_account_request_renewal_email_button") } - /// J’ai renouvelé mon compte + /// Continuer public static var expiredAccountResumeButton: String { return TchapL10n.tr("Tchap", "expired_account_resume_button") } @@ -591,7 +603,7 @@ public class TchapL10n: NSObject { public static var roomFilesTabTitle: String { return TchapL10n.tr("Tchap", "room_files_tab_title") } - /// Cet utilisateur n'est pas autorisé à rejoindre ce salon. + /// Cet utilisateur est déjà membre du salon ou n'est pas autorisé à le rejoindre. public static var roomInviteErrorActionForbidden: String { return TchapL10n.tr("Tchap", "room_invite_error_action_forbidden") } @@ -615,6 +627,14 @@ public class TchapL10n: NSObject { public static var roomMembersTabTitle: String { return TchapL10n.tr("Tchap", "room_members_tab_title") } + /// Le fichier est trop lourd pour être envoyé. La taille limite est de %ldMo, mais la taille de votre fichier est de %ldMo. + public static func roomSendFileTooBigMessage(_ p1: Int, _ p2: Int) -> String { + return TchapL10n.tr("Tchap", "room_send_file_too_big_message", p1, p2) + } + /// Erreur d'envoi + public static var roomSendFileTooBigTitle: String { + return TchapL10n.tr("Tchap", "room_send_file_too_big_title") + } /// Ce changement n’est pas supporté actuellement car le salon est accessible par lien. Il sera supporté prochainement public static var roomSettingsAllowExternalUsersForbidden: String { return TchapL10n.tr("Tchap", "room_settings_allow_external_users_forbidden") @@ -795,6 +815,14 @@ public class TchapL10n: NSObject { public static var settingsCryptoImportInvalidFile: String { return TchapL10n.tr("Tchap", "settings_crypto_import_invalid_file") } + /// En savoir plus. + public static var settingsEnableEmailNotifLink: String { + return TchapL10n.tr("Tchap", "settings_enable_email_notif_link") + } + /// Recevez un e-mail si au moins un message récent non lu pendant 72h. + public static var settingsEnableEmailNotifText: String { + return TchapL10n.tr("Tchap", "settings_enable_email_notif_text") + } /// Sans cette autorisation, les appels entrants ne seront pas notifiés. public static var settingsEnablePushNotifText: String { return TchapL10n.tr("Tchap", "settings_enable_push_notif_text") @@ -807,7 +835,7 @@ public class TchapL10n: NSObject { public static var settingsHideFromUsersDirectoryTitle: String { return TchapL10n.tr("Tchap", "settings_hide_from_users_directory_title") } - /// Notification par courriel + /// Notification par e-mail public static var settingsNotificationEmail: String { return TchapL10n.tr("Tchap", "settings_notification_email") } diff --git a/Tchap/Utils/Tools.h b/Tchap/Utils/Tools.h index e27b33821..645fc421a 100644 --- a/Tchap/Utils/Tools.h +++ b/Tchap/Utils/Tools.h @@ -54,7 +54,13 @@ */ + (NSURL*)fixURLWithSeveralHashKeys:(NSURL*)url; -<<<<<<< HEAD:Tchap/Utils/Tools.h +#pragma mark - Time utilities + +/** + * Convert a number of days to a duration in ms. + */ ++ (uint64_t)durationInMsFromDays:(uint)days; + #pragma mark - Tchap permalink /* @@ -84,13 +90,6 @@ */ + (NSString*)permalinkToEvent:(NSString*)eventId inRoom:(NSString*)roomIdOrAlias; -======= -#pragma mark - Time utilities -/** - * Convert a number of days to a duration in ms. - */ -+ (uint64_t)durationInMsFromDays:(uint)days; ->>>>>>> v1.11.15:Riot/Utils/Tools.h @end diff --git a/Tchap/Utils/Tools.m b/Tchap/Utils/Tools.m index a794e0d60..8db610bbb 100644 --- a/Tchap/Utils/Tools.m +++ b/Tchap/Utils/Tools.m @@ -142,7 +142,13 @@ + (NSURL *)fixURLWithSeveralHashKeys:(NSURL *)url return fixedURL; } -<<<<<<< HEAD:Tchap/Utils/Tools.m +#pragma mark - Time utilities + ++ (uint64_t)durationInMsFromDays:(uint)days +{ + return days * (uint64_t)(86400000); +} + #pragma mark - Tchap permalink + (NSString *)permalinkToRoom:(NSString *)roomIdOrAlias @@ -190,13 +196,4 @@ + (NSString *)permalinkToEvent:(NSString *)eventId inRoom:(NSString *)roomIdOrAl } -======= -#pragma mark - Time utilities - -+ (uint64_t)durationInMsFromDays:(uint)days -{ - return days * (uint64_t)(86400000); -} - ->>>>>>> v1.11.15:Riot/Utils/Tools.m @end diff --git a/Tchap/target.yml b/Tchap/target.yml index 9f497793c..63080dfe3 100644 --- a/Tchap/target.yml +++ b/Tchap/target.yml @@ -54,6 +54,7 @@ targetTemplates: - package: WysiwygComposer - package: AnalyticsEvents - package: Mapbox + - package: PostHog preBuildScripts: - name: 🛠 Environment diff --git a/changelog.d/1066.change b/changelog.d/1066.change new file mode 100644 index 000000000..8a583097a --- /dev/null +++ b/changelog.d/1066.change @@ -0,0 +1 @@ +Rebase sur Element 1.11.15 \ No newline at end of file