Remove the CommonSettingsProtocol and use UserSession to carry multiple dependencies. (#6302)

* Remove the CommonSettingsProtocol.

* Replace multiple dependencies with the UserSession when it carries them.
This commit is contained in:
Doug
2026-10-09 10:20:00 +01:00
committed by GitHub
parent a3d170534c
commit 65bab49f39
75 changed files with 212 additions and 369 deletions
@@ -7,7 +7,7 @@
import UserNotifications
nonisolated extension CommonSettingsProtocol {
nonisolated extension AppSettings {
/// The sound name to use in outgoing notifications.
/// Falls back to the default Element X tone if no custom tone has been selected.
var notificationSoundName: UNNotificationSoundName {
+5 -5
View File
@@ -17,7 +17,7 @@ nonisolated protocol NSEUserSessionProtocol {
}
final nonisolated class NSEUserSession: NSEUserSessionProtocol {
private let userSettings: CommonSettingsProtocol
let userSettings: UserSettings
private let baseClient: ClientProtocol
private let notificationClient: NotificationClient
private let userID: String
@@ -49,17 +49,17 @@ final nonisolated class NSEUserSession: NSEUserSessionProtocol {
}
var threadsEnabled: Bool {
userSettings.threadsEnabled
userSettings.app.threadsEnabled
}
init(credentials: KeychainCredentials,
roomID: String,
clientSessionDelegate: ClientSessionDelegate,
clientFactory: ClientFactoryProtocol = ClientFactory(),
userSettings: CommonSettingsProtocol,
appSettings: AppSettings,
appHooks: AppHooks) async throws {
userID = credentials.userID
self.userSettings = userSettings
userSettings = appSettings.userSettings(for: credentials.userID)
baseClient = try await clientFactory.makeNSEClient(credentials: credentials,
roomID: roomID,
@@ -75,7 +75,7 @@ final nonisolated class NSEUserSession: NSEUserSessionProtocol {
delegateHandle = try baseClient.setDelegate(delegate: ClientDelegateWrapper())
// Inject the content scanner so the SDK gates the media it downloads whilst building the notification.
if let contentScannerURL = userSettings.contentScannerURL.publisher.value {
if let contentScannerURL = userSettings.app.contentScannerURL.publisher.value {
let contentScanner = ContentScanner(scannerUrl: contentScannerURL.absoluteString)
await baseClient.setContentScanner(contentScanner: contentScanner)
}
+12 -11
View File
@@ -13,7 +13,6 @@ import UserNotifications
nonisolated class NotificationHandler {
private let userSession: NSEUserSession
private let settings: CommonSettingsProtocol
private let contentHandler: (UNNotificationContent) -> Void
private var notificationContent: UNMutableNotificationContent
private let tag: String
@@ -23,13 +22,15 @@ nonisolated class NotificationHandler {
/// Whether this handler has already counted its notification towards the app icon badge.
private var hasCountedTowardsBadge = false
private var userSettings: UserSettings {
userSession.userSettings
}
init(userSession: NSEUserSession,
settings: CommonSettingsProtocol,
contentHandler: @escaping (UNNotificationContent) -> Void,
notificationContent: UNMutableNotificationContent,
tag: String) {
self.userSession = userSession
self.settings = settings
self.contentHandler = contentHandler
self.notificationContent = notificationContent
self.tag = tag
@@ -38,7 +39,7 @@ nonisolated class NotificationHandler {
style: .plain)
notificationContentBuilder = NotificationContentBuilder(messageEventStringBuilder: eventStringBuilder,
notificationSoundName: settings.notificationSoundName,
notificationSoundName: userSession.userSettings.app.notificationSoundName,
userSession: userSession)
}
@@ -55,7 +56,7 @@ nonisolated class NotificationHandler {
case .processedShouldDiscard, .unsupportedShouldDiscard:
discardNotification()
case .shouldDisplay:
if settings.hideQuietNotificationAlerts, !notificationItemProxy.isNoisy {
if userSettings.app.hideQuietNotificationAlerts, !notificationItemProxy.isNoisy {
discardNotification()
return
}
@@ -79,20 +80,20 @@ nonisolated class NotificationHandler {
private func deliverNotification() {
notificationContent.badge = NSNumber(value: incrementBadgeCount())
MXLog.info("\(tag) Delivering notification, new badge value: \(settings.lastKnownBadgeCount)")
MXLog.info("\(tag) Delivering notification, new badge value: \(userSettings.app.lastKnownBadgeCount)")
contentHandler(notificationContent)
}
private func incrementBadgeCount() -> Int {
// `handleTimeExpiration` can deliver a notification this handler already delivered.
guard !hasCountedTowardsBadge else {
return settings.lastKnownBadgeCount
return userSettings.app.lastKnownBadgeCount
}
hasCountedTowardsBadge = true
settings.lastKnownBadgeCount += 1
userSettings.app.lastKnownBadgeCount += 1
return settings.lastKnownBadgeCount
return userSettings.app.lastKnownBadgeCount
}
private func discardNotification() {
@@ -100,7 +101,7 @@ nonisolated class NotificationHandler {
let content = UNMutableNotificationContent()
// Nothing new is shown to the user, so leave the badge where the app last put it.
content.badge = NSNumber(value: settings.lastKnownBadgeCount)
content.badge = NSNumber(value: userSettings.app.lastKnownBadgeCount)
MXLog.info("\(tag) New badge value: \(content.badge?.stringValue ?? "nil")")
contentHandler(content)
@@ -135,7 +136,7 @@ nonisolated class NotificationHandler {
if let targetNotification = deliveredNotifications.first(where: { $0.request.content.eventID == redactedEventID }) {
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [targetNotification.request.identifier])
settings.lastKnownBadgeCount = max(0, settings.lastKnownBadgeCount - 1)
userSettings.app.lastKnownBadgeCount = max(0, userSettings.app.lastKnownBadgeCount - 1)
}
return .processedShouldDiscard
+11 -12
View File
@@ -63,7 +63,7 @@ actor NotificationServiceExtensionActor {
private static let firstNotificationThreshold: TimeInterval = 15 * 60
private let settings: CommonSettingsProtocol
private let appSettings: AppSettings
private let appHooks: AppHooks
/// This is nonisolated just because the expire function needs to be served ASAP so we should not call it from a Task, however this is
@@ -82,7 +82,7 @@ actor NotificationServiceExtensionActor {
guard let userDefaults = TrackedUserDefaults(suiteName: AppSettings.suiteName) else {
fatalError("Catastrophic error retrieving user defaults for \(AppSettings.suiteName)")
}
settings = AppSettings(store: userDefaults)
appSettings = AppSettings(store: userDefaults)
appHooks = AppHooks()
appHooks.setUp()
@@ -96,10 +96,10 @@ actor NotificationServiceExtensionActor {
if !BootDetectionManager.isDeviceLockedAfterReboot(containerURL: URL.appGroupContainerDirectory) {
Self.targetConfiguration.withLock { state in
guard state == nil else { return }
state = Target.nse.configure(logLevel: settings.logLevel,
traceLogPacks: settings.traceLogPacks,
state = Target.nse.configure(logLevel: appSettings.logLevel,
traceLogPacks: appSettings.traceLogPacks,
sentryURL: nil,
rageshakeURL: settings.bugReportRageshakeURL,
rageshakeURL: appSettings.bugReportRageshakeURL,
appHooks: appHooks)
}
}
@@ -161,7 +161,7 @@ actor NotificationServiceExtensionActor {
}
let homeserverURL = credentials.restorationToken.session.homeserverUrl
await appHooks.remoteSettingsHook.loadCache(forHomeserver: homeserverURL, applyingTo: settings)
await appHooks.remoteSettingsHook.loadCache(forHomeserver: homeserverURL, applyingTo: appSettings)
guard let mutableContent = request.content.mutableCopy() as? UNMutableNotificationContent else {
return contentHandler(request.content)
@@ -177,11 +177,10 @@ actor NotificationServiceExtensionActor {
let userSession = try await NSEUserSession(credentials: credentials,
roomID: roomID,
clientSessionDelegate: keychainController,
userSettings: settings,
appSettings: appSettings,
appHooks: appHooks)
notificationHandler = NotificationHandler(userSession: userSession,
settings: settings,
contentHandler: contentHandler,
notificationContent: mutableContent,
tag: tag)
@@ -221,10 +220,10 @@ actor NotificationServiceExtensionActor {
return false
}
guard let lastKnownBootTime = settings.lastNotificationBootTime else {
guard let lastKnownBootTime = appSettings.lastNotificationBootTime else {
// Assume a missing boot time indicates a fresh installation…
// So store the current boot time but let the notification through.
settings.lastNotificationBootTime = currentBootTime
appSettings.lastNotificationBootTime = currentBootTime
return false
}
@@ -233,7 +232,7 @@ actor NotificationServiceExtensionActor {
}
// This is the first notification since boot, store the boot time.
settings.lastNotificationBootTime = currentBootTime
appSettings.lastNotificationBootTime = currentBootTime
// At this point it becomes a trade-off. Once the device has been powered on for a long enough amount
// of time it is a reasonable assumption that the device has now connected to a network and that any
@@ -258,7 +257,7 @@ actor NotificationServiceExtensionActor {
let content = UNMutableNotificationContent()
content.body = L10n.notificationReceivedWhileOfflineIos
content.sound = settings.notificationSound
content.sound = appSettings.notificationSound
let request = UNNotificationRequest(identifier: Self.receivedWhileOfflineNotificationID, content: content, trigger: nil)
UNUserNotificationCenter.current().add(request)