206 lines
9.1 KiB
Swift
206 lines
9.1 KiB
Swift
//
|
|
// Copyright 2022 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 SwiftUI
|
|
|
|
/// Store Element specific app settings.
|
|
final class AppSettings {
|
|
private enum UserDefaultsKeys: String {
|
|
case lastVersionLaunched
|
|
case seenInvites
|
|
case timelineStyle
|
|
case analyticsConsentState
|
|
case enableInAppNotifications
|
|
case pusherProfileTag
|
|
case shouldCollapseRoomStateEvents
|
|
case startChatFlowEnabled
|
|
case startChatUserSuggestionsEnabled
|
|
case editRoomDetailsFlowEnabled
|
|
case invitesFlowEnabled
|
|
case inviteMorePeopleFlowEnabled
|
|
case readReceiptsEnabled
|
|
}
|
|
|
|
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
|
|
|
/// UserDefaults to be used on reads and writes.
|
|
private static var store: UserDefaults! = UserDefaults(suiteName: suiteName)
|
|
|
|
static func reset() {
|
|
MXLog.warning("Resetting the AppSettings.")
|
|
store.removePersistentDomain(forName: suiteName)
|
|
}
|
|
|
|
static func configureWithSuiteName(_ name: String) {
|
|
suiteName = name
|
|
|
|
guard let userDefaults = UserDefaults(suiteName: name) else {
|
|
fatalError("Fail to load shared UserDefaults")
|
|
}
|
|
|
|
store = userDefaults
|
|
}
|
|
|
|
// MARK: - Application
|
|
|
|
lazy var canShowDeveloperOptions: Bool = {
|
|
#if DEBUG
|
|
true
|
|
#else
|
|
let apps = ["io.element.elementx.nightly", "io.element.elementx.pr"]
|
|
return apps.contains(InfoPlistReader.main.baseBundleIdentifier)
|
|
#endif
|
|
}()
|
|
|
|
/// The last known version of the app that was launched on this device, which is
|
|
/// used to detect when migrations should be run. When `nil` the app may have been
|
|
/// deleted between runs so should clear data in the shared container and keychain.
|
|
@UserPreference(key: UserDefaultsKeys.lastVersionLaunched, storageType: .userDefaults(store))
|
|
var lastVersionLaunched: String?
|
|
|
|
let lastLaunchDate = Date()
|
|
|
|
/// The Set of room identifiers of invites that the user already saw in the invites list.
|
|
/// This Set is being used to implement badges for unread invites.
|
|
@UserPreference(key: UserDefaultsKeys.seenInvites, defaultValue: [], storageType: .userDefaults(store))
|
|
var seenInvites: Set<String>
|
|
|
|
/// The default homeserver address used. This is intentionally a string without a scheme
|
|
/// so that it can be passed to Rust as a ServerName for well-known discovery.
|
|
let defaultHomeserverAddress = "matrix.org"
|
|
|
|
/// An override of the homeserver's Sliding Sync proxy URL. This allows development against servers
|
|
/// that don't yet have an officially trusted proxy configured in their well-known.
|
|
let slidingSyncProxyURL: URL? = nil
|
|
|
|
/// The task identifier used for background app refresh. Also used in main target's the Info.plist
|
|
let backgroundAppRefreshTaskIdentifier = "io.element.elementx.background.refresh"
|
|
|
|
// MARK: - Authentication
|
|
|
|
/// The URL that is opened when tapping the Learn more button on the sliding sync alert during authentication.
|
|
let slidingSyncLearnMoreURL = URL(staticString: "https://github.com/matrix-org/sliding-sync/blob/main/docs/Landing.md")
|
|
|
|
/// The redirect URL used for OIDC.
|
|
let oidcRedirectURL = URL(staticString: "io.element:/callback")
|
|
/// The app's main URL shown when using OIDC.
|
|
let oidcClientURL = URL(staticString: "https://element.io")
|
|
/// The app's Terms of Service URL shown when using OIDC.
|
|
let oidcTermsURL = URL(staticString: "https://element.io/user-terms-of-service")
|
|
/// The app's Privacy Policy URL shown when using OIDC.
|
|
let oidcPolicyURL = URL(staticString: "https://element.io/privacy")
|
|
/// Any pre-defined static client registrations for OIDC issuers.
|
|
let oidcStaticRegistrations = [URL(staticString: "https://id.thirdroom.io/realms/thirdroom"): "elementx"]
|
|
|
|
// MARK: - Notifications
|
|
|
|
var pusherAppId: String {
|
|
#if DEBUG
|
|
InfoPlistReader.main.baseBundleIdentifier + ".ios.dev"
|
|
#else
|
|
InfoPlistReader.main.baseBundleIdentifier + ".ios.prod"
|
|
#endif
|
|
}
|
|
|
|
let pushGatewayBaseURL = URL(staticString: "https://matrix.org/_matrix/push/v1/notify")
|
|
|
|
// MARK: - Bug report
|
|
|
|
let bugReportServiceBaseURL = URL(staticString: "https://riot.im/bugreports")
|
|
let bugReportSentryURL = URL(staticString: "https://f39ac49e97714316965b777d9f3d6cd8@sentry.tools.element.io/44")
|
|
// Use the name allocated by the bug report server
|
|
let bugReportApplicationId = "element-x-ios"
|
|
let bugReportUISIId = "element-auto-uisi"
|
|
|
|
// MARK: - Analytics
|
|
|
|
#if DEBUG
|
|
/// The configuration to use for analytics during development. Set `isEnabled` to false to disable analytics in debug builds.
|
|
/// **Note:** Analytics are disabled by default for forks. If you are maintaining a fork, set custom configurations.
|
|
let analyticsConfiguration = AnalyticsConfiguration(isEnabled: InfoPlistReader.main.bundleIdentifier.starts(with: "io.element.elementx"),
|
|
host: "https://posthog.element.dev",
|
|
apiKey: "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN",
|
|
termsURL: URL(staticString: "https://element.io/cookie-policy"))
|
|
#else
|
|
/// The configuration to use for analytics. Set `isEnabled` to false to disable analytics.
|
|
/// **Note:** Analytics are disabled by default for forks. If you are maintaining a fork, set custom configurations.
|
|
let analyticsConfiguration = AnalyticsConfiguration(isEnabled: InfoPlistReader.main.bundleIdentifier.starts(with: "io.element.elementx"),
|
|
host: "https://posthog.hss.element.io",
|
|
apiKey: "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
|
|
termsURL: URL(staticString: "https://element.io/cookie-policy"))
|
|
#endif
|
|
|
|
/// Whether the user has opted in to send analytics.
|
|
@UserPreference(key: UserDefaultsKeys.analyticsConsentState, defaultValue: AnalyticsConsentState.unknown, storageType: .userDefaults(store))
|
|
var analyticsConsentState
|
|
|
|
// MARK: - Room Screen
|
|
|
|
@UserPreference(key: UserDefaultsKeys.timelineStyle, defaultValue: TimelineStyle.bubbles, storageType: .userDefaults(store))
|
|
var timelineStyle
|
|
|
|
@UserPreference(key: UserDefaultsKeys.shouldCollapseRoomStateEvents, defaultValue: true, storageType: .volatile)
|
|
var shouldCollapseRoomStateEvents
|
|
|
|
// MARK: - Notifications
|
|
|
|
@UserPreference(key: UserDefaultsKeys.enableInAppNotifications, defaultValue: true, storageType: .userDefaults(store))
|
|
var enableInAppNotifications
|
|
|
|
let enableLocalPushNotifications = false
|
|
|
|
/// Tag describing which set of device specific rules a pusher executes.
|
|
@UserPreference(key: UserDefaultsKeys.pusherProfileTag, storageType: .userDefaults(store))
|
|
var pusherProfileTag: String?
|
|
|
|
/// A set of all the notification identifiers that have been served so far, it's reset every time the app is launched
|
|
@UserPreference(key: SharedUserDefaultsKeys.servedNotificationIdentifiers, initialValue: [], storageType: .userDefaults(store))
|
|
var servedNotificationIdentifiers: Set<String>
|
|
|
|
// MARK: - Other
|
|
|
|
let permalinkBaseURL = URL(staticString: "https://matrix.to")
|
|
|
|
// MARK: - Feature Flags
|
|
|
|
// MARK: Start Chat
|
|
|
|
@UserPreference(key: UserDefaultsKeys.startChatFlowEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
var startChatFlowEnabled
|
|
|
|
@UserPreference(key: UserDefaultsKeys.startChatUserSuggestionsEnabled, defaultValue: false, storageType: .volatile)
|
|
var startChatUserSuggestionsEnabled
|
|
|
|
// MARK: Invites
|
|
|
|
@UserPreference(key: UserDefaultsKeys.invitesFlowEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
var invitesFlowEnabled
|
|
|
|
@UserPreference(key: UserDefaultsKeys.inviteMorePeopleFlowEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
var inviteMorePeopleFlowEnabled
|
|
|
|
// MARK: Receipts
|
|
|
|
@UserPreference(key: UserDefaultsKeys.readReceiptsEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
var readReceiptsEnabled
|
|
|
|
// MARK: Room details edit
|
|
|
|
@UserPreference(key: UserDefaultsKeys.editRoomDetailsFlowEnabled, defaultValue: false, storageType: .userDefaults(store))
|
|
var editRoomDetailsFlowEnabled
|
|
}
|