MESSENGER-5706 merge from #5660 and refactoring

This commit is contained in:
JanNiklas Grabowski
2024-03-01 14:06:46 +01:00
parent a37e40b4b8
commit ebcb633892
13 changed files with 130 additions and 134 deletions

View File

@@ -38,7 +38,7 @@ extension BWIBuildSettings {
ignoreBlockingMaintenance = true ignoreBlockingMaintenance = true
bwiUseWellKnownPrivacyPolicyLink = true bwiUseWellKnownPrivacyPolicyLink = true
showChangeProfilePictureHint = true showChangeProfilePictureHint = true
showFederationIntroduction = true showFederationIntroduction = false
itunesAppLink = "https://apps.apple.com/de/app/bundesmessenger/id1616866351" itunesAppLink = "https://apps.apple.com/de/app/bundesmessenger/id1616866351"
avoidServerSelectionOnAppConfig = true avoidServerSelectionOnAppConfig = true

View File

@@ -52,8 +52,10 @@
"bwi_settings_developer_unrestrict_user" = "Nutzereinschränkung aufheben"; "bwi_settings_developer_unrestrict_user" = "Nutzereinschränkung aufheben";
"bwi_settings_developer_unmark_banner" = "Banner als nicht gelesen markieren"; "bwi_settings_developer_unmark_banner" = "Banner als nicht gelesen markieren";
"bwi_settings_developer_introduce_federation" = "Föderation"; "bwi_settings_developer_introduce_federation" = "Föderation";
"bwi_settings_developer_introduce_federation_preview" = "Vorschau zeigen"; "bwi_settings_developer_introduce_federation_preview" = "Introduction zeigen";
"bwi_settings_developer_introduce_federation_reset" = "Account Data Flag urücksetzen"; "bwi_settings_developer_introduce_federation_reset" = "Account Data Flag für Introduction zurücksetzen";
"bwi_settings_developer_announcement_federation_preview" = "Announcement zeigen";
"bwi_settings_developer_announcement_federation_reset" = "Account Data Flag für Announcement zurücksetzen";
"bwi_settings_developer_well_known" = "Well-Known"; "bwi_settings_developer_well_known" = "Well-Known";
"bwi_settings_developer_capabilities" = "Capabilities"; "bwi_settings_developer_capabilities" = "Capabilities";
"bwi_settings_developer_maintenance" = "Maintenance"; "bwi_settings_developer_maintenance" = "Maintenance";

View File

@@ -53,8 +53,10 @@
"bwi_settings_developer_unrestrict_user" = "Remove user restriction"; "bwi_settings_developer_unrestrict_user" = "Remove user restriction";
"bwi_settings_developer_unmark_banner" = "Unmark Feature Banner"; "bwi_settings_developer_unmark_banner" = "Unmark Feature Banner";
"bwi_settings_developer_introduce_federation" = "Federation"; "bwi_settings_developer_introduce_federation" = "Federation";
"bwi_settings_developer_introduce_federation_preview" = "Show preview"; "bwi_settings_developer_introduce_federation_preview" = "Show introduction preview";
"bwi_settings_developer_introduce_federation_reset" = "Reset account data flag"; "bwi_settings_developer_introduce_federation_reset" = "Reset account data flag for introduction";
"bwi_settings_developer_announcement_federation_preview" = "Show announcement preview";
"bwi_settings_developer_announcement_federation_reset" = "Reset account data flag for announcement";
"bwi_settings_developer_well_known" = "Well-Known"; "bwi_settings_developer_well_known" = "Well-Known";
"bwi_settings_developer_capabilities" = "Capabilities"; "bwi_settings_developer_capabilities" = "Capabilities";
"bwi_settings_developer_maintenance" = "Maintenance"; "bwi_settings_developer_maintenance" = "Maintenance";

View File

@@ -539,6 +539,14 @@ public class BWIL10n: NSObject {
public static var bwiSettingsDeveloper: String { public static var bwiSettingsDeveloper: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer") return BWIL10n.tr("Bwi", "bwi_settings_developer")
} }
/// Announcement zeigen
public static var bwiSettingsDeveloperAnnouncementFederationPreview: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer_announcement_federation_preview")
}
/// Account Data Flag für Announcement zurücksetzen
public static var bwiSettingsDeveloperAnnouncementFederationReset: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer_announcement_federation_reset")
}
/// MDM Config: MSG Demo /// MDM Config: MSG Demo
public static var bwiSettingsDeveloperApplyAppConfig: String { public static var bwiSettingsDeveloperApplyAppConfig: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer_apply_app_config") return BWIL10n.tr("Bwi", "bwi_settings_developer_apply_app_config")
@@ -555,6 +563,18 @@ public class BWIL10n: NSObject {
public static var bwiSettingsDeveloperCreateNewPersonalNotesRoom: String { public static var bwiSettingsDeveloperCreateNewPersonalNotesRoom: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer_create_new_personal_notes_room") return BWIL10n.tr("Bwi", "bwi_settings_developer_create_new_personal_notes_room")
} }
/// Föderation
public static var bwiSettingsDeveloperIntroduceFederation: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer_introduce_federation")
}
/// Introduction zeigen
public static var bwiSettingsDeveloperIntroduceFederationPreview: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer_introduce_federation_preview")
}
/// Account Data Flag für Introduction zurücksetzen
public static var bwiSettingsDeveloperIntroduceFederationReset: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer_introduce_federation_reset")
}
/// Key Backup /// Key Backup
public static var bwiSettingsDeveloperKeyBackup: String { public static var bwiSettingsDeveloperKeyBackup: String {
return BWIL10n.tr("Bwi", "bwi_settings_developer_key_backup") return BWIL10n.tr("Bwi", "bwi_settings_developer_key_backup")
@@ -867,6 +887,34 @@ public class BWIL10n: NSObject {
public static var integrityAlertTitle: String { public static var integrityAlertTitle: String {
return BWIL10n.tr("Bwi", "integrity_alert_title") return BWIL10n.tr("Bwi", "integrity_alert_title")
} }
/// Übergreifende sichere Kommunikation zwischen verschiedenen Organisationen
public static var introduceFederationScreen1Description: String {
return BWIL10n.tr("Bwi", "introduce_federation_screen1_description")
}
/// Föderation
public static var introduceFederationScreen1Title: String {
return BWIL10n.tr("Bwi", "introduce_federation_screen1_title")
}
/// Föderierte Personen und Räume erkennst du am Symbol mit den zwei sich überschneidenden Kreisen.
public static var introduceFederationScreen2Description: String {
return BWIL10n.tr("Bwi", "introduce_federation_screen2_description")
}
/// Kennzeichnung
public static var introduceFederationScreen2Title: String {
return BWIL10n.tr("Bwi", "introduce_federation_screen2_title")
}
/// Bestimme als Admin, welche Räume für eine Föderation zugelassen sind.
public static var introduceFederationScreen3Description: String {
return BWIL10n.tr("Bwi", "introduce_federation_screen3_description")
}
/// Individuelle Einstellung
public static var introduceFederationScreen3Title: String {
return BWIL10n.tr("Bwi", "introduce_federation_screen3_title")
}
/// Verstanden
public static var introduceFederationStart: String {
return BWIL10n.tr("Bwi", "introduce_federation_start")
}
/// Einladen /// Einladen
public static var invite: String { public static var invite: String {
return BWIL10n.tr("Bwi", "invite") return BWIL10n.tr("Bwi", "invite")

View File

@@ -303,23 +303,6 @@ class RiotSharedSettings: NSObject {
return session.setAccountData(notificationsDict, forType: "de.bwi.notifications", success: success, failure: failure) return session.setAccountData(notificationsDict, forType: "de.bwi.notifications", success: success, failure: failure)
} }
// MARK: FederationAnnouncement
// bwi: 5706 show federation announcement promt
func shouldShowFederationAnnouncement() -> Bool {
guard let notificationsDict = getAccountData(forEventType: "de.bwi.notifications") else {
return true
}
return (notificationsDict["should_show_federation_announcement"] as? Bool) ?? true
}
@discardableResult
func setFederationAnnouncement() -> MXHTTPOperation? {
var notificationsDict = getAccountData(forEventType: "de.bwi.notifications") ?? [:]
notificationsDict["should_show_federation_announcement"] = false
return session.setAccountData(notificationsDict, forType: "de.bwi.notifications", success: nil, failure: nil)
}
// MARK: - Private // MARK: - Private
private func getAccountData(forEventType eventType: String) -> [String: Any]? { private func getAccountData(forEventType eventType: String) -> [String: Any]? {
return session.accountData.accountData(forEventType: eventType) as? [String: Any] return session.accountData.accountData(forEventType: eventType) as? [String: Any]

View File

@@ -716,12 +716,6 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol {
// bwi: 5706 show federation announcement promt // bwi: 5706 show federation announcement promt
self.allChatsViewController.bwiCheckForFederationAnnouncementPromt() self.allChatsViewController.bwiCheckForFederationAnnouncementPromt()
// bwi: 5660 introduce federation // bwi: 5660 introduce federation
self.bwiShowFederationIntroduction()
}
}
private func bwiShowFederationIntroduction() {
if BWIBuildSettings.shared.showFederationIntroduction {
self.allChatsViewController.presentFederationIntroductionSheet() self.allChatsViewController.presentFederationIntroductionSheet()
} }
} }

View File

@@ -325,6 +325,10 @@ class AllChatsViewController: HomeViewController {
} }
func presentFederationIntroductionSheet() { func presentFederationIntroductionSheet() {
guard BWIBuildSettings.shared.showFederationIntroduction else {
return
}
guard BWIBuildSettings.shared.isFederationEnabled else { guard BWIBuildSettings.shared.isFederationEnabled else {
return return
} }
@@ -519,15 +523,20 @@ class AllChatsViewController: HomeViewController {
// bwi: 5706 show federation announcement promt // bwi: 5706 show federation announcement promt
func bwiCheckForFederationAnnouncementPromt() { func bwiCheckForFederationAnnouncementPromt() {
if self.mainSession.homeserverWellknown.shouldShowFederationAnnouncement() { guard self.mainSession.homeserverWellknown.shouldShowFederationAnnouncement() else {
let sharedSettings = RiotSharedSettings(session: self.mainSession) return
if sharedSettings.shouldShowFederationAnnouncement() { }
let viewController = FederationAnnouncementSheet().makeViewController()
viewController.modalPresentationStyle = .formSheet let notificationService = BWIAccountNotificationService(mxSession: self.mainSession)
self.present(viewController, animated: true) { guard notificationService.showFederationAnnouncementFlag() else {
sharedSettings.setFederationAnnouncement() return
} }
}
let viewController = UIHostingController(rootView: FederationAnnouncementView().environmentObject(BWIThemeService.shared))
viewController.isModalInPresentation = true
viewController.modalPresentationStyle = .formSheet
present(viewController, animated: true) {
notificationService.setShowFederationAnnouncementFlag(false)
} }
} }

View File

@@ -37,6 +37,7 @@ struct DeveloperSettingsView: View {
@State private var showAlertBirthdayCampaign = false @State private var showAlertBirthdayCampaign = false
@State private var permalinkPrefix: String? = UserDefaults.standard.string(forKey: "bwi_permalink_prefix") @State private var permalinkPrefix: String? = UserDefaults.standard.string(forKey: "bwi_permalink_prefix")
@State private var showIntroduceFederation = false @State private var showIntroduceFederation = false
@State private var showAnnouncementFederation = false
var body: some View { var body: some View {
Form { Form {
@@ -83,6 +84,23 @@ struct DeveloperSettingsView: View {
} }
} }
SwiftUI.Section(header: Text(BWIL10n.bwiSettingsDeveloperIntroduceFederation)) { SwiftUI.Section(header: Text(BWIL10n.bwiSettingsDeveloperIntroduceFederation)) {
Button(action: { showAnnouncementFederation = true }) {
Text(BWIL10n.bwiSettingsDeveloperAnnouncementFederationPreview)
.foregroundColor(Color(themeService.theme.tintColor))
.font(.system(size: 17))
}
.sheet(isPresented: $showAnnouncementFederation) {
IntroduceFederationView()
.interactiveDismissDisabled()
.environmentObject(BWIThemeService.shared)
}
if let session = session {
Button(action: { BWIAccountNotificationService(mxSession: session).setShowFederationAnnouncementFlag(true) }) {
Text(BWIL10n.bwiSettingsDeveloperAnnouncementFederationReset)
.foregroundColor(Color(themeService.theme.tintColor))
.font(.system(size: 17))
}
}
Button(action: { showIntroduceFederation = true }) { Button(action: { showIntroduceFederation = true }) {
Text(BWIL10n.bwiSettingsDeveloperIntroduceFederationPreview) Text(BWIL10n.bwiSettingsDeveloperIntroduceFederationPreview)
.foregroundColor(Color(themeService.theme.tintColor)) .foregroundColor(Color(themeService.theme.tintColor))

View File

@@ -17,34 +17,9 @@
import SwiftUI import SwiftUI
@objcMembers class FederationAnnouncementSheet: NSObject {
@Published var theme: Theme
override init() {
theme = ThemeService.shared().theme
}
func makeViewController() -> UIViewController {
registerThemeServiceDidChangeThemeNotification()
return UIHostingController(rootView: FederationAnnouncementView(theme: Binding(get: {
return self.theme
}, set: { newTheme in
self.theme = newTheme
})))
}
private func registerThemeServiceDidChangeThemeNotification() {
NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil)
}
@objc private func themeDidChange() {
self.theme = ThemeService.shared().theme
}
}
struct FederationAnnouncementView: View { struct FederationAnnouncementView: View {
@Environment(\.dismiss) var dismissView @Environment(\.dismiss) var dismissView
@Binding var theme: Theme @EnvironmentObject var themeService: BWIThemeService
let imageStackScale = 0.30 let imageStackScale = 0.30
let imageStackShift = 5.0 let imageStackShift = 5.0
@@ -69,7 +44,7 @@ struct FederationAnnouncementView: View {
ZStack(alignment: .center) { ZStack(alignment: .center) {
Circle() Circle()
.fill(Color(theme.colors.quinaryContent)) .fill(Color(themeService.theme.colors.quinaryContent))
.padding(outerLineWith) .padding(outerLineWith)
.offset(x:((getImageSize(width: geo.size.width, height: geo.size.height) * imageStackScale) / imageStackShift)) .offset(x:((getImageSize(width: geo.size.width, height: geo.size.height) * imageStackScale) / imageStackShift))
@@ -78,10 +53,10 @@ struct FederationAnnouncementView: View {
.aspectRatio(contentMode: .fill) .aspectRatio(contentMode: .fill)
.clipShape(Circle()) .clipShape(Circle())
.padding(innerLineWith) .padding(innerLineWith)
.background(Color(theme.colors.quinaryContent)) .background(Color(themeService.theme.colors.quinaryContent))
.clipShape(Circle()) .clipShape(Circle())
.padding(outerLineWith) .padding(outerLineWith)
.background(Color(theme.colors.background)) .background(Color(themeService.theme.colors.background))
.clipShape(Circle()) .clipShape(Circle())
.offset(x:-((getImageSize(width: geo.size.width, height: geo.size.height) * imageStackScale) / imageStackShift)) .offset(x:-((getImageSize(width: geo.size.width, height: geo.size.height) * imageStackScale) / imageStackShift))
} }
@@ -92,17 +67,17 @@ struct FederationAnnouncementView: View {
.font(.system(size: 24).bold()) .font(.system(size: 24).bold())
.multilineTextAlignment(.center) .multilineTextAlignment(.center)
.lineLimit(nil) .lineLimit(nil)
.foregroundColor(Color(theme.colors.primaryContent)) .foregroundColor(Color(themeService.theme.colors.primaryContent))
Text(announcementText) Text(announcementText)
.font(Font(theme.fonts.subheadline)) .font(Font(themeService.theme.fonts.subheadline))
.multilineTextAlignment(.center) .multilineTextAlignment(.center)
.lineLimit(nil) .lineLimit(nil)
.foregroundColor(Color(theme.colors.primaryContent)) .foregroundColor(Color(themeService.theme.colors.primaryContent))
Text(BWIL10n.federationAnnouncementSubText) Text(BWIL10n.federationAnnouncementSubText)
.font(Font(theme.fonts.subheadline)) .font(Font(themeService.theme.fonts.subheadline))
.multilineTextAlignment(.center) .multilineTextAlignment(.center)
.lineLimit(nil) .lineLimit(nil)
.foregroundColor(Color(theme.colors.secondaryContent)) .foregroundColor(Color(themeService.theme.colors.secondaryContent))
} }
.padding(spacing) .padding(spacing)
@@ -121,7 +96,7 @@ struct FederationAnnouncementView: View {
} }
.interactiveDismissDisabled() .interactiveDismissDisabled()
.frame(width: geo.size.width, height: geo.size.height) .frame(width: geo.size.width, height: geo.size.height)
.background(Color(theme.colors.background)) .background(Color(themeService.theme.colors.background))
} }
} }

View File

@@ -48,12 +48,12 @@ import Foundation
if let federationAnnouncementVal = dict[AccountNotifications.CodingKeys.federationAnnouncement.rawValue] as? Bool { if let federationAnnouncementVal = dict[AccountNotifications.CodingKeys.federationAnnouncement.rawValue] as? Bool {
federationAnnouncement = federationAnnouncementVal federationAnnouncement = federationAnnouncementVal
} else { } else {
federationAnnouncement = false federationAnnouncement = true
} }
if let federationIntroductionVal = dict[AccountNotifications.CodingKeys.federationIntroduction.rawValue] as? Bool { if let federationIntroductionVal = dict[AccountNotifications.CodingKeys.federationIntroduction.rawValue] as? Bool {
federationIntroduction = federationIntroductionVal federationIntroduction = federationIntroductionVal
} else { } else {
federationIntroduction = false federationIntroduction = true
} }
} }
} }
@@ -85,6 +85,7 @@ import Foundation
session.setAccountData(notificationsDict, forType: AccountDataTypes.notifications, success: nil, failure: nil) session.setAccountData(notificationsDict, forType: AccountDataTypes.notifications, success: nil, failure: nil)
} }
// bwi: 5706 show federation announcement promt
func showFederationAnnouncementFlag() -> Bool { func showFederationAnnouncementFlag() -> Bool {
guard let notificationsDict = session.accountData.accountData(forEventType: AccountDataTypes.notifications) as? [String: Any] else { guard let notificationsDict = session.accountData.accountData(forEventType: AccountDataTypes.notifications) as? [String: Any] else {
return true return true
@@ -94,6 +95,7 @@ import Foundation
return notifications.federationAnnouncement return notifications.federationAnnouncement
} }
// bwi: 5706 show federation announcement promt
func setShowFederationAnnouncementFlag(_ value: Bool) { func setShowFederationAnnouncementFlag(_ value: Bool) {
var notificationsDict = session.accountData.accountData(forEventType: AccountDataTypes.notifications) ?? [:] var notificationsDict = session.accountData.accountData(forEventType: AccountDataTypes.notifications) ?? [:]
notificationsDict[AccountNotifications.CodingKeys.federationAnnouncement.rawValue] = value notificationsDict[AccountNotifications.CodingKeys.federationAnnouncement.rawValue] = value

View File

@@ -75,6 +75,24 @@ public extension MXWellKnown {
return false return false
} }
} }
@objc func shouldShowFederationAnnouncement() -> Bool {
do {
guard let bwiDict = self.jsonDictionary()["de.bwi"] as? [String : Any] else {
return false
}
let bwi = try WellknownBWI(dict: bwiDict)
if let federation = bwi.federation {
return federation.showAnnouncement ?? false
} else {
return false
}
}
catch {
return false
}
}
// returns true if there is a valid url or no url, only the case "is url" but not valid is wrong // returns true if there is a valid url or no url, only the case "is url" but not valid is wrong
@objc func isValidDataPrivacyURL() -> Bool { @objc func isValidDataPrivacyURL() -> Bool {
@@ -122,22 +140,4 @@ public extension MXWellKnown {
return nil return nil
} }
} }
@objc func shouldShowFederationAnnouncement() -> Bool {
do {
guard let bwiDict = self.jsonDictionary()["de.bwi"] as? [String : Any] else {
return false
}
let bwi = try WellknownBWI(dict: bwiDict)
if let federation = bwi.federation {
return federation.showAnnouncement ?? false
} else {
return false
}
}
catch {
return false
}
}
} }

View File

@@ -36,8 +36,13 @@ struct WellknownBWI: Decodable {
} }
struct WellknownFederation: Decodable { struct WellknownFederation: Decodable {
// show announcement (1 screen)
let showAnnouncement: Bool? let showAnnouncement: Bool?
// show federation tutorial (3 screens)
let showIntroduction: Bool? let showIntroduction: Bool?
// enables the federation feature for the app - show federation views, activate invitation rules, show federation settings
let enable: Bool? let enable: Bool?
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {

View File

@@ -1,42 +0,0 @@
//
/*
* Copyright (c) 2024 BWI GmbH
*
* 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
struct WellknownFederation {
/// show federation announcement
let showAnnouncement: Bool?
/// show federation tutorial (3 screens)
let showIntroduction: Bool
/// enables the federation feature for the app - show federation views, activate invitation rules, show federation settings
let enable: Bool
init(dict: [String: Any]) throws {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: [])
let decoder = JSONDecoder()
self = try decoder.decode(Self.self, from: jsonData)
}
}
extension WellknownFederation: Decodable {
enum CodingKeys: String, CodingKey {
case showAnnouncement = "show_announcement"
case showIntroduction = "show_introduction"
case enable = "enable"
}
}