Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct IdCardActionView: View {
isIdCardActionMessageFocused = true
}
}
.accessibilityElement(children: .combine)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ struct IdCardInputView: View {
@AppTheme private var theme
@AppTypography private var typography

@AccessibilityFocusState private var isActionMessageFocused: Bool

let personIdentifier: String
@Binding var pinNumber: String
@Binding var pinError: String
Expand Down Expand Up @@ -73,6 +75,7 @@ struct IdCardInputView: View {
Text(verbatim: actionMessage)
.font(typography.labelLarge)
.foregroundStyle(theme.onSurfaceVariant)
.accessibilityFocused($isActionMessageFocused)

Text(verbatim: personIdentifier)
.font(typography.bodyLarge)
Expand All @@ -97,6 +100,11 @@ struct IdCardInputView: View {
.foregroundStyle(theme.error)
}
}
.onAppear {
DispatchQueue.main.async {
isActionMessageFocused = true
}
}
}
}

Expand Down
28 changes: 16 additions & 12 deletions RIADigiDoc/UI/Component/Container/Signing/IdCard/IdCardView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,6 @@ struct IdCardView: View {
await viewModel.stopDiscoveringReaders()
cancelIdCardAction()
resetIdCardAction()
isInProgress = false
isShowingPinView = false
isShowingLoadingView = false

onSuccessDecrypt(container)
dismiss()
Expand Down Expand Up @@ -239,6 +236,7 @@ struct IdCardView: View {
icon: "ic_m3_smart_card_reader_48pt_wght400",
message: $idCardActionMessage
)
.accessibilityHidden(!isInProgress)
} else if isInProgress && isShowingPinView {
IdCardInputView(
personIdentifier: personIdentifier,
Expand Down Expand Up @@ -385,6 +383,10 @@ struct IdCardView: View {
}
}
.onDisappear {
isInProgress = false
isShowingPinView = false
isShowingLoadingView = false
idCardActionMessage = ""
pinNumber.removeAll()
cancelIdCardAction()
}
Expand Down Expand Up @@ -491,17 +493,19 @@ struct IdCardView: View {

await viewModel.stopDiscoveringReaders()
cancelIdCardAction()
isInProgress = false
isShowingPinView = false
isShowingLoadingView = false

Toast.show(signatureAddedMessage, type: .success)
if voiceOverEnabled {
AccessibilityUtil.announceMessage(signatureAddedMessage)
}
await MainActor.run {
idCardActionMessage = ""

onSuccess(container)
dismiss()
Toast.show(signatureAddedMessage, type: .success)

if voiceOverEnabled {
AccessibilityUtil.announceMessage(signatureAddedMessage)
}

onSuccess(container)
dismiss()
}
}
}
}
Expand Down
51 changes: 31 additions & 20 deletions RIADigiDoc/UI/Component/Container/Signing/NFC/NFCInputView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import FactoryKit
import IdCardLib

struct NFCInputView: View {
@Environment(\.accessibilityVoiceOverEnabled) private var voiceOverEnabled
@Environment(LanguageSettings.self) private var languageSettings

@AppTheme private var theme
Expand Down Expand Up @@ -80,27 +81,14 @@ struct NFCInputView: View {
var body: some View {
VStack(alignment: .leading) {
VStack(alignment: .leading, spacing: Dimensions.Padding.MPadding) {
VStack(alignment: .leading, spacing: Dimensions.Padding.XSPadding) {
FloatingLabelTextField(
title: canNumberTitle,
placeholder: canNumberTitle,
text: $canNumber,
isError: !(canNumberError?.isEmpty ?? true),
errorText: canNumberError ?? "",
keyboardType: .numberPad,
sortPriority: 0
)
.onChange(of: canNumber) {
onInputChange()
}

Text(verbatim: canNumberLocationLabel)
.font(typography.labelMedium)
.foregroundStyle(theme.onSecondaryContainer)
.padding(.top, Dimensions.Padding.XXSPadding)
.accessibilitySortPriority(1)
// Allow keyboard to focus on input fields
// but have custom sort priority (contain to VStack) for these elements only with VoiceOver
if voiceOverEnabled {
nfcInputFields
.accessibilityElement(children: .contain)
} else {
nfcInputFields
}
.accessibilityElement(children: .contain)
}
.padding(.bottom, Dimensions.Padding.MPadding)

Expand Down Expand Up @@ -138,6 +126,29 @@ struct NFCInputView: View {
}
}
}

private var nfcInputFields: some View {
VStack(alignment: .leading, spacing: Dimensions.Padding.XSPadding) {
FloatingLabelTextField(
title: canNumberTitle,
placeholder: canNumberTitle,
text: $canNumber,
isError: !(canNumberError?.isEmpty ?? true),
errorText: canNumberError ?? "",
keyboardType: .numberPad,
sortPriority: 0
)
.onChange(of: canNumber) {
onInputChange()
}

Text(verbatim: canNumberLocationLabel)
.font(typography.labelMedium)
.foregroundStyle(theme.onSecondaryContainer)
.padding(.top, Dimensions.Padding.XXSPadding)
.accessibilitySortPriority(1)
}
}
}

#Preview {
Expand Down
4 changes: 4 additions & 0 deletions RIADigiDoc/UI/Component/Container/Signing/NFC/NFCView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ struct NFCView: View {

Toast.show(signatureAddedMessage, type: .success)

if voiceOverEnabled {
AccessibilityUtil.announceMessage(signatureAddedMessage)
}

onSuccess(container)
dismiss()
}
Expand Down
15 changes: 15 additions & 0 deletions RIADigiDoc/UI/Component/Container/Signing/SignaturesListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ struct SignaturesListView: View {
@Binding var selectedSignature: SignatureWrapper?
@Binding var containerMimetype: String
var dataFilesCount: Int
@Binding var focusedIndex: Int?
var showRemoveSignatureButton: Bool
@Binding var showRemoveSignatureModal: Bool

let nameUtil: NameUtilProtocol
let signatureUtil: SignatureUtilProtocol

@AccessibilityFocusState private var focusedSignatureIndex: Int?

var body: some View {
VStack {
if #available(iOS 26.0, *) {
Expand All @@ -55,6 +58,7 @@ struct SignaturesListView: View {
selectedSignature = timestamp
}
)
.accessibilityFocused($focusedSignatureIndex, equals: index)
}
} else {
ForEach(Array(timestamps.enumerated()), id: \.offset) { index, timestamp in
Expand All @@ -72,8 +76,10 @@ struct SignaturesListView: View {
selectedSignature = timestamp
}
)
.accessibilityFocused($focusedSignatureIndex, equals: index)
}
}

if #available(iOS 26.0, *) {
ForEach(signatures.enumerated(), id: \.offset) { index, signature in
SignatureView(
Expand All @@ -89,6 +95,13 @@ struct SignaturesListView: View {
selectedSignature = signature
}
)
.id(index)
.accessibilityFocused($focusedSignatureIndex, equals: index)
}
.onChange(of: focusedIndex) { _, newValue in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
focusedSignatureIndex = newValue
}
}
} else {
ForEach(Array(signatures.enumerated()), id: \.offset) { index, signature in
Expand All @@ -105,6 +118,7 @@ struct SignaturesListView: View {
selectedSignature = signature
}
)
.accessibilityFocused($focusedSignatureIndex, equals: index)
}
}
}
Expand Down Expand Up @@ -140,6 +154,7 @@ struct SignaturesListView: View {
selectedSignature: .constant(signature),
containerMimetype: .constant("application/vnd.etsi.asic-e+zip"),
dataFilesCount: 1,
focusedIndex: .constant(nil),
showRemoveSignatureButton: true,
showRemoveSignatureModal: .constant(false),
nameUtil: Container.shared.nameUtil(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct SigningRootView: View {
@Environment(NavigationPathManager.self) private var pathManager

@State private var chosenMethod: ActionMethod = .idCardViaNFC
@State private var isSuccess = false

@State private var viewModel: SigningRootViewModel

Expand Down Expand Up @@ -58,6 +59,7 @@ struct SigningRootView: View {
pinType: CodeType.pin2,
signedContainer: container,
onSuccess: { container in
isSuccess = true
sharedContainerViewModel.removeLastContainer()
sharedContainerViewModel.setSignedContainer(container)
sharedContainerViewModel.setIsSignatureAdded(true)
Expand All @@ -76,11 +78,13 @@ struct SigningRootView: View {
],
signedContainer: container,
onSuccess: { container in
isSuccess = true
sharedContainerViewModel.removeLastContainer()
sharedContainerViewModel.setSignedContainer(container)
sharedContainerViewModel.setIsSignatureAdded(true)
}
)
.accessibilityHidden(isSuccess)
}
case .mobileId:
if let container = signedContainer as? SignedContainerProtocol {
Expand Down
28 changes: 25 additions & 3 deletions RIADigiDoc/UI/Component/Container/Signing/SigningView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import UtilsLib

struct SigningView: View {
@Environment(\.presentationMode) var presentationMode
@Environment(\.accessibilityVoiceOverEnabled) private var voiceOverEnabled
@AppTheme private var theme
@AppTypography private var typography
@Environment(LanguageSettings.self) private var languageSettings
Expand Down Expand Up @@ -56,7 +57,8 @@ struct SigningView: View {

@State private var showSivaMessage = false

@AccessibilityFocusState private var focusedField: AccessibilityField?
@State private var scrollPosition: Int?
@State private var focusedSignatureIndex: Int?

private var containerTitle: String {
!isContainerSigned && !isNestedContainer ?
Expand Down Expand Up @@ -282,6 +284,7 @@ struct SigningView: View {
selectedSignature: $selectedSignature,
containerMimetype: $viewModel.containerMimetype,
dataFilesCount: viewModel.dataFiles.count,
focusedIndex: $focusedSignatureIndex,
showRemoveSignatureButton: viewModel.isSignatureRemoveButtonShown(),
showRemoveSignatureModal: $showRemoveSignatureModal,
nameUtil: nameUtil,
Expand Down Expand Up @@ -329,6 +332,11 @@ struct SigningView: View {
}
}
.padding(Dimensions.Padding.SPadding)
.scrollPosition(id: $scrollPosition, anchor: .bottom)
.onChange(of: viewModel.signatures.count) { previousCount, newCount in
guard newCount > previousCount else { return }
scrollToBottom()
}

if isSignedContainer {
if let containerFile = viewModel.containerURL {
Expand Down Expand Up @@ -386,8 +394,10 @@ struct SigningView: View {
}
}
.onAppear {
if viewModel.isSignatureAdded() {
selectedTab = .signatures
DispatchQueue.main.async {
if viewModel.isSignatureAdded() {
selectedTab = .signatures
}
}

containerLoadingTask = Task {
Expand Down Expand Up @@ -474,6 +484,18 @@ struct SigningView: View {
}
}

private func scrollToBottom() {
DispatchQueue.main.async {
guard let lastSignature = viewModel.signatures.indices.last else { return }

scrollPosition = lastSignature

DispatchQueue.main.async {
focusedSignatureIndex = lastSignature
}
}
}

private func updateSignAndEncryptButtonVisibility() async {
let shouldShowSignButton = await viewModel
.isSignButtonShown(
Expand Down
Loading
Loading