Feature/4772 add accessibility declaration

This commit is contained in:
JanNiklas Grabowski
2023-06-14 06:14:17 +00:00
committed by Frank Rotermund
parent 42214cad99
commit f8348a66d0
11 changed files with 187 additions and 1 deletions

View File

@@ -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
}

View File

@@ -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";

View File

@@ -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";

View File

@@ -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)

View File

@@ -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
{

View File

@@ -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 {

View File

@@ -54,6 +54,8 @@ class AuthenticationLoginViewModel: AuthenticationLoginViewModelType, Authentica
Task { await callback?(.qrLogin) }
case .register:
Task { await callback?(.register) }
case .accessibilityDeclaration:
Task { await callback?(.accessibilityDeclaration) }
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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())
}
}
}

View 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
}
}
}