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
5 changes: 4 additions & 1 deletion Vault/Sources/CryptoEngine/Helpers/Data+Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ extension UInt64 {

extension Data {
/// An unsafe operation to cast the bytes of this data to the provided type.
///
/// `Data` gives no alignment guarantee for its backing buffer — a slice can start at any byte
/// offset — so the load must tolerate misalignment. An aligned `load` traps at runtime instead.
func asType<T>(_: T.Type) -> T {
withUnsafeBytes { (ptr: UnsafeRawBufferPointer) in
ptr.load(as: T.self)
ptr.loadUnaligned(as: T.self)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct VaultDetailEncryptionEditView: View {
) {
self.title = title
self.description = description
encryptionIsEnabled = encryptionInitiallyEnabled
_encryptionIsEnabled = State(initialValue: encryptionInitiallyEnabled)
self.didSetNewEncryptionPassword = didSetNewEncryptionPassword
self.didRemoveEncryption = didRemoveEncryption
}
Expand Down
4 changes: 3 additions & 1 deletion Vault/Sources/VaultiOS/Views/Feed/VaultItemFeedView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,9 @@ public struct VaultItemFeedView<
dataModel.items.move(fromOffsets: [move.fromIndex], toOffset: move.toIndex)
}
Task {
try await dataModel.reorder(items: [dropItem], to: move.reorderingPosition)
// The list has already moved optimistically. A failed persist leaves the
// stored order untouched and the next reload restores the on-disk order.
try? await dataModel.reorder(items: [dropItem], to: move.reorderingPosition)
}
return true
}
Expand Down
5 changes: 4 additions & 1 deletion Vault/Sources/VaultiOS/Views/General/AsyncButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ struct AsyncButton<Label: View, Loading: View>: View {
isDisabled = false
showProgressView = false
}
try await action()

// Errors belong to the action: call sites either catch them inline or surface them
// through their own view model state. The button only drives loading and disabled state.
try? await action()
}
},
label: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ public struct VaultItemOnTapDecoratorViewGenerator<
behaviour: VaultItemViewBehaviour,
) -> some View {
Button {
Task { try await onTap(metadata.id) }
Task {
// Fail closed. A thrown error means the tap action did not complete — most often a
// failed authentication gating a copy — so the tap must do nothing at all.
try? await onTap(metadata.id)
}
} label: {
generator.makeVaultPreviewView(item: item, metadata: metadata, behaviour: behaviour)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,3 @@ public protocol VaultItemPreviewSceneResponder {
func scenePhaseDidChange(to scene: ScenePhase)
func didAppear()
}

// MARK: - Mock

extension VaultItemPreviewViewGeneratorMock: VaultItemCopyActionHandler {
public func textToCopyForVaultItem(id _: Identifier<VaultItem>) -> VaultTextCopyAction? {
nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ struct PendingValueTests {
let waitForTaskStart = Pending.signal()
Task.detached(priority: .high) {
await waitForTaskStart.fulfill()
_ = try await sut.wait()
// The wait is torn down by `sut.cancel()` at the end of the test, so a throw is expected.
_ = try? await sut.wait()
}

try await waitForTaskStart.wait()
Expand Down
24 changes: 16 additions & 8 deletions Vault/Tests/VaultCoreTests/Clock/IntervalTimerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ enum IntervalTimerTests {
let pendingStart = Pending.signal()
let completed = Pending.signal()
Task {
try await confirmation(timeout: .seconds(1), expectedCount: 0) { _ in
await pendingStart.fulfill()
try await sut.wait(for: 0.1)
await completed.fulfill()
do {
try await confirmation(timeout: .seconds(1), expectedCount: 0) { _ in
await pendingStart.fulfill()
try await sut.wait(for: 0.1)
await completed.fulfill()
}
} catch {
Issue.record(error)
}
}

Expand All @@ -49,10 +53,14 @@ enum IntervalTimerTests {
let pendingStart = Pending.signal()
let completed = Pending.signal()
Task {
try await confirmation(timeout: .seconds(1), expectedCount: 0) { _ in
await pendingStart.fulfill()
try await sut.wait(for: 0.1, tolerance: 0.1)
await completed.fulfill()
do {
try await confirmation(timeout: .seconds(1), expectedCount: 0) { _ in
await pendingStart.fulfill()
try await sut.wait(for: 0.1, tolerance: 0.1)
await completed.fulfill()
}
} catch {
Issue.record(error)
}
}

Expand Down