mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-16 06:28:27 +02:00
Feature/4772 add accessibility declaration
This commit is contained in:
committed by
Frank Rotermund
parent
42214cad99
commit
f8348a66d0
@@ -622,6 +622,13 @@ class BWIBuildSettings: NSObject {
|
||||
// MARK: Sessions Manager
|
||||
var enableNewSessionManagerByDefault = false
|
||||
|
||||
// MARK: Accessibility declaration
|
||||
// bwi flag for showing accessibility declaration on login screen and in settings
|
||||
var bwiShowAccessibilityDeclaration = false
|
||||
// internal markdown file for accessibility declaration in en and de.
|
||||
var accessibilityDeclarationFileDe = ""
|
||||
var accessibilityDeclarationFileEn = ""
|
||||
|
||||
// MARK: Voice Broadcast
|
||||
var enableLabFeatureVoiceBroadcasts = false
|
||||
}
|
||||
|
||||
@@ -620,3 +620,6 @@
|
||||
// MARK: - Voice Over
|
||||
"textfield_reveal_secret" = "Texteingabe anzeigen";
|
||||
"textfield_hide_secret" = "Texteingabe verbergen";
|
||||
|
||||
// MARK: - Accessibility declaration
|
||||
"bwi_accessibility_declaration_button_title" = "Barrierefreiheitserklärung";
|
||||
|
||||
@@ -531,3 +531,5 @@
|
||||
"textfield_reveal_secret" = "reveal text input";
|
||||
"textfield_hide_secret" = "hide text input";
|
||||
|
||||
// MARK: - Accessibility declaration
|
||||
"bwi_accessibility_declaration_button_title" = "Accessibility declaration";
|
||||
|
||||
@@ -99,6 +99,10 @@ public class BWIL10n: NSObject {
|
||||
public static var bumAutheticationTitle: String {
|
||||
return BWIL10n.tr("Bwi", "bum_authetication_title")
|
||||
}
|
||||
/// Barrierefreiheitserklärung
|
||||
public static var bwiAccessibilityDeclarationButtonTitle: String {
|
||||
return BWIL10n.tr("Bwi", "bwi_accessibility_declaration_button_title")
|
||||
}
|
||||
/// Wir brauchen Deine Hilfe, um Fehler im %@ besser analysieren zu können. Dazu würden wir gerne anonymisierte Diagnosedaten erfassen. Es werden keine Daten an Dritte übermittelt. Details findest Du in der Datenschutzerklärung.\n\nFalls Du nicht mehr mithelfen möchtest, kannst Du dies in den Einstellungen jederzeit wieder deaktivieren.\n\nMöchtest du bei der Fehler-Analyse unterstützen?
|
||||
public static func bwiAnalyticsAlertBody(_ p1: String) -> String {
|
||||
return BWIL10n.tr("Bwi", "bwi_analytics_alert_body", p1)
|
||||
|
||||
@@ -216,7 +216,8 @@ typedef NS_ENUM(NSUInteger, ABOUT)
|
||||
ABOUT_MARK_ALL_AS_READ_INDEX,
|
||||
ABOUT_CLEAR_CACHE_INDEX,
|
||||
ABOUT_REPORT_BUG_INDEX,
|
||||
ABOUT_NETIQUETTE_INDEX
|
||||
ABOUT_NETIQUETTE_INDEX,
|
||||
ABOUT_ACCESSIBILITY_DECLARATION_INDEX
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, LABS_ENABLE)
|
||||
@@ -725,6 +726,10 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
{
|
||||
[sectionAbout addRowWithTag:ABOUT_PRIVACY_INDEX];
|
||||
}
|
||||
// bwi 4772 - show accessibility declaration
|
||||
if (BWIBuildSettings.shared.bwiShowAccessibilityDeclaration) {
|
||||
[sectionAbout addRowWithTag:ABOUT_ACCESSIBILITY_DECLARATION_INDEX];
|
||||
}
|
||||
[sectionAbout addRowWithTag:ABOUT_THIRD_PARTY_INDEX];
|
||||
sectionAbout.headerTitle = VectorL10n.settingsAbout;
|
||||
|
||||
@@ -2837,6 +2842,16 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
|
||||
cell = privacyPolicyCell;
|
||||
}
|
||||
else if (row == ABOUT_ACCESSIBILITY_DECLARATION_INDEX)
|
||||
{
|
||||
MXKTableViewCell *accessibilityDeclarationCell = [self getDefaultTableViewCell:tableView];
|
||||
|
||||
accessibilityDeclarationCell.textLabel.text = [BWIL10n bwiAccessibilityDeclarationButtonTitle];
|
||||
|
||||
[accessibilityDeclarationCell vc_setAccessoryDisclosureIndicatorWithCurrentTheme];
|
||||
|
||||
cell = accessibilityDeclarationCell;
|
||||
}
|
||||
else if (row == ABOUT_THIRD_PARTY_INDEX)
|
||||
{
|
||||
MXKTableViewCell *thirdPartyCell = [self getDefaultTableViewCell:tableView];
|
||||
@@ -3305,6 +3320,10 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
{
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:BWIBuildSettings.shared.applicationPrivacyPolicyUrlString] options:@{} completionHandler:nil];
|
||||
}
|
||||
else if (row == ABOUT_ACCESSIBILITY_DECLARATION_INDEX)
|
||||
{
|
||||
[self showAccessibilityDeclaration];
|
||||
}
|
||||
else if (row == ABOUT_THIRD_PARTY_INDEX)
|
||||
{
|
||||
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:@"third_party_licenses" ofType:@"html" inDirectory:nil];
|
||||
@@ -4493,6 +4512,12 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
|
||||
UIViewController *developerSettingsViewController = [DeveloperSettingsViewController makeViewControllerWithSession:self.mainSession];
|
||||
[self pushViewController:developerSettingsViewController];
|
||||
}
|
||||
|
||||
- (void)showAccessibilityDeclaration
|
||||
{
|
||||
UIViewController *accessibilityDeclarationViewController = [AccessibilityDeclarationViewController makeViewController];
|
||||
[self pushViewController:accessibilityDeclarationViewController];
|
||||
}
|
||||
|
||||
- (void)showPersonalStateSettings
|
||||
{
|
||||
|
||||
@@ -35,6 +35,8 @@ enum AuthenticationLoginViewModelResult: CustomStringConvertible {
|
||||
case qrLogin
|
||||
/// bwi: register info
|
||||
case register
|
||||
/// bwi #4772: accessibility declaration
|
||||
case accessibilityDeclaration
|
||||
|
||||
/// A string representation of the result, ignoring any associated values that could leak PII.
|
||||
var description: String {
|
||||
@@ -55,6 +57,8 @@ enum AuthenticationLoginViewModelResult: CustomStringConvertible {
|
||||
return "qrLogin"
|
||||
case .register:
|
||||
return "register"
|
||||
case .accessibilityDeclaration:
|
||||
return "accessibilityDeclaration"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,6 +122,8 @@ enum AuthenticationLoginViewAction {
|
||||
case qrLogin
|
||||
/// bwi: register info
|
||||
case register
|
||||
/// bwi #4772: accessibility declaration
|
||||
case accessibilityDeclaration
|
||||
}
|
||||
|
||||
enum AuthenticationLoginErrorType: Hashable {
|
||||
|
||||
@@ -54,6 +54,8 @@ class AuthenticationLoginViewModel: AuthenticationLoginViewModelType, Authentica
|
||||
Task { await callback?(.qrLogin) }
|
||||
case .register:
|
||||
Task { await callback?(.register) }
|
||||
case .accessibilityDeclaration:
|
||||
Task { await callback?(.accessibilityDeclaration) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,8 @@ final class AuthenticationLoginCoordinator: Coordinator, Presentable {
|
||||
case .register:
|
||||
// bwi: show info alert
|
||||
self.authenticationLoginViewModel.displayInfoAlert(.register)
|
||||
case .accessibilityDeclaration:
|
||||
self.showAccessibilityDeclaration()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,6 +327,13 @@ final class AuthenticationLoginCoordinator: Coordinator, Presentable {
|
||||
}
|
||||
}
|
||||
|
||||
/// bwi #4772 show accessibility declaration
|
||||
@MainActor private func showAccessibilityDeclaration() {
|
||||
MXLog.debug("[AuthenticationLoginCoordinator] showAccessibilityDeclaration")
|
||||
let accessibilityDeclarationViewController = AccessibilityDeclarationViewController.makeViewController()
|
||||
navigationRouter.push(accessibilityDeclarationViewController, animated: true, popCompletion: nil)
|
||||
}
|
||||
|
||||
/// Updates the view model to reflect any changes made to the homeserver.
|
||||
@MainActor private func updateViewModel() {
|
||||
let homeserver = authenticationService.state.homeserver
|
||||
|
||||
@@ -93,6 +93,13 @@ struct AuthenticationLoginScreen: View {
|
||||
.readableFrame()
|
||||
.padding(.horizontal, 16)
|
||||
}
|
||||
|
||||
if BWIBuildSettings.shared.bumLoginFlowLayout && BWIBuildSettings.shared.bwiShowAccessibilityDeclaration {
|
||||
accessibilityDeclaration
|
||||
.frame(alignment: .bottom)
|
||||
.padding(.bottom, 10)
|
||||
}
|
||||
|
||||
if BWIBuildSettings.shared.bumLoginFlowLayout {
|
||||
dataPrivacyForm
|
||||
.frame(alignment: .bottom)
|
||||
@@ -305,6 +312,19 @@ struct AuthenticationLoginScreen: View {
|
||||
return BWIBuildSettings.shared.bwiLoginFlowLayout ? BWIL10n.authUserIdPlaceholder : BWIL10n.authenticationLoginUsername
|
||||
}
|
||||
}
|
||||
|
||||
// bwi: Accessibility declaration
|
||||
var accessibilityDeclaration: some View {
|
||||
Button(action: {
|
||||
viewModel.send(viewAction: .accessibilityDeclaration)
|
||||
}, label: {
|
||||
Text(BWIL10n.bwiAccessibilityDeclarationButtonTitle)
|
||||
.font(theme.fonts.footnote)
|
||||
.foregroundColor(.blue)
|
||||
.underline()
|
||||
})
|
||||
.padding([.horizontal], 20)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
/*
|
||||
* Copyright (c) 2023 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 SwiftUI
|
||||
|
||||
@objcMembers class AccessibilityDeclarationViewController: NSObject {
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
class func makeViewController() -> UIViewController {
|
||||
var accessibilityDeclarationFilePath: URL? = nil
|
||||
if !BWIBuildSettings.shared.accessibilityDeclarationFileDe.isEmpty && Bundle.main.preferredLocalizations[0].elementsEqual("de") {
|
||||
accessibilityDeclarationFilePath = Bundle.main.url(forResource: BWIBuildSettings.shared.accessibilityDeclarationFileDe, withExtension: "md")
|
||||
} else if !BWIBuildSettings.shared.accessibilityDeclarationFileEn.isEmpty {
|
||||
accessibilityDeclarationFilePath = Bundle.main.url(forResource: BWIBuildSettings.shared.accessibilityDeclarationFileEn, withExtension: "md")
|
||||
}
|
||||
|
||||
if let url = accessibilityDeclarationFilePath {
|
||||
guard let string = try? String(contentsOf: url) else {
|
||||
return UIHostingController(rootView: EmptyView())
|
||||
}
|
||||
let vc = UIHostingController(rootView: MarkDownView(markdownString: string))
|
||||
vc.title = BWIL10n.bwiAccessibilityDeclarationButtonTitle
|
||||
vc.view.backgroundColor = ThemeService.shared().theme.backgroundColor
|
||||
vc.navigationItem.largeTitleDisplayMode = .never
|
||||
return vc
|
||||
} else {
|
||||
return UIHostingController(rootView: EmptyView())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
62
bwi/MarkDown/MarkDownView.swift
Normal file
62
bwi/MarkDown/MarkDownView.swift
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
/*
|
||||
* Copyright (c) 2023 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 SwiftUI
|
||||
import Down
|
||||
|
||||
struct MarkDownView: View {
|
||||
var markdownString: String
|
||||
@State var labelHeight: CGFloat = .zero
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geometry in
|
||||
ScrollView(.vertical) {
|
||||
UIMarkDownWrapper(markDownString: markdownString, height: $labelHeight)
|
||||
.frame(width: geometry.size.width - 20)
|
||||
.frame(minHeight: labelHeight)
|
||||
.padding(10)
|
||||
}
|
||||
.background(Color(ThemeService.shared().theme.backgroundColor))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct UIMarkDownWrapper: UIViewRepresentable {
|
||||
var markDownString: String
|
||||
@Binding var height: CGFloat
|
||||
|
||||
func makeUIView(context: Context) -> UILabel {
|
||||
let label = UILabel(frame: .zero)
|
||||
label.numberOfLines = 0
|
||||
label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||
return label
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: UILabel, context: Context) {
|
||||
let down = Down(markdownString: markDownString)
|
||||
|
||||
guard let attributedString = try? down.toAttributedString() else { return }
|
||||
let mutableString = NSMutableAttributedString(attributedString: attributedString)
|
||||
mutableString.addAttributes([.foregroundColor: ThemeService.shared().theme.textPrimaryColor], range: NSRange(location: 0, length: attributedString.length))
|
||||
|
||||
uiView.attributedText = mutableString
|
||||
DispatchQueue.main.async {
|
||||
height = uiView.sizeThatFits(CGSize(width: uiView.bounds.width, height: CGFloat.greatestFiniteMagnitude)).height
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user