Skip to content

Commit 34085ea

Browse files
committed
Add accessibility improvements to Crypto views
1 parent f40293b commit 34085ea

7 files changed

Lines changed: 91 additions & 23 deletions

File tree

RIADigiDoc/UI/Component/Container/Crypto/CryptoDataFilesLockedSection.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ struct CryptoDataFilesLockedSection: View {
4040
Text(verbatim: languageSettings.localized("Crypto files encrypted"))
4141
.font(typography.bodyMedium)
4242
.fixedSize(horizontal: false, vertical: true)
43-
.lineLimit(4)
44-
.truncationMode(.middle)
43+
.lineLimit(nil)
44+
.minimumScaleFactor(0.5)
4545
.multilineTextAlignment(TextAlignment.leading)
4646
.accessibilityLabel(
4747
Text(

RIADigiDoc/UI/Component/Container/Crypto/EncryptView.swift

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import UtilsLib
2525

2626
struct EncryptView: View {
2727
@Environment(\.presentationMode) var presentationMode
28+
@Environment(\.accessibilityVoiceOverEnabled) private var voiceOverEnabled
2829
@AppTheme private var theme
2930
@AppTypography private var typography
3031
@Environment(NavigationPathManager.self) private var pathManager
@@ -513,18 +514,27 @@ struct EncryptView: View {
513514
.animation(.easeInOut, value: showRenameModal)
514515
.onChange(of: viewModel.errorMessage) { _, error in
515516
guard let error else { return }
516-
Toast.show(
517-
languageSettings.localized(error.key, [error.args.joined(separator: ", ")])
518-
)
517+
let localizedMessage = languageSettings
518+
.localized(error.key, [error.args.joined(separator: ", ")])
519+
Toast.show(localizedMessage)
520+
521+
if voiceOverEnabled {
522+
AccessibilityUtil.announceMessage(localizedMessage)
523+
}
524+
519525
viewModel.resetErrorMessage()
520526
encryptionButtonEnabled = true
521527
}
522528
.onChange(of: viewModel.successMessage) { _, message in
523529
guard let message else { return }
524-
Toast.show(
525-
languageSettings.localized(message.key, [message.args.joined(separator: ", ")]),
526-
type: .success
527-
)
530+
let localizedMessage = languageSettings
531+
.localized(message.key, [message.args.joined(separator: ", ")])
532+
Toast.show(localizedMessage, type: .success)
533+
534+
if voiceOverEnabled {
535+
AccessibilityUtil.announceMessage(localizedMessage)
536+
}
537+
528538
viewModel.resetSuccessMessage()
529539
}
530540
.onChange(of: viewModel.navigateToNestedSignedContainerView) { _, isNavigating in

RIADigiDoc/UI/Component/Container/Crypto/Recipient/EncryptRecipientView.swift

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import CommonsLib
2424
import CryptoObjCWrapper
2525

2626
struct EncryptRecipientView: View {
27+
@Environment(\.accessibilityVoiceOverEnabled) private var voiceOverEnabled
2728
@Environment(\.dismiss) private var dismiss
2829
@Environment(LanguageSettings.self) private var languageSettings
2930

@@ -32,6 +33,9 @@ struct EncryptRecipientView: View {
3233
@AppTheme private var theme
3334
@AppTypography private var typography
3435

36+
@AccessibilityFocusState private var isTitleFocused: Bool
37+
@AccessibilityFocusState private var isSearchFieldFocused: Bool
38+
@AccessibilityFocusState private var focusedRecipientIndex: Int?
3539
@FocusState private var isSearchFocused: Bool
3640
@State private var isSearchExpanded = false
3741

@@ -134,8 +138,16 @@ struct EncryptRecipientView: View {
134138
.foregroundStyle(theme.onSurface)
135139
.font(typography.headlineSmall)
136140
.padding(.top, Dimensions.Padding.SPadding)
141+
.minimumScaleFactor(0.5)
137142
.accessibilityHeading(.h1)
138143
.accessibilityAddTraits([.isHeader])
144+
.accessibilityFocused($isTitleFocused)
145+
.accessibilitySortPriority(3)
146+
.onAppear {
147+
if noSearchResults {
148+
isTitleFocused = true
149+
}
150+
}
139151
}
140152
HStack {
141153
Image(systemName: "magnifyingglass")
@@ -149,31 +161,56 @@ struct EncryptRecipientView: View {
149161
.submitLabel(.done)
150162
.textInputAutocapitalization(.never)
151163
.autocorrectionDisabled(true)
164+
.accessibilityFocused($isSearchFieldFocused)
152165
.focused($isSearchFocused)
153166
.onChange(of: isSearchFocused) { _, newValue in
154167
isSearchExpanded = newValue
155168
}
156169
.onChange(of: viewModel.searchText) {
157170
viewModel.handleSearchTextChange()
158171
}
172+
.onChange(of: filteredRecipients) { _, newValue in
173+
guard !newValue.isEmpty else { return }
174+
175+
Task { @MainActor in
176+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
177+
focusedRecipientIndex = 0
178+
}
179+
}
180+
}
159181
.onSubmit {
160182
if viewModel.searchText.allSatisfy(\.isNumber) &&
161183
viewModel.searchText.count == 11 &&
162184
!PersonalCodeValidator.isPersonalCodeValid(viewModel.searchText) {
163-
Toast.show(languageSettings.localized("Personal code is not valid"))
185+
let personalCodeNotValidMessage = languageSettings.localized(
186+
"Personal code is not valid"
187+
)
188+
189+
Toast.show(personalCodeNotValidMessage)
190+
191+
if voiceOverEnabled {
192+
AccessibilityUtil.announceMessage(
193+
personalCodeNotValidMessage
194+
)
195+
}
164196
return
165197
}
166198

167199
Task {
168200
await viewModel.loadRecipients()
169201

170-
if noRecipients {
171-
showNoRecipientsFoundMessage = true
172-
}
202+
await MainActor.run {
203+
isTitleFocused = false
173204

174-
isSearchFocused = true
205+
if voiceOverEnabled && noRecipients {
206+
AccessibilityUtil.announceMessage(
207+
languageSettings.localized("No recipients found")
208+
)
209+
}
210+
}
175211
}
176212
}
213+
.accessibilitySortPriority(1)
177214

178215
if isSearchExpanded {
179216
Button(
@@ -204,6 +241,7 @@ struct EncryptRecipientView: View {
204241
)
205242
.padding(.top, Dimensions.Padding.LPadding)
206243
.padding(.bottom, Dimensions.Padding.SPadding)
244+
207245
ScrollView {
208246
if noSearchResults && !isSearchExpanded {
209247
VStack {
@@ -229,8 +267,10 @@ struct EncryptRecipientView: View {
229267
addedRecipientsSection
230268
}
231269
}
270+
.accessibilitySortPriority(filteredRecipients.isEmpty ? 2 : 0)
232271
}
233272
.padding(.horizontal, Dimensions.Padding.SPadding)
273+
.accessibilityElement(children: .contain)
234274

235275
if showRemoveRecipientModal {
236276
ConfirmModalView(
@@ -298,6 +338,8 @@ struct EncryptRecipientView: View {
298338
.padding(Dimensions.Padding.MPadding)
299339
.accessibilityElement(children: .ignore)
300340
.accessibilityLabel(encryptLabel.lowercased())
341+
.accessibilityAddTraits([.isButton])
342+
301343
.accessibilityIdentifier("bottomEncryptButton")
302344
}
303345
.onAppear {
@@ -338,6 +380,7 @@ struct EncryptRecipientView: View {
338380
.contentShape(Rectangle())
339381
.buttonStyle(.plain)
340382
.background(theme.surface)
383+
.accessibilityFocused($focusedRecipientIndex, equals: index)
341384
}
342385

343386
private func addedRecipientRow(index: Int, item: Addressee) -> some View {

RIADigiDoc/UI/Component/Container/Crypto/Recipient/RecipientsView.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,9 @@ struct RecipientsView: View {
108108
.fixedSize(horizontal: false, vertical: true)
109109
.multilineTextAlignment(.leading)
110110
.accessibilityLabel({
111-
if recipientIndex != 0 {
112-
let prefix = languageSettings.localized("Recipient")
113-
let name = nameText.lowercased()
114-
return Text(verbatim: "\(prefix) \(recipientIndex), \(name)")
115-
} else {
116-
return Text(verbatim: nameText.lowercased())
117-
}
111+
let prefix = languageSettings.localized("Recipient")
112+
let name = nameText.lowercased()
113+
return Text(verbatim: "\(prefix) \(recipientIndex + 1), \(name)")
118114
}())
119115

120116
let certType = recipientUtil.getRecipientCertTypeText(certType: recipient.certType)
@@ -142,7 +138,7 @@ struct RecipientsView: View {
142138
.frame(width: Dimensions.Icon.IconSizeXXS, height: Dimensions.Icon.IconSizeXXS)
143139
.foregroundStyle(theme.onSurface)
144140
.accessibilityLabel(
145-
Text(verbatim: languageSettings.localized("Remove container"))
141+
Text(verbatim: languageSettings.localized("Remove recipient"))
146142
)
147143
})
148144
}

RIADigiDoc/UI/Component/HomeView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ struct HomeView: View {
303303
if !files.isEmpty {
304304
isFileOpeningLoading = true
305305
viewModel.isImporting = false
306+
viewModel.setFileOpeningMethod(.all)
306307
viewModel.setChosenFiles(.success(files))
307308
}
308309
}

RIADigiDoc/ViewModel/EncryptViewModel.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,19 @@ class EncryptViewModel: EncryptViewModelProtocol, Loggable {
723723
isSivaConfirmed: true
724724
)
725725

726+
let signedContainerName = URL(fileURLWithPath: containerName)
727+
.deletingPathExtension()
728+
.appendingPathExtension(Constants.Extension.Default)
729+
.lastPathComponent
730+
731+
let renamedContainer = try await signedContainer.renameContainer(
732+
to: signedContainerName
733+
)
734+
726735
sharedContainerViewModel.setCryptoContainer(nil)
727736
sharedContainerViewModel.clearContainers()
728737
sharedContainerViewModel.setAddedFilesCount(addedFiles: dataFileURLs.count)
729-
sharedContainerViewModel.setSignedContainer(signedContainer)
738+
sharedContainerViewModel.setSignedContainer(renamedContainer)
730739

731740
return true
732741
}

RIADigiDoc/ViewModel/SigningViewModel.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,15 @@ class SigningViewModel: SigningViewModelProtocol, Loggable {
609609
let cryptoContainer = try await
610610
CryptoContainer.openOrCreate(dataFiles: dataFileURLs)
611611

612+
let cryptoContainerName = URL(fileURLWithPath: containerName)
613+
.deletingPathExtension()
614+
.appendingPathExtension(Constants.Extension.DefaultCrypto)
615+
.lastPathComponent
616+
617+
try await cryptoContainer.renameContainer(
618+
to: cryptoContainerName
619+
)
620+
612621
sharedContainerViewModel.setSignedContainer(nil)
613622
sharedContainerViewModel.clearContainers()
614623
sharedContainerViewModel.setAddedFilesCount(addedFiles: dataFileURLs.count)

0 commit comments

Comments
 (0)