Feature/3811 appconfig

This commit is contained in:
Frank Rotermund
2023-09-19 11:21:12 +00:00
parent e3cfb301a9
commit 5dd5dc2db7
13 changed files with 205 additions and 145 deletions

View File

@@ -678,4 +678,7 @@ class BWIBuildSettings: NSObject {
// MARK: Create Room Menu
var enableAllChatsToolbar = true
// MARK: App Config
var avoidServerSelectionOnAppConfig = false
}

View File

@@ -40,6 +40,6 @@ extension BWIBuildSettings {
enableAllChatsToolbar = false
itunesAppLink = "itms://itunes.apple.com/app/bundesmessenger-beta/id1617068656?mt=8"
avoidServerSelectionOnAppConfig = true
}
}

View File

@@ -31,6 +31,7 @@ extension BWIBuildSettings {
bwiEnableLoginProtection = false
itunesAppLink = "itms://itunes.apple.com/app/bundesmessenger-open/id6450672686?mt=8"
avoidServerSelectionOnAppConfig = true
}
}

View File

@@ -28,6 +28,7 @@ extension BWIBuildSettings {
bwiNotificationTimes = true
enableNewSessionManagerByDefault = true
itunesAppLink = "itms://itunes.apple.com/app/bundesmessenger/id1616866351?mt=8"
avoidServerSelectionOnAppConfig = true
}
}

View File

@@ -144,7 +144,12 @@ final class AuthenticationCoordinator: NSObject, AuthenticationCoordinatorProtoc
// bwi: force serverselection on test apps
if (BWIBuildSettings.shared.authScreenShowTestServerOptions && BWIBuildSettings.shared.bwiLoginFlowLayout) ||
BWIBuildSettings.shared.bumLoginFlowLayout {
showServerSelectionScreen(for: flow)
// bwi #3811: when there is a valid url from app config don't show server selection
if BWIBuildSettings.shared.avoidServerSelectionOnAppConfig && AppConfigService.shared.isAppConfig {
self.useHomeserver(AppConfigService.shared.serverUrl())
} else {
showServerSelectionScreen(for: flow)
}
} else {
do {
// Start the flow using the default server (or a provisioning link if set).
@@ -267,6 +272,21 @@ final class AuthenticationCoordinator: NSObject, AuthenticationCoordinatorProtoc
callback?(.cancel(.register))
}
/// Updates the login flow using the supplied homeserver address, or shows an error when this isn't possible.
@MainActor private func useHomeserver(_ homeserverAddress: String) {
let homeserverAddress = HomeserverAddress.sanitized(homeserverAddress)
Task {
do {
try await authenticationService.startFlow(.login, for: homeserverAddress)
showLoginScreen()
} catch {
displayError(message: error.localizedDescription)
}
}
}
// MARK: - Login
/// Shows the login screen.

View File

@@ -189,7 +189,7 @@ final class OnboardingCoordinator: NSObject, OnboardingCoordinatorProtocol {
}
private func showWelcomeExperience() {
let welcomeVC = WelcomeExperienceViewController.makeViewController(completion: { [weak self] in
let welcomeVC = WelcomeExperienceViewController.makeViewController(completion: { [weak self] in
if BWIBuildSettings.shared.onboardingEnableNewAuthenticationFlow {
self?.startLoading()
self?.beginAuthentication(with: .login) { [weak self] in

View File

@@ -59,6 +59,7 @@ targets:
- path: ../Config/BWIBuildSettings.swift
- path: ../Config/BuM/BWIBuildSettings+BuM.swift
- path: ../bwi/UserAgent/UserAgentService.swift
- path: ../bwi/LoginProtection/LoginProtectionService.swift
- path: ../Riot/Utils/DataProtectionHelper.swift
- path: ../Config/CommonConfiguration.swift
- path: ../Riot/Experiments/

View File

@@ -17,10 +17,6 @@
import SwiftUI
import AVKit
enum AuthenticationServerSelectionScreenAlertType {
case showServerMaintenanceInfoMessageAlert, showServerMaintenanceDefaultAlert, showInvalidAppVersionAlert, showDowntimeTimeAlert, showInvalidServerAlert
}
struct AuthenticationServerSelectionScreen: View {
// MARK: - Properties
@@ -39,7 +35,8 @@ struct AuthenticationServerSelectionScreen: View {
// bwi #4976 show maintenance alert
@State private var isFetchingDowntime = false
@State private var showAlert = false
@State private var activeAlert: AuthenticationServerSelectionScreenAlertType = .showInvalidAppVersionAlert
@State private var isInvalidServerAlert = false
@State private var activeAlert: ServerMaintenanceAlertType = .showInvalidAppVersionAlert
private var textFieldFooterColor: Color {
viewModel.viewState.hasValidationError ? theme.colors.alert : theme.colors.tertiaryContent
@@ -98,67 +95,12 @@ struct AuthenticationServerSelectionScreen: View {
}
}
.alert(isPresented: $showAlert, content: {
switch activeAlert {
case .showInvalidAppVersionAlert:
return Alert(title: Text(BWIL10n.bwiOutdatedVersionWarningTitle),
message: Text(BWIL10n.bwiOutdatedVersionWarningMessage(AppInfo.current.displayName)),
dismissButton: .destructive(Text(BWIL10n.bwiOutdatedVersionAppstoreButton), action: {
let iTunesLink = BWIBuildSettings.shared.itunesAppLink
UIApplication.shared.open(URL(string: iTunesLink)!, options: [:], completionHandler: nil)
}))
case .showDowntimeTimeAlert:
if BWIBuildSettings.shared.ignoreBlockingMaintenance && service.isBlocking() {
return Alert( title: Text(""),
message: Text(ServerDowntimeDefaultService().downtimeText()),
primaryButton: .cancel(Text(BWIL10n.blockingDowntimeAlertIgnoreButton)) {
UserDefaults.standard.set(false, forKey: "ServerDownTimeBlockingKey")
service.setManuallyIgnored()
self.submit()
},
secondaryButton: .destructive(Text(BWIL10n.blockingDowntimeAlertDismissButton))
)
} else {
return Alert(title: Text(BWIL10n.downtimeTitle),
message: Text(ServerDowntimeDefaultService().downtimeText() != "" ? BWIL10n.downtimeDefaultMessage + "\n\n" + ServerDowntimeDefaultService().downtimeText() : BWIL10n.downtimeDefaultMessage),
dismissButton: .destructive(Text(service.isBlocking() ? BWIL10n.blockingDowntimeAlertDismissButton : BWIL10n.downtimeAlertDismissButton)) {
if service.isBlocking() {
return
} else {
self.submit()
}
})
}
case .showServerMaintenanceInfoMessageAlert:
if BWIBuildSettings.shared.ignoreBlockingMaintenance && service.isBlocking() {
return Alert( title: Text(""),
message: Text(ServerDowntimeDefaultService().downtimeText()),
primaryButton: .cancel(Text(BWIL10n.blockingDowntimeAlertIgnoreButton)) {
self.submit()
},
secondaryButton: .destructive(Text(BWIL10n.blockingDowntimeAlertDismissButton))
)
} else {
return Alert(title: Text(""),
message: Text(ServerDowntimeDefaultService().downtimeText()),
dismissButton: .destructive(Text(service.isBlocking() ? BWIL10n.blockingDowntimeAlertDismissButton : BWIL10n.downtimeAlertDismissButton)) {
if service.isBlocking() {
return
} else {
self.submit()
}
})
}
case .showServerMaintenanceDefaultAlert:
return Alert(title: Text(BWIL10n.downtimeTitle),
message: Text(BWIL10n.downtimeDefaultMessage),
dismissButton: .destructive(Text(BWIL10n.downtimeAlertDismissButton)) {
self.submit()
})
case .showInvalidServerAlert:
if isInvalidServerAlert {
return self.invalidServerAlert()
} else {
return service.alert(alertType: activeAlert) {
self.submit()
}
}
})
@@ -274,7 +216,7 @@ struct AuthenticationServerSelectionScreen: View {
if isHomeserverAddressValid(viewModel.homeserverAddress) {
viewModel.send(viewAction: .confirm)
} else {
activeAlert = .showInvalidServerAlert
isInvalidServerAlert = true
showAlert = true
}
}
@@ -362,18 +304,11 @@ struct AuthenticationServerSelectionScreen: View {
}
private func showAlertIfNeeded() {
switch service.nextDowntimeStatus() {
case .none, .warning:
self.submit()
break
case .ongoing:
if service.downtimeType() == .adhocMessage {
activeAlert = .showServerMaintenanceInfoMessageAlert
} else {
activeAlert = .showDowntimeTimeAlert
}
if service.showAlert() {
activeAlert = service.alertType()
showAlert = true
break
} else {
self.submit()
}
}
}

View File

@@ -35,7 +35,7 @@ extension UserDefaults
@objcMembers class AppConfigService : NSObject {
static let shared = AppConfigService()
private let serverUrlKey = "serverUrl"
private let serverUrlKey = "home_server_url"
private let contentScannerKey = "contentScanner"
private let pusherUrlKey = "pusherUrl"
private let permalinkUrlKey = "permalinkUrl"
@@ -50,10 +50,14 @@ extension UserDefaults
var session: MXSession?
var isAppConfig: Bool
private func loadAppConfig() {
isAppConfig = false
do {
if let dataIn = UserDefaults.standard.value(forKey: savedConfig) as? Data {
appConfig = try JSONDecoder().decode(AppConfig.self, from: dataIn)
isAppConfig = true
}
} catch {
@@ -70,17 +74,18 @@ extension UserDefaults
}
private func checkUrlSavety(_ serverUrl: String) -> Bool {
if serverUrl.hasSuffix("bwi.de")
|| serverUrl.hasSuffix("example.com")
|| serverUrl.hasSuffix("example.com")
|| serverUrl.hasSuffix("example.com") {
return true
if BWIBuildSettings.shared.bwiEnableLoginProtection {
let protectionService = LoginProtectionService()
protectionService.hashes = BWIBuildSettings.shared.bwiHashes
return protectionService.isValid(serverUrl)
} else {
return false
return true
}
}
override init() {
isAppConfig = false
super.init()
self.loadAppConfig()
}
@@ -93,12 +98,13 @@ extension UserDefaults
}
func handleAppConfig() {
if let dict = UserDefaults.standard.dictionary(forKey: configKey) {
var config = AppConfig()
if let serverUrl = dict[serverUrlKey] as? String {
if checkUrlSavety(serverUrl) {
if serverUrl.count == 0 {
config.serverUrl = nil
} else if checkUrlSavety(serverUrl) {
config.serverUrl = serverUrl
}
}
@@ -118,6 +124,9 @@ extension UserDefaults
}
}
// app config needs at least a valid server url
isAppConfig = (config.serverUrl != nil)
if config != appConfig {
appConfig = config
self.saveAppConfig()
@@ -125,6 +134,8 @@ extension UserDefaults
completion(true)
}
}
UserDefaults.standard.removeObject(forKey: configKey)
}
}

View File

@@ -16,6 +16,7 @@
*/
import Foundation
import SwiftUI
enum ServerDowntimeStatus {
case none
@@ -23,6 +24,10 @@ enum ServerDowntimeStatus {
case ongoing
}
enum ServerMaintenanceAlertType {
case showServerMaintenanceInfoMessageAlert, showServerMaintenanceDefaultAlert, showInvalidAppVersionAlert, showDowntimeTimeAlert
}
enum ServerDowntimeType: String {
case adhocMessage = "ADHOC_MESSAGE"
case maintenance = "MAINTENANCE"
@@ -38,4 +43,7 @@ protocol ServerDowntimeService {
func isBlocking() -> Bool
func setManuallyIgnored()
func isManuallyIgnored() -> Bool
func alert( alertType:ServerMaintenanceAlertType, completion: @escaping () -> Void) -> Alert
func showAlert() -> Bool
func alertType() -> ServerMaintenanceAlertType
}

View File

@@ -18,6 +18,7 @@
import Foundation
import UIKit
import MatrixSDK
import SwiftUI
fileprivate let BWI_ServerDowntimes = "BWI_ServerDowntimes"
@@ -150,6 +151,80 @@ fileprivate let maintenanceURL = "/_matrix/cmaintenance"
extension ServerDowntimeDefaultService : ServerDowntimeService {
func alert(alertType: ServerMaintenanceAlertType, completion: @escaping () -> Void) -> Alert {
switch alertType {
case .showInvalidAppVersionAlert:
return Alert(title: Text(BWIL10n.bwiOutdatedVersionWarningTitle),
message: Text(BWIL10n.bwiOutdatedVersionWarningMessage(AppInfo.current.displayName)),
dismissButton: .destructive(Text(BWIL10n.bwiOutdatedVersionAppstoreButton), action: {
let iTunesLink = BWIBuildSettings.shared.itunesAppLink
UIApplication.shared.open(URL(string: iTunesLink)!, options: [:], completionHandler: nil)
}))
case .showDowntimeTimeAlert:
if BWIBuildSettings.shared.ignoreBlockingMaintenance && isBlocking() {
return Alert( title: Text(""),
message: Text(ServerDowntimeDefaultService().downtimeText()),
primaryButton: .cancel(Text(BWIL10n.blockingDowntimeAlertIgnoreButton)) {
UserDefaults.standard.set(false, forKey: "ServerDownTimeBlockingKey")
self.setManuallyIgnored()
completion()
},
secondaryButton: .destructive(Text(BWIL10n.blockingDowntimeAlertDismissButton))
)
} else {
return Alert(title: Text(BWIL10n.downtimeTitle),
message: Text(ServerDowntimeDefaultService().downtimeText() != "" ? BWIL10n.downtimeDefaultMessage + "\n\n" + ServerDowntimeDefaultService().downtimeText() : BWIL10n.downtimeDefaultMessage),
dismissButton: .destructive(Text(isBlocking() ? BWIL10n.blockingDowntimeAlertDismissButton : BWIL10n.downtimeAlertDismissButton)) {
if self.isBlocking() {
return
} else {
completion()
}
})
}
case .showServerMaintenanceInfoMessageAlert:
if BWIBuildSettings.shared.ignoreBlockingMaintenance && isBlocking() {
return Alert( title: Text(""),
message: Text(ServerDowntimeDefaultService().downtimeText()),
primaryButton: .cancel(Text(BWIL10n.blockingDowntimeAlertIgnoreButton)) {
completion()
},
secondaryButton: .destructive(Text(BWIL10n.blockingDowntimeAlertDismissButton))
)
} else {
return Alert(title: Text(""),
message: Text(ServerDowntimeDefaultService().downtimeText()),
dismissButton: .destructive(Text(isBlocking() ? BWIL10n.blockingDowntimeAlertDismissButton : BWIL10n.downtimeAlertDismissButton)) {
if self.isBlocking() {
return
} else {
completion()
}
})
}
case .showServerMaintenanceDefaultAlert:
return Alert(title: Text(BWIL10n.downtimeTitle),
message: Text(BWIL10n.downtimeDefaultMessage),
dismissButton: .destructive(Text(BWIL10n.downtimeAlertDismissButton)) {
completion()
})
}
}
func showAlert() -> Bool {
return nextDowntimeStatus() == .ongoing
}
func alertType() -> ServerMaintenanceAlertType {
if downtimeType() == .adhocMessage {
return .showServerMaintenanceInfoMessageAlert
} else {
return .showDowntimeTimeAlert
}
}
func fetchDowntimes(session: MXSession, completion: @escaping () -> Void) {
session.matrixRestClient.getDowntime(completion: { (jsonResponse, error) in
do {

View File

@@ -16,10 +16,6 @@
import SwiftUI
enum OnBoardingSplashScreenAlertType {
case showServerMaintenanceInfoMessageAlert, showServerMaintenanceDefaultAlert, showInvalidAppVersionAlert, showDowntimeTimeAlert
}
@available(iOS 14.0, *)
/// The splash screen shown at the beginning of the onboarding flow.
struct OnboardingBwiSplashScreen: View {
@@ -36,7 +32,7 @@ struct OnboardingBwiSplashScreen: View {
@State private var overlayFrame: CGRect = .zero
@State private var isFetchingDowntime = false
@State private var showAlert = false
@State private var activeAlert: OnBoardingSplashScreenAlertType = .showInvalidAppVersionAlert
@State private var activeAlert: ServerMaintenanceAlertType = .showInvalidAppVersionAlert
// MARK: Public
@@ -79,40 +75,8 @@ struct OnboardingBwiSplashScreen: View {
.navigationTitle("")
.navigationBarHidden(true)
.alert(isPresented: $showAlert, content: {
switch activeAlert {
case .showInvalidAppVersionAlert:
return Alert(title: Text(BWIL10n.bwiOutdatedVersionWarningTitle),
message: Text(BWIL10n.bwiOutdatedVersionWarningMessage(AppInfo.current.displayName)),
dismissButton: .destructive(Text(BWIL10n.bwiOutdatedVersionAppstoreButton), action: {
let iTunesLink = BWIBuildSettings.shared.itunesAppLink
UIApplication.shared.open(URL(string: iTunesLink)!, options: [:], completionHandler: nil)
}))
case .showDowntimeTimeAlert:
return Alert(title: Text(BWIL10n.downtimeTitle),
message: Text(ServerDowntimeDefaultService().downtimeText() != "" ? BWIL10n.downtimeDefaultMessage + "\n\n" + ServerDowntimeDefaultService().downtimeText() : BWIL10n.downtimeDefaultMessage),
dismissButton: .destructive(Text(service.isBlocking() ? BWIL10n.blockingDowntimeAlertDismissButton : BWIL10n.downtimeAlertDismissButton)) {
if service.isBlocking() {
return
} else {
viewModel.send(viewAction: .login)
}
})
case .showServerMaintenanceInfoMessageAlert:
return Alert(title: Text(""),
message: Text(ServerDowntimeDefaultService().downtimeText()),
dismissButton: .destructive(Text(service.isBlocking() ? BWIL10n.blockingDowntimeAlertDismissButton : BWIL10n.downtimeAlertDismissButton)) {
if service.isBlocking() {
return
} else {
viewModel.send(viewAction: .login)
}
})
case .showServerMaintenanceDefaultAlert:
return Alert(title: Text(BWIL10n.downtimeTitle),
message: Text(BWIL10n.downtimeDefaultMessage),
dismissButton: .destructive(Text(BWIL10n.downtimeAlertDismissButton)) {
viewModel.send(viewAction: .login)
})
service.alert(alertType: activeAlert) {
viewModel.send(viewAction: .login)
}
})
}
@@ -146,24 +110,11 @@ struct OnboardingBwiSplashScreen: View {
private func showAlertIfNeeded() {
switch service.nextDowntimeStatus() {
case .none:
viewModel.send(viewAction: .login)
break
case .ongoing:
if service.downtimeType() == .adhocMessage {
activeAlert = .showServerMaintenanceInfoMessageAlert
} else {
activeAlert = .showDowntimeTimeAlert
}
if service.showAlert() {
activeAlert = service.alertType()
showAlert = true
break
case .warning:
// only show active downtimes
} else {
viewModel.send(viewAction: .login)
// showAlert = true
// activeAlert = .showServerMaintenanceAlert
break
}
}
}

View File

@@ -36,6 +36,11 @@ fileprivate struct Page: View {
@State var buttonCallback: (() -> Void)?
private let service = ServerDowntimeDefaultService()
@State private var isFetchingDowntime = false
@State private var showAlert = false
@State private var activeAlert: ServerMaintenanceAlertType = .showInvalidAppVersionAlert
var body: some View {
GeometryReader { geometry in
VStack(alignment: .center, spacing: 40) {
@@ -54,8 +59,9 @@ fileprivate struct Page: View {
.multilineTextAlignment(.center)
Spacer()
// bwi #3811: check for maintenance when the server selection is skipped
if let doneButton = doneButton, let buttonCallback = buttonCallback {
Button(action: buttonCallback) {
Button(action: startButtonAction) {
Text(doneButton)
.foregroundColor(.white)
.padding(.vertical, 10)
@@ -64,6 +70,11 @@ fileprivate struct Page: View {
.clipShape(RoundedRectangle(cornerRadius: 10))
}
.padding(.bottom, 100)
.alert(isPresented: $showAlert, content: {
service.alert(alertType: activeAlert) {
buttonCallback()
}
})
}
}
.padding(.top, 100)
@@ -71,6 +82,49 @@ fileprivate struct Page: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
private func startButtonAction() {
guard let buttonCallback = buttonCallback else {
return
}
if BWIBuildSettings.shared.enableMaintenanceInfoOnLogin && BWIBuildSettings.shared.avoidServerSelectionOnAppConfig && AppConfigService.shared.isAppConfig {
isFetchingDowntime = true // show progresview
if BWIBuildSettings.shared.useTestDataForDowntime {
service.fetchDowntimes {
self.isFetchingDowntime = false // hide progressview
self.showAlertIfNeeded()
}
} else {
service.fetchDowntimesWithDirectRequest { success in
DispatchQueue.main.async {
self.isFetchingDowntime = false // hide progressview
if success {
self.showAlertIfNeeded()
} else {
}
}
}
}
} else {
buttonCallback()
}
}
private func showAlertIfNeeded() {
guard let buttonCallback = buttonCallback else {
return
}
if service.showAlert() {
activeAlert = service.alertType()
showAlert = true
} else {
buttonCallback()
}
}
}
struct WelcomeExperienceView_Previews: PreviewProvider {