Files
element-x-ios/ElementX/Sources/Services/Client/HomeserverHistoryManager.swift
T
Doug 64aae09c6d Add an AccountProvider type and use it within the authentication flow. (#6103)
* Add an AccountProvider type and use it within AppSettings.

* Use the AccountProvider type within the Authentication flow too.

* Fix unit test compilation with Swift 6.4

* Make sure defaultAccountProvider takes allowOtherAccountProviders into account.

* Document a caveat on using AuthenticationService.homeserver.value.accountProvider.
2026-09-14 15:25:33 +01:00

75 lines
3.0 KiB
Swift

//
// Copyright 2026 Element Creations Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Combine
/// Manages the tracking, removal, and autocomplete matchin of previous servers in AppSettings.
/// Servers are sorted by most recently used.
class HomeserverHistoryManager {
let appSettings: AppSettings
/// cache with confirmed lowercase servers to avoid having to lowercase the entire list on every keystroke
private var cachedServers: [String] = []
var servers: [String] {
cachedServers
}
private var cancellables: Set<AnyCancellable> = []
init(appSettings: AppSettings) {
self.appSettings = appSettings
appSettings
.previousServersPublisher
.sink { [weak self] _ in
self?.updateCachedServers()
}
.store(in: &cancellables)
}
/// Tracks the given server in AppSettings's `previousServers`. The server is asserted
/// unique and placed at the beginning of the list, such that the most recent connected server is at the front.
func addServerToList(_ server: String) {
MXLog.info("Tracking server in previous servers: \(server)")
let lowercaseServer = server.lowercased()
var newList = _removeServerFromList(lowercaseServer) // don't trigger a publisher update
newList.insert(lowercaseServer, at: 0)
appSettings.previousServers = newList
}
/// Removes `server` from the tracking history of `AppSettings.previousServers`
func removeServerFromList(_ server: String) {
let lowercaseServer = server.lowercased()
appSettings.previousServers = _removeServerFromList(lowercaseServer)
}
/// Removes `lowercaseServer` from `appSettings.previousServers`
/// - Parameter lowercaseServer: the server string. It MUST be passed in with all lowercased letters.
/// - Returns: a new copy of the list without `lowercaseServer`
private func _removeServerFromList(_ lowercaseServer: String) -> [String] {
var newList = appSettings.previousServers
newList.removeAll { $0.lowercased() == lowercaseServer }
return newList
}
/// Retrieves the most recent server matching the given prefix, if any
func server(matchingPrefix prefix: String) -> String? {
let lowercasedPrefix = prefix.lowercased()
return servers.first { $0.hasPrefix(lowercasedPrefix) }
}
/// Retrieves all servers from AppSettings, previous and pre-provided and stores them in memory
/// in all lowercase. This is the list that matches are made against.
private func updateCachedServers() {
let previous = appSettings.previousServers.map { $0.lowercased() }
let defaultProviders = appSettings.accountProviders.map { $0.serverNameOrBaseURL.lowercased() }
cachedServers = previous + defaultProviders
}
}