Format files before build

This commit is contained in:
Jacek Krasiukianis
2025-08-26 10:30:02 +00:00
parent d93bc14cfe
commit 87949338fd
70 changed files with 277 additions and 243 deletions
@@ -54,7 +54,8 @@ final class SenderImageAPIDataSource: Sendable, SenderImageDataSource {
guard let userSession = dependencies.appContext.sessionState.userSession else {
return nil
}
let senderImageResult = await userSession
let senderImageResult =
await userSession
.imageForSender(
address: params.address,
bimiSelector: params.bimiSelector,
@@ -42,11 +42,11 @@ actor DeviceTokenRegistrar {
private func prepareDeviceRegistrationRequest(deviceToken: String) -> RegisteredDevice {
let environment: DeviceEnvironment
#if DEBUG
environment = .appleDev
#else
environment = .appleProd
#endif
#if DEBUG
environment = .appleDev
#else
environment = .appleProd
#endif
return RegisteredDevice(
deviceToken: deviceToken,
@@ -24,7 +24,7 @@ extension AllListActions {
hiddenListActions: [
.notSpam(.testInbox),
.permanentDelete,
.moveToSystemFolder(.init(localId: .init(value: 7), name: .archive))
.moveToSystemFolder(.init(localId: .init(value: 7), name: .archive)),
],
visibleListActions: [.markRead, .star, .moveTo, .labelAs, .more]
)
@@ -23,17 +23,18 @@ enum MoveToSheetPreviewProvider {
static var availableMoveToActions: AvailableMoveToActions {
.init(
message: { _, _ in
.ok([
.systemFolder(.init(localId: .init(value: 1), name: .inbox)),
.systemFolder(.init(localId: .init(value: 2), name: .archive)),
.customFolder(customFoldersTree),
.customFolder(.init(
.ok([
.systemFolder(.init(localId: .init(value: 1), name: .inbox)),
.systemFolder(.init(localId: .init(value: 2), name: .archive)),
.customFolder(customFoldersTree),
.customFolder(
.init(
localId: .init(value: 6),
name: "4",
color: .init(value: "#9E221A"),
children: []
))
])
)),
])
},
conversation: { _, _ in .ok([]) }
)
@@ -44,7 +44,7 @@ extension Array where Element == AttachmentDisplayModel {
mimeType: .init(mime: "doc", category: .pages),
name: "Long long long long long long long long long long name",
size: 120000
)
),
]
}
@@ -23,9 +23,7 @@ extension MailboxItemCellUIModel {
static let proton2 = makeModel(subject: "sales up to 50%", isFromProton: true)
static func testData() -> [MailboxItemCellUIModel] {
[proton1] +
MailboxItemCellUIModel.emailSubjects.map { makeModel(subject: $0) } +
[proton2]
[proton1] + MailboxItemCellUIModel.emailSubjects.map { makeModel(subject: $0) } + [proton2]
}
}
@@ -42,11 +40,13 @@ private extension MailboxItemCellUIModel {
enum Attachment {
static func randomAttachment() -> [AttachmentCapsuleUIModel] {
if [false, false, Bool.random()].randomElement()! {
[[
AttachmentCapsuleUIModel(id: .init(value: 1), icon: DS.Icon.icFileTypeIconPdf, name: "#34JE3KLP.pdf"),
AttachmentCapsuleUIModel(id: .init(value: 2), icon: DS.Icon.icFileTypeIconWord, name: "meeting_minutes.doc"),
AttachmentCapsuleUIModel(id: .init(value: 1), icon: DS.Icon.icFileTypeIconExcel, name: "ARR_Q2.xls"),
].randomElement()!]
[
[
AttachmentCapsuleUIModel(id: .init(value: 1), icon: DS.Icon.icFileTypeIconPdf, name: "#34JE3KLP.pdf"),
AttachmentCapsuleUIModel(id: .init(value: 2), icon: DS.Icon.icFileTypeIconWord, name: "meeting_minutes.doc"),
AttachmentCapsuleUIModel(id: .init(value: 1), icon: DS.Icon.icFileTypeIconExcel, name: "ARR_Q2.xls"),
].randomElement()!
]
} else {
[]
}
@@ -69,16 +69,17 @@ private extension MailboxItemCellUIModel {
static func randomLabels() -> [LabelUIModel] {
Bool.random()
? [[work, readLater].randomElement()!] + LabelUIModel.random(num: [0, 1, 2].randomElement()!)
: []
? [[work, readLater].randomElement()!] + LabelUIModel.random(num: [0, 1, 2].randomElement()!)
: []
}
}
static func makeModel(subject: String, isFromProton: Bool = false) -> MailboxItemCellUIModel {
let avatar = isFromProton
? .init(info: .init(initials: "P", color: .purple), type: .sender(params: .init()))
: Avatar.randomAvatar()
let avatar =
isFromProton
? .init(info: .init(initials: "P", color: .purple), type: .sender(params: .init()))
: Avatar.randomAvatar()
return MailboxItemCellUIModel(
id: .random(),
conversationID: .random(),
@@ -152,7 +153,7 @@ private extension MailboxItemCellUIModel {
"What Time Should I Pick You Up on Saturday?",
"Looking Forward to Seeing You This Weekend",
"Thanks for Being a Loyal Customer Enjoy 10% Off",
"Only a Few Hours Left Final Sale Ends Soon!"
"Only a Few Hours Left Final Sale Ends Soon!",
]
}
@@ -53,12 +53,14 @@ struct SendingTag: View {
}
#Preview {
ZStack(alignment: .center, content: {
VStack {
SendingTag(variant: .sending)
SendingTag(variant: .failure)
}
})
ZStack(
alignment: .center,
content: {
VStack {
SendingTag(variant: .sending)
SendingTag(variant: .failure)
}
})
}
private extension SendingTag.Variant {
@@ -44,9 +44,10 @@ struct AttachmentsView: View {
var body: some View {
GeometryReader { geometry in
let spaceForCapsules = geometry.size.width
- (maxNumberOfCapsules*Layout.spacingBetweenCapsules) - Layout.extraAttachmentsViewWidth
let capsuleMaxWidth = uiModel.count == 1 ? spaceForCapsules : spaceForCapsules/CGFloat(maxNumberOfCapsules)
let spaceForCapsules =
geometry.size.width
- (maxNumberOfCapsules * Layout.spacingBetweenCapsules) - Layout.extraAttachmentsViewWidth
let capsuleMaxWidth = uiModel.count == 1 ? spaceForCapsules : spaceForCapsules / CGFloat(maxNumberOfCapsules)
/**
SwiftUI does not make it easy to calculate dynamically to fit the maximum number of capsules. After trying
@@ -189,18 +190,18 @@ fileprivate enum Layout {
.init(id: .init(value: 5), icon: DS.Icon.icFileTypeIconCode, name: "5.bash"),
.init(id: .init(value: 6), icon: DS.Icon.icFileTypeIconWord, name: "6.pdf"),
.init(id: .init(value: 7), icon: DS.Icon.icFileTypeIconCode, name: "7.png"),
.init(id: .init(value: 8), icon: DS.Icon.icFileTypeIconWord, name: "8.xls")
.init(id: .init(value: 8), icon: DS.Icon.icFileTypeIconWord, name: "8.xls"),
]
)
.border(.red)
AttachmentsView(
uiModel:[
uiModel: [
.init(id: .init(value: 1), icon: DS.Icon.icFileTypeIconPdf, name: "super_long_title_that_goes_beyond_half.pdf"),
.init(id: .init(value: 2), icon: DS.Icon.icFileTypeIconImage, name: "quite.png"),
.init(id: .init(value: 3), icon: DS.Icon.icFileTypeIconExcel, name: "numebrs.xls"),
.init(id: .init(value: 4), icon: DS.Icon.icFileTypeIconWord, name: "words.doc"),
.init(id: .init(value: 5), icon: DS.Icon.icFileTypeIconCode, name: "scripts.bash")
.init(id: .init(value: 5), icon: DS.Icon.icFileTypeIconCode, name: "scripts.bash"),
]
)
.frame(width: 300)
@@ -58,23 +58,23 @@ struct AvatarCheckboxView: View {
AvatarCheckboxView(
isSelected: true,
avatar: .init(info: .init(initials: "Mb", color: .cyan), type: .sender(params: .init()))
) { _ in}
.square(size: 40)
.clipped()
) { _ in }
.square(size: 40)
.clipped()
AvatarCheckboxView(
isSelected: false,
avatar: .init(info: .init(initials: "Mb", color: .cyan), type: .sender(params: .init()))
) { _ in}
.square(size: 40)
.clipped()
) { _ in }
.square(size: 40)
.clipped()
AvatarCheckboxView(
isSelected: false,
avatar: .init(info: .init(initials: "Mb", color: .cyan), type: .sender(params: .init()))
) { _ in}
.square(size: 40)
.clipped()
) { _ in }
.square(size: 40)
.clipped()
}
}
@@ -19,11 +19,11 @@ import proton_app_uniffi
struct AllMessagesDeleter {
private let deleteAllMessages: @Sendable (_ labelID: ID) async -> VoidActionResult
init(mailUserSession: MailUserSession, wrapper: RustEmptyFolderBannerWrapper) {
self.deleteAllMessages = { labelID in await wrapper.deleteAllMessages(mailUserSession, labelID) }
}
@discardableResult
func deleteAll(labelID: ID) async -> VoidActionResult {
await deleteAllMessages(labelID)
@@ -23,7 +23,7 @@ struct EmptyFolderBanner {
case upgradePlan
case emptyLocation
}
struct FolderDetails {
let labelID: ID
let type: SpamOrTrash
@@ -35,9 +35,11 @@ struct ListScrollOffsetTrackerView: View {
.listRowInsets(EdgeInsets())
.listRowBackground(Color.clear)
.frame(maxHeight: 1)
.readLayoutData(coordinateSpace: .global, onChange: { data in
let realScrollOffset = data.frameInCoordinateSpace.minY - listTopOffset
onScrollEvent(.onChangeOffset(value: realScrollOffset))
})
.readLayoutData(
coordinateSpace: .global,
onChange: { data in
let realScrollOffset = data.frameInCoordinateSpace.minY - listTopOffset
onScrollEvent(.onChangeOffset(value: realScrollOffset))
})
}
}
@@ -25,7 +25,7 @@ enum OneLineLabelsListViewPreviewDataProvider {
["Private"],
["😈"],
["Long long long long long long long long long long long long long long"],
["Aaaaaaaa", "Long long label long long long long long", "aaaaaaaaaaaaa"]
["Aaaaaaaa", "Long long label long long long long long", "aaaaaaaaaaaaa"],
].map { $0.map(LabelUIModel.testData) }
}
@@ -57,7 +57,7 @@ final class ProtonRefreshControl: UIRefreshControl, ObservableObject {
spinnerAnimation.centerXAnchor.constraint(equalTo: centerXAnchor),
spinnerAnimation.centerYAnchor.constraint(equalTo: centerYAnchor),
spinnerAnimation.heightAnchor.constraint(equalToConstant: spinnerSize),
spinnerAnimation.widthAnchor.constraint(equalTo: spinnerAnimation.heightAnchor)
spinnerAnimation.widthAnchor.constraint(equalTo: spinnerAnimation.heightAnchor),
])
}
@@ -18,9 +18,10 @@
import BackgroundTasks
struct BackgroundTaskRegistration {
let registerWithIdentifier: (
_ identifier: String,
_ queue: DispatchQueue?,
_ handler: @escaping (BackgroundTask) -> Void
) -> Bool
let registerWithIdentifier:
(
_ identifier: String,
_ queue: DispatchQueue?,
_ handler: @escaping (BackgroundTask) -> Void
) -> Bool
}
@@ -75,7 +75,8 @@ class RecurringBackgroundTaskScheduler: @unchecked Sendable {
func submit() async {
let allTaskRequests = await backgroundTaskScheduler.pendingTaskRequests()
let isTaskSchedulled = allTaskRequests
let isTaskSchedulled =
allTaskRequests
.contains(where: { request in request.identifier == Self.identifier })
guard !isTaskSchedulled else {
return
@@ -137,7 +138,8 @@ class RecurringBackgroundTaskScheduler: @unchecked Sendable {
}
private func checkForSessionSetUpToComplete(completion: @Sendable @escaping () -> Void) {
sessionSetUpCheckCancellable = Publishers
sessionSetUpCheckCancellable =
Publishers
.CombineLatest(sessionStatePublisher, timerFactory(0.5))
.map { sessionState, _ in sessionState }
.prefix(untilOutputFrom: backgroundTaskExpired)
+2 -2
View File
@@ -22,8 +22,8 @@ import Foundation
func forceCast<Value, ExpectedType>(_ value: Value, _ type: ExpectedType.Type) -> ExpectedType {
guard let castedValue = value as? ExpectedType else {
let message = """
Could not cast value: <\(value)> of type: <\(Swift.type(of: value))> to expected type: <\(ExpectedType.self)>.
"""
Could not cast value: <\(value)> of type: <\(Swift.type(of: value))> to expected type: <\(ExpectedType.self)>.
"""
AppLogger.log(message: message)
fatalError(message)
}
@@ -33,11 +33,9 @@ extension Date {
func mailboxFormat(calendar: Calendar = .current) -> String {
if calendar.isDateInToday(self) {
return formatted(.dateTime.hour().minute())
}
else if calendar.isDate(self, equalTo: .now, toGranularity: .year) {
} else if calendar.isDate(self, equalTo: .now, toGranularity: .year) {
return formatted(.dateTime.month().day())
}
else {
} else {
return formatted(date: .abbreviated, time: .omitted)
}
}
@@ -68,11 +66,9 @@ extension Date {
func mailboxVoiceOverSupport(calendar: Calendar = .current) -> String {
if calendar.isDateInToday(self) {
return formatted(.dateTime.hour().minute())
}
else if calendar.isDate(self, equalTo: .now, toGranularity: .year) {
} else if calendar.isDate(self, equalTo: .now, toGranularity: .year) {
return formatted(.dateTime.month(.wide).day())
}
else {
} else {
return formatted(date: .long, time: .omitted)
}
}
@@ -32,9 +32,10 @@ extension Date {
isAboutToExpire = hours < 1 && minute < 1
}
let text = isAboutToExpire
? L10n.Mailbox.Item.expiresInLessThanOneMinute
: L10n.Mailbox.Item.expiresIn(value: self.localisedRemainingTimeFromNow())
let text =
isAboutToExpire
? L10n.Mailbox.Item.expiresInLessThanOneMinute
: L10n.Mailbox.Item.expiresIn(value: self.localisedRemainingTimeFromNow())
return ExpirationDateUIModel(text: text, color: color)
}
}
@@ -28,7 +28,7 @@ struct CustomizeToolbarsScreenSnapshotTests {
state: .init(
toolbars: [
.list(.init(selected: [.move, .archive, .label, .toggleRead], unselected: [])),
.message(.init(selected: [.reply, .move, .forward, .toggleRead], unselected: []))
.message(.init(selected: [.reply, .move, .forward, .toggleRead], unselected: [])),
],
editToolbar: nil
),
@@ -35,7 +35,7 @@ extension LegacyKeychain {
func set(privateKey privateKeyData: Data, forLabel label: PrivateKeyLabel) throws {
let attributes: [CFString: Any] = [
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
]
var error: Unmanaged<CFError>?
@@ -51,7 +51,7 @@ extension LegacyKeychain {
kSecAttrLabel: label.rawValue,
kSecAttrApplicationTag: service,
kSecAttrAccessGroup: accessGroup,
kSecValueRef: secKey!
kSecValueRef: secKey!,
]
let status = SecItemAdd(query as CFDictionary, nil)
@@ -65,7 +65,7 @@ extension LegacyKeychain {
let query: [CFString: Any] = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: service,
kSecAttrAccessGroup: accessGroup
kSecAttrAccessGroup: accessGroup,
]
let status = SecItemDelete(query as CFDictionary)
@@ -62,7 +62,8 @@ private extension MainKeyUnlockerTests {
}
var biometricsProtectedMainKey: Data {
.init(base64Encoded: "BMXkPgRzsc3e8xTY+Pnndl2HjqyZJ6rN5BF2T8t973NyeSoVs1A3CQGpwiprUAQHopyKa+ovFPzPgk5gFmZsbVIWK2qxX242iy0FOBtGWaEDjv06kQkFP34IFoCpFpfx9YhBb29+KLJd2JHebSpctqY=").unsafelyUnwrapped
.init(base64Encoded: "BMXkPgRzsc3e8xTY+Pnndl2HjqyZJ6rN5BF2T8t973NyeSoVs1A3CQGpwiprUAQHopyKa+ovFPzPgk5gFmZsbVIWK2qxX242iy0FOBtGWaEDjv06kQkFP34IFoCpFpfx9YhBb29+KLJd2JHebSpctqY=")
.unsafelyUnwrapped
}
var secureEnclavePrivateKey: Data {
@@ -70,7 +71,10 @@ private extension MainKeyUnlockerTests {
}
var pinProtectedMainKey: Data {
.init(base64Encoded: "dAcGOBeHqCMJvQPyOOy303bveHdY+QmCt8RpD6xX8u6+7PLF3pnUXhn91fIb2UND5P7Se8wKkKboY9a9ayFOJMm9uviXe6jCnT9C9Mh8rT3Bn04ctKPIg1YwZXCQwz80kQ/y/tW8wWACS4xRJ70v2MG5nh9jCGsi2nZ3PfFuX4545dfK0H6K0IpdwYYaZqWT6WJrGr6x+QGkJZZc6qfzLvZ7O7lmenuzc2u/fS7+fRouUROQW/2O7bo=").unsafelyUnwrapped
.init(
base64Encoded:
"dAcGOBeHqCMJvQPyOOy303bveHdY+QmCt8RpD6xX8u6+7PLF3pnUXhn91fIb2UND5P7Se8wKkKboY9a9ayFOJMm9uviXe6jCnT9C9Mh8rT3Bn04ctKPIg1YwZXCQwz80kQ/y/tW8wWACS4xRJ70v2MG5nh9jCGsi2nZ3PfFuX4545dfK0H6K0IpdwYYaZqWT6WJrGr6x+QGkJZZc6qfzLvZ7O7lmenuzc2u/fS7+fRouUROQW/2O7bo="
).unsafelyUnwrapped
}
var pinProtectionSalt: Data {
@@ -86,7 +86,7 @@ final class NotificationAuthorizationStoreTests {
userDefaults[.notificationAuthorizationRequestDates] = [
Calendar.autoupdatingCurrent.date(byAdding: .day, value: -20, to: .now)!,
Calendar.autoupdatingCurrent.date(byAdding: .day, value: -10, to: .now)!
Calendar.autoupdatingCurrent.date(byAdding: .day, value: -10, to: .now)!,
]
#expect(await sut.shouldRequestAuthorization(trigger: .messageSent) == false)
@@ -114,17 +114,19 @@ class AppSettingsStateStoreTests {
await changeAlternativeRoutingValue(false)
#expect(appSettingsRepositorySpy.changedAppSettingsWithDiff == [
.diff(useAlternativeRouting: false)
])
#expect(
appSettingsRepositorySpy.changedAppSettingsWithDiff == [
.diff(useAlternativeRouting: false)
])
#expect(sut.state.storedAppSettings.useAlternativeRouting == false)
await changeAlternativeRoutingValue(true)
#expect(appSettingsRepositorySpy.changedAppSettingsWithDiff == [
.diff(useAlternativeRouting: false),
.diff(useAlternativeRouting: true),
])
#expect(
appSettingsRepositorySpy.changedAppSettingsWithDiff == [
.diff(useAlternativeRouting: false),
.diff(useAlternativeRouting: true),
])
#expect(sut.state.storedAppSettings.useAlternativeRouting == true)
}
@@ -134,17 +136,19 @@ class AppSettingsStateStoreTests {
await changeCombinedContactsValue(true)
#expect(appSettingsRepositorySpy.changedAppSettingsWithDiff == [
.diff(useCombineContacts: true)
])
#expect(
appSettingsRepositorySpy.changedAppSettingsWithDiff == [
.diff(useCombineContacts: true)
])
#expect(sut.state.storedAppSettings.useCombineContacts == true)
await changeCombinedContactsValue(false)
#expect(appSettingsRepositorySpy.changedAppSettingsWithDiff == [
.diff(useCombineContacts: true),
.diff(useCombineContacts: false),
])
#expect(
appSettingsRepositorySpy.changedAppSettingsWithDiff == [
.diff(useCombineContacts: true),
.diff(useCombineContacts: false),
])
#expect(sut.state.storedAppSettings.useCombineContacts == false)
}
@@ -140,7 +140,7 @@ final class ConversationDetailBottomSheetComposeTests: PMUIMockedNetworkTestCase
$0.hasComposeButtons()
}
}
private func withActionBottomSheetDisplayed(destination: UITestDestination = .inbox, interaction: (ActionBottomSheetRobot) -> Void) {
navigator.navigateTo(destination)
@@ -88,7 +88,7 @@ final class ConversationDetailHeaderMultipleFieldsTests: PMUIMockedNetworkTestCa
timestamp: 1718976443,
toRecipients: [
UITestHeaderRecipientEntry(index: 0, name: "Test Free Account", address: "notsofree@proton.black"),
UITestHeaderRecipientEntry(index: 1, name: "notsofree+1@proton.black", address: "notsofree+1@proton.black")
UITestHeaderRecipientEntry(index: 1, name: "notsofree+1@proton.black", address: "notsofree+1@proton.black"),
],
ccRecipients: [
UITestHeaderRecipientEntry(index: 0, name: "free@proton.black", address: "free@proton.black")
@@ -49,7 +49,7 @@ final class ConversationDetailMessageItemsTests: PMUIMockedNetworkTestCase {
let expectedCollapsedEntries = [
UITestConversationCollapsedItemEntry(index: 0, senderName: "notsofree@proton.black", date: "Jun 17", preview: "to youngbee@proton.black"),
UITestConversationCollapsedItemEntry(index: 1, senderName: "notsofree@proton.black", date: "Jun 18", preview: "to youngbee@proton.black"),
UITestConversationCollapsedItemEntry(index: 2, senderName: "Young Bee", date: "Jun 18", preview: "to notsofree@proton.black")
UITestConversationCollapsedItemEntry(index: 2, senderName: "Young Bee", date: "Jun 18", preview: "to notsofree@proton.black"),
]
navigator.navigateTo(UITestDestination.inbox)
@@ -220,7 +220,7 @@ final class MailboxAttachmentPreviewsTests: PMUIMockedNetworkTestCase {
let capsules = [
UITestAttachmentPreviewCapsuleItemEntry(index: 0, attachmentName: "fifth.png"),
UITestAttachmentPreviewCapsuleItemEntry(index: 1, attachmentName: "first.png")
UITestAttachmentPreviewCapsuleItemEntry(index: 1, attachmentName: "first.png"),
]
let attachmentPreviews = UITestAttachmentPreviewItemEntry(items: capsules, extraItemsCount: 4)
@@ -321,7 +321,7 @@ final class MailboxAttachmentPreviewsTests: PMUIMockedNetworkTestCase {
let capsules = [
UITestAttachmentPreviewCapsuleItemEntry(index: 0, attachmentName: "zipfile.zip"),
UITestAttachmentPreviewCapsuleItemEntry(index: 1, attachmentName: "fifth.png")
UITestAttachmentPreviewCapsuleItemEntry(index: 1, attachmentName: "fifth.png"),
]
let attachmentPreviews = UITestAttachmentPreviewItemEntry(items: capsules, extraItemsCount: 5)
@@ -345,7 +345,7 @@ final class MailboxAttachmentPreviewsTests: PMUIMockedNetworkTestCase {
let capsules = [
UITestAttachmentPreviewCapsuleItemEntry(index: 0, attachmentName: "zip_conv.zip"),
UITestAttachmentPreviewCapsuleItemEntry(index: 1, attachmentName: "zip_rep.zip")
UITestAttachmentPreviewCapsuleItemEntry(index: 1, attachmentName: "zip_rep.zip"),
]
let attachmentPreviews = UITestAttachmentPreviewItemEntry(items: capsules, extraItemsCount: 7)
@@ -370,7 +370,7 @@ final class MailboxAttachmentPreviewsTests: PMUIMockedNetworkTestCase {
let capsules = [
UITestAttachmentPreviewCapsuleItemEntry(index: 0, attachmentName: "zip_conv.zip"),
UITestAttachmentPreviewCapsuleItemEntry(index: 1, attachmentName: "zip_rep.zip")
UITestAttachmentPreviewCapsuleItemEntry(index: 1, attachmentName: "zip_rep.zip"),
]
let attachmentPreviews = UITestAttachmentPreviewItemEntry(items: capsules, extraItemsCount: 1)
@@ -33,7 +33,7 @@ struct UITestBottomSheetDefaultEntries {
UITestBottomSheetDynamicEntry(section: 2, index: 2, text: "Print"),
UITestBottomSheetDynamicEntry(section: 2, index: 3, text: "View headers"),
UITestBottomSheetDynamicEntry(section: 2, index: 4, text: "View HTML"),
UITestBottomSheetDynamicEntry(section: 2, index: 5, text: "Report phishing")
UITestBottomSheetDynamicEntry(section: 2, index: 5, text: "Report phishing"),
]
static let defaultTrashList = [
@@ -49,7 +49,7 @@ struct UITestBottomSheetDefaultEntries {
UITestBottomSheetDynamicEntry(section: 2, index: 2, text: "Print"),
UITestBottomSheetDynamicEntry(section: 2, index: 3, text: "View headers"),
UITestBottomSheetDynamicEntry(section: 2, index: 4, text: "View HTML"),
UITestBottomSheetDynamicEntry(section: 2, index: 5, text: "Report phishing")
UITestBottomSheetDynamicEntry(section: 2, index: 5, text: "Report phishing"),
]
static let defaultSpamList = [
@@ -65,7 +65,7 @@ struct UITestBottomSheetDefaultEntries {
UITestBottomSheetDynamicEntry(section: 2, index: 2, text: "Print"),
UITestBottomSheetDynamicEntry(section: 2, index: 3, text: "View headers"),
UITestBottomSheetDynamicEntry(section: 2, index: 4, text: "View HTML"),
UITestBottomSheetDynamicEntry(section: 2, index: 5, text: "Report phishing")
UITestBottomSheetDynamicEntry(section: 2, index: 5, text: "Report phishing"),
]
static let defaultArchiveList = [
@@ -81,7 +81,7 @@ struct UITestBottomSheetDefaultEntries {
UITestBottomSheetDynamicEntry(section: 2, index: 2, text: "Print"),
UITestBottomSheetDynamicEntry(section: 2, index: 3, text: "View headers"),
UITestBottomSheetDynamicEntry(section: 2, index: 4, text: "View HTML"),
UITestBottomSheetDynamicEntry(section: 2, index: 5, text: "Report phishing")
UITestBottomSheetDynamicEntry(section: 2, index: 5, text: "Report phishing"),
]
static let defaultSenderActions = [
@@ -96,7 +96,7 @@ struct UITestBottomSheetDefaultEntries {
UITestBottomSheetDynamicEntry(section: 0, index: 0, text: "Message"),
UITestBottomSheetDynamicEntry(section: 0, index: 1, text: "Add to contacts"),
UITestBottomSheetDynamicEntry(section: 1, index: 0, text: "Copy address"),
UITestBottomSheetDynamicEntry(section: 1, index: 1, text: "Copy name")
UITestBottomSheetDynamicEntry(section: 1, index: 1, text: "Copy name"),
]
}
}
@@ -25,8 +25,11 @@ struct UITestConversationExpandedHeaderEntry {
let toRecipients: [UITestHeaderRecipientEntry]
let ccRecipients: [UITestHeaderRecipientEntry]?
let bccRecipients: [UITestHeaderRecipientEntry]?
init(index: Int, senderName: String, senderAddress: String, timestamp: UInt64, toRecipients: [UITestHeaderRecipientEntry], ccRecipients: [UITestHeaderRecipientEntry]? = nil, bccRecipients: [UITestHeaderRecipientEntry]? = nil) {
init(
index: Int, senderName: String, senderAddress: String, timestamp: UInt64, toRecipients: [UITestHeaderRecipientEntry], ccRecipients: [UITestHeaderRecipientEntry]? = nil,
bccRecipients: [UITestHeaderRecipientEntry]? = nil
) {
self.index = index
self.senderName = senderName
self.senderAddress = senderAddress
@@ -25,7 +25,7 @@ struct UITestMailboxListItemEntry {
let date: String
let count: Int?
let attachmentPreviews: UITestAttachmentPreviewItemEntry?
init(index: Int, avatar: UITestAvatarItemEntry, sender: String, subject: String, date: String, count: Int? = nil, attachmentPreviews: UITestAttachmentPreviewItemEntry? = nil) {
self.index = index
self.avatar = avatar
+2 -2
View File
@@ -38,12 +38,12 @@ extension Robot {
return self
}
func waitMessageBySubject(subject: String) {
let subjectText = application.staticTexts[subject].firstMatch
subjectText.waitUntilShown()
}
func clickMessageBySubject(subject: String) {
let subjectText = application.staticTexts[subject].firstMatch
subjectText.tap()
@@ -25,11 +25,11 @@ public class DurationMeasurement: Measurement {
return stopTime - startTime
}
public init(startTime: TimeInterval = Date().timeIntervalSince1970 , stopTime: TimeInterval = Date().timeIntervalSince1970) {
public init(startTime: TimeInterval = Date().timeIntervalSince1970, stopTime: TimeInterval = Date().timeIntervalSince1970) {
self.startTime = startTime
self.stopTime = stopTime
}
public func onStartMeasurement(measurementProfile: MeasurementProfile) {
startTime = Date().timeIntervalSince1970
}
@@ -30,7 +30,7 @@ enum LokiPushError: Error {
@available(macOS 12.0, *)
class LokiClient {
init(){
init() {
self.session = URLSession(configuration: .default, delegate: CustomSessionDelegate(), delegateQueue: nil)
}
@@ -89,4 +89,3 @@ class LokiClient {
}
}
}
@@ -15,7 +15,6 @@
// You should have received a copy of the GNU General Public License
// along with Proton Mail. If not, see https://www.gnu.org/licenses/.
import Foundation
import XCTest
@@ -35,7 +34,9 @@ public class MeasureBlock {
internal func startMeasurement() {
profile.measuresList.append(self)
if self.labels["sli"] as! String == "unknown" {
XCTFail("MeasurementProfile: measure block for profile with workflow: \"\(profile.workflow)\" expected Service Level Indicator to be set via profile.setServiceLevelIndicator() but it wasn't. Current value is \"null\".")
XCTFail(
"MeasurementProfile: measure block for profile with workflow: \"\(profile.workflow)\" expected Service Level Indicator to be set via profile.setServiceLevelIndicator() but it wasn't. Current value is \"null\"."
)
}
profile.measurements.forEach { $0.onStartMeasurement(measurementProfile: profile) }
}
@@ -47,17 +48,19 @@ public class MeasureBlock {
}
public func getMeasureStream() -> [String: Any] {
let timestamp = Int(Date().timeIntervalSince1970 * 1_000_000_000) // Nanoseconds since epoch
let timestamp = Int(Date().timeIntervalSince1970 * 1_000_000_000) // Nanoseconds since epoch
let values: [[Any]] = [[
"\(timestamp)",
metrics.jsonString(),
metadata
]]
let values: [[Any]] = [
[
"\(timestamp)",
metrics.jsonString(),
metadata,
]
]
return [
"stream": profile.sharedLabels,
"values": values
"values": values,
]
}
@@ -116,4 +119,3 @@ extension Dictionary {
return "{}"
}
}
@@ -16,9 +16,9 @@
// along with Proton Mail. If not, see https://www.gnu.org/licenses/.
#if os(macOS)
import AppKit
import AppKit
#else
import UIKit
import UIKit
#endif
public class MeasurementProfile: MeasurementProtocol {
@@ -33,15 +33,15 @@ public class MeasurementProfile: MeasurementProtocol {
public init(workflow: String) {
self.workflow = workflow
#if os(macOS)
let platform = "macOS"
let systemVersion = ProcessInfo.processInfo.operatingSystemVersionString
let deviceModel = "Mac"
#else
let platform = "iOS"
let systemVersion = UIDevice.current.systemVersion
let deviceModel = UIDevice.current.model
#endif
#if os(macOS)
let platform = "macOS"
let systemVersion = ProcessInfo.processInfo.operatingSystemVersionString
let deviceModel = "Mac"
#else
let platform = "iOS"
let systemVersion = UIDevice.current.systemVersion
let deviceModel = UIDevice.current.model
#endif
self.sharedLabels = [
"workflow": workflow,
@@ -56,12 +56,12 @@ public class MeasurementProfile: MeasurementProtocol {
self.sharedMetadata = [
"app_version": MeasurementConfig.version,
"build_commit_sha1": MeasurementConfig.buildCommitShortSha,
"ci_job_id": MeasurementConfig.ciJobId
"ci_job_id": MeasurementConfig.ciJobId,
]
}
@discardableResult
public func addMeasurement(_ measurement: Measurement) -> MeasurementProfile {
public func addMeasurement(_ measurement: Measurement) -> MeasurementProfile {
measurements.append(measurement)
return self
}
@@ -78,14 +78,14 @@ public class MeasurementProfile: MeasurementProtocol {
return components.joined(separator: "_")
}
public func addMetricToMeasures(_ key: String, _ value: String) {
public func addMetricToMeasures(_ key: String, _ value: String) {
measuresList.forEach { measure in
measure.addMetric(key: key, value: value)
}
}
@discardableResult
public func addMetrics(data: [String: String]) -> MeasurementProfile {
public func addMetrics(data: [String: String]) -> MeasurementProfile {
measuresList.forEach { measure in
measure.addMetrics(data)
}
@@ -93,7 +93,7 @@ public class MeasurementProfile: MeasurementProtocol {
}
@discardableResult
public func setServiceLevelIndicator(_ sli: String) -> MeasurementProfile {
public func setServiceLevelIndicator(_ sli: String) -> MeasurementProfile {
self.serviceLevelIndicator = sli
sharedLabels["sli"] = sli
return self
@@ -118,4 +118,3 @@ public class MeasurementProfile: MeasurementProtocol {
}
}
}
+5 -4
View File
@@ -22,12 +22,13 @@ func getTestConfigValue(forKey key: String) -> String {
for bundle in testBundles {
if let url = bundle.url(forResource: "Loki", withExtension: "plist"),
let data = try? Data(contentsOf: url),
let plist = try? PropertyListSerialization.propertyList(from: data, format: nil) as? [String: Any],
let value = plist[key] as? String {
let data = try? Data(contentsOf: url),
let plist = try? PropertyListSerialization.propertyList(from: data, format: nil) as? [String: Any],
let value = plist[key] as? String
{
return value
}
}
return ProcessInfo.processInfo.environment[key] ?? "invalid"
}
@@ -20,9 +20,9 @@ import Foundation
extension Date {
/**
Calculates a future date by applying an initial time buffer and then rounding up to the nearest specified minute interval.
Example:
```swift
let now = Date() // Assume current time is 10:07
let roundedDate = now.roundedUp(
@@ -31,7 +31,7 @@ extension Date {
)
// roundedDate will be 10:30
```
*/
func roundedUp(by minuteInterval: TimeInterval, withInitialBuffer bufferInMinutes: TimeInterval) -> Date {
let futureTime = addingTimeInterval(bufferInMinutes * 60)
@@ -35,7 +35,6 @@ enum DiscardDraftAlertAction: AlertActionInfo, CaseIterable {
}
}
enum ExpiringMessageUnsupportedAlertAction: AlertActionInfo, CaseIterable {
case sendAnyway
case addPassword
@@ -19,8 +19,7 @@ import UIKit
extension UIStackView {
func addArrangedSubviewWithInsets(_ view: UIView, insets: UIEdgeInsets)
{
func addArrangedSubviewWithInsets(_ view: UIView, insets: UIEdgeInsets) {
let container = UIView()
container.addSubview(view)
NSLayoutConstraint.activate([
@@ -69,7 +69,7 @@ final class DraftActionBarViewController: UIViewController {
}
stack.addArrangedSubview(passwordButton)
// stack.addArrangedSubview(expirationButton) // TODO: Enable when SDK is ready
// stack.addArrangedSubview(expirationButton) // TODO: Enable when SDK is ready
stack.addArrangedSubview(spacer)
stack.addArrangedSubview(discardButton)
attachmentButton.addTarget(self, action: #selector(onAttachmentTap), for: .touchUpInside)
@@ -34,8 +34,11 @@ private struct FileImporterModifier: ViewModifier {
extension View {
func fileImporter(isPresented: Binding<Bool>, onCompletion: @escaping (Result<[URL], any Error>) async -> Void) -> some View {
modifier(FileImporterModifier(isPresented: isPresented, onCompletion: { result in
Task { await onCompletion(result) }
}))
modifier(
FileImporterModifier(
isPresented: isPresented,
onCompletion: { result in
Task { await onCompletion(result) }
}))
}
}
@@ -40,7 +40,8 @@ extension PhotosItemFile: Transferable {
},
importing: { received in
let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
let tempFolder = cacheDirectory
let tempFolder =
cacheDirectory
.appendingPathComponent(tempDestinationFolderName, isDirectory: true)
.appendingPathComponent(UUID().uuidString, isDirectory: true)
try fileManager.createDirectory(at: tempFolder, withIntermediateDirectories: true)
@@ -152,7 +152,7 @@ protocol PhotosPickerItemTransferable {
extension PhotosPickerItem: PhotosPickerItemTransferable {}
private extension URL {
/// File of type HEIC. This type identifies pictures taken with the camera of the device
var isHeicType: Bool {
utType?.conforms(to: .heic) ?? false
@@ -166,7 +166,7 @@ private extension URL {
private var utType: UTType? {
do {
if let typeIdentifier = try resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier {
return UTType(typeIdentifier)
return UTType(typeIdentifier)
}
} catch {
AppLogger.log(error: error, category: .composer)
@@ -40,10 +40,11 @@ extension View {
additionallyObserving modalAction: Binding<ComposerViewModalState?>, // Change parameter
content: ComposerViewModalFactory
) -> some View {
modifier(ComposerModalModifier(
modalState: item,
modalAction: modalAction,
modalFactory: content
))
modifier(
ComposerModalModifier(
modalState: item,
modalAction: modalAction,
modalFactory: content
))
}
}
@@ -399,7 +399,7 @@ enum L10n {
}
static let failedToDecryptExternalEncryptionPassword = LocalizedStringResource(
"Failed to decrypt external encryption password", // FIXME: - To verify
"Failed to decrypt external encryption password", // FIXME: - To verify
comment: "Error in the context of scheduling a message."
)
@@ -73,7 +73,8 @@ final class FilePickerItemHandlerTests: XCTestCase {
}
func testAddSelectedFiles_whenThereIsAnErrorInTheResults_itShouldReturnError() async throws {
let error = NSError(domain: "".notLocalized, code: -1,
let error = NSError(
domain: "".notLocalized, code: -1,
userInfo: [NSLocalizedDescriptionKey: "the localised error".notLocalized]
)
await sut.addSelectedFiles(to: mockDraft, selectionResult: .failure(error), onErrors: mockOnErrors)
@@ -46,11 +46,12 @@ public struct ContactSuggestionsRepository {
// MARK: - Private
private func deviceContacts() -> [DeviceContact] {
let keys: [CNKeyDescriptor] = [
CNContactGivenNameKey,
CNContactFamilyNameKey,
CNContactEmailAddressesKey
] as [CNKeyDescriptor]
let keys: [CNKeyDescriptor] =
[
CNContactGivenNameKey,
CNContactFamilyNameKey,
CNContactEmailAddressesKey,
] as [CNKeyDescriptor]
let request = CNContactFetchRequest(keysToFetch: keys)
var contacts: [DeviceContact] = []
@@ -43,10 +43,11 @@ extension RustContactsWrappers {
}
public struct AllContactsProvider {
public let contactSuggestions: (
_ deviceContacts: [DeviceContact],
_ userSession: MailUserSession
) async -> ContactSuggestionsResult
public let contactSuggestions:
(
_ deviceContacts: [DeviceContact],
_ userSession: MailUserSession
) async -> ContactSuggestionsResult
public init(
contactSuggestions: @escaping ([DeviceContact], MailUserSession) async -> ContactSuggestionsResult
@@ -64,10 +65,11 @@ public struct GroupedContactsProvider {
}
public struct ContactsWatcher {
public let watch: (
_ session: MailUserSession,
_ callback: ContactsLiveQueryCallback
) async -> WatchContactListResult
public let watch:
(
_ session: MailUserSession,
_ callback: ContactsLiveQueryCallback
) async -> WatchContactListResult
}
extension GroupedContactsProvider {
@@ -80,7 +80,7 @@ final class ContactGroupCell: UITableViewCell {
iconImageView.centerXAnchor.constraint(equalTo: iconBackgroundView.centerXAnchor),
iconImageView.centerYAnchor.constraint(equalTo: iconBackgroundView.centerYAnchor),
iconImageView.widthAnchor.constraint(equalToConstant: 20),
iconImageView.heightAnchor.constraint(equalTo: iconImageView.widthAnchor)
iconImageView.heightAnchor.constraint(equalTo: iconImageView.widthAnchor),
])
}
@@ -59,7 +59,7 @@ final class ContactLabelsView: UIView {
stackView.topAnchor.constraint(equalTo: topAnchor),
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: trailingAnchor)
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
])
}
@@ -74,7 +74,7 @@ final class NoContactsPlaceholderView: UIView {
stackView.centerYAnchor.constraint(equalTo: centerYAnchor, constant: -40),
stackView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: trailingAnchor)
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
])
}
@@ -24,7 +24,7 @@ extension URL {
static func create(domain: String) -> URL {
url(domain: domain, path: "/inbox#create-contact")
}
static func edit(domain: String, id: String) -> URL {
static func edit(domain: String, id: String) -> URL {
url(domain: domain, path: "/inbox#edit-contact=:\(id)")
}
}
@@ -22,9 +22,7 @@ class CNContactStoreSpy: CNContactStoring {
static var stubbedAuthorizationStatus: [CNEntityType: CNAuthorizationStatus] = .default
private(set) var requestAccessCalls: [
(entityType: CNEntityType, completionHandler: (Bool, (any Error)?) -> Void)
] = []
private(set) var requestAccessCalls: [(entityType: CNEntityType, completionHandler: (Bool, (any Error)?) -> Void)] = []
private(set) var enumerateContactsCalls: [CNContactFetchRequest] = []
var stubbedEnumerateContacts: [CNContact] = []
var requestAccessCompletionBlockCalledImmediately: Bool = false
@@ -102,8 +102,7 @@ extension Event {
// Check for unhandled exceptions or for specific crash mechanisms
return exceptions.contains(where: {
$0.mechanism?.handled == false ||
["signal", "mach_exception", "uncaught_exception"].contains($0.mechanism?.type)
$0.mechanism?.handled == false || ["signal", "mach_exception", "uncaught_exception"].contains($0.mechanism?.type)
})
}
}
+14 -12
View File
@@ -21,7 +21,7 @@ import Combine
public typealias DispatchQueueScheduler = AnyScheduler<DispatchQueue.SchedulerTimeType>
public class AnyScheduler<SchedulerTimeType>: Scheduler
where SchedulerTimeType: Strideable, SchedulerTimeType.Stride: SchedulerTimeIntervalConvertible {
where SchedulerTimeType: Strideable, SchedulerTimeType.Stride: SchedulerTimeIntervalConvertible {
public typealias SchedulerOptions = Never
@@ -70,16 +70,18 @@ public class AnyScheduler<SchedulerTimeType>: Scheduler
private let _now: () -> SchedulerTimeType
private let _minimumTolerance: () -> SchedulerTimeType.Stride
private let _schedule_action: (@escaping () -> Void) -> Void
private let _schedule_after_tolerance_action: (
SchedulerTimeType,
SchedulerTimeType.Stride,
@escaping () -> Void
) -> Void
private let _schedule_after_interval_tolerance_action: (
SchedulerTimeType,
SchedulerTimeType.Stride,
SchedulerTimeType.Stride,
@escaping () -> Void
) -> Cancellable
private let _schedule_after_tolerance_action:
(
SchedulerTimeType,
SchedulerTimeType.Stride,
@escaping () -> Void
) -> Void
private let _schedule_after_interval_tolerance_action:
(
SchedulerTimeType,
SchedulerTimeType.Stride,
SchedulerTimeType.Stride,
@escaping () -> Void
) -> Cancellable
}
@@ -28,11 +28,11 @@ extension Bundle {
The effectiveAppVersion property returns the public-facing version of the app,
used for features such as human verification and bug reporting. It ensures that
the version is never reported as lower than "7.0.1" (the official initial release version).
Examples:
- If the version is "0.2.0", effectiveAppVersion returns "7.0.1" (minimum enforced version).
- If the version is "7.1.1" or "11.0.0", effectiveAppVersion returns the actual version ("7.1.1" or "11.0.0").
Once the app's internal version naturally reaches or exceeds "7.0.1", this property
will reflect the real app version, so we can get rid of it and start using bundleShortVersion.
*/
@@ -44,15 +44,15 @@ private struct DismissKey: EnvironmentKey {
func callAsFunction() {
let message = """
This should not be used at runtime. For testing purposes, please inject
a test double into the SwiftUI view using the `environment(_: _:)` function, specifying
the keyPath defined in the scope of `EnvironmentValues`, for example:
This should not be used at runtime. For testing purposes, please inject
a test double into the SwiftUI view using the `environment(_: _:)` function, specifying
the keyPath defined in the scope of `EnvironmentValues`, for example:
```
let sut: View = ...
sut.environment(\\.dismissable, DismissSpy())
```
"""
```
let sut: View = ...
sut.environment(\\.dismissable, DismissSpy())
```
"""
fatalError(message)
}
}
+2 -2
View File
@@ -21,8 +21,8 @@ import Foundation
func forceCast<Value, ExpectedType>(_ value: Value, _ type: ExpectedType.Type) -> ExpectedType {
guard let castedValue = value as? ExpectedType else {
let message = """
Could not cast value: <\(value)> of type: <\(Swift.type(of: value))> to expected type: <\(ExpectedType.self)>.
"""
Could not cast value: <\(value)> of type: <\(Swift.type(of: value))> to expected type: <\(ExpectedType.self)>.
"""
AppLogger.log(message: message)
fatalError(message)
}
@@ -34,4 +34,3 @@ extension DateFormatter {
}
}
@@ -27,7 +27,7 @@ public struct FormSection<Content: View>: View {
public init(
header: LocalizedStringResource? = nil,
footer: LocalizedStringResource? = nil,
@ViewBuilder content: @escaping () -> Content
@ViewBuilder content: @escaping () -> Content
) {
self.header = header
self.footer = footer
+1 -1
View File
@@ -7,7 +7,7 @@ let package = Package(
name: "InboxDesignSystem",
platforms: [.iOS(.v17)],
products: [
.library(name: "InboxDesignSystem", targets: ["InboxDesignSystem"]),
.library(name: "InboxDesignSystem", targets: ["InboxDesignSystem"])
],
targets: [
.target(name: "InboxDesignSystem", resources: [.process("Resources")])
@@ -49,4 +49,3 @@ private extension DescriptionEntitlement {
.init(type: .empty, text: text, iconName: iconName, hint: nil)
}
}
+2 -2
View File
@@ -7,11 +7,11 @@ let package = Package(
name: "InboxKeychain",
platforms: [.iOS(.v17)],
products: [
.library(name: "InboxKeychain", targets: ["InboxKeychain"]),
.library(name: "InboxKeychain", targets: ["InboxKeychain"])
],
dependencies: [
.package(path: "../InboxCore"),
.package(path: "../../ProtonPackages/proton_app_uniffi")
.package(path: "../../ProtonPackages/proton_app_uniffi"),
],
targets: [
.target(name: "InboxKeychain", dependencies: ["InboxCore", "proton_app_uniffi"]),
+5 -5
View File
@@ -212,7 +212,7 @@ open class Keychain {
kSecReturnData as String: kCFBooleanTrue,
kSecMatchLimit as String: kSecMatchLimitOne,
kSecAttrAccessGroup as String: self.accessGroup as AnyObject,
kSecAttrSynchronizable as String: kSecAttrSynchronizableAny
kSecAttrSynchronizable as String: kSecAttrSynchronizableAny,
]
if #available(macOS 10.15, tvOS 13.0, watchOS 6.0, macCatalyst 13.0, *) {
query[kSecUseDataProtectionKeychain as String] = kCFBooleanTrue
@@ -269,7 +269,7 @@ open class Keychain {
kSecAttrService as String: self.service as AnyObject,
kSecAttrAccount as String: key as AnyObject,
kSecAttrAccessGroup as String: self.accessGroup as AnyObject,
kSecAttrSynchronizable as String: kSecAttrSynchronizableAny
kSecAttrSynchronizable as String: kSecAttrSynchronizableAny,
]
if #available(macOS 10.15, tvOS 13.0, watchOS 6.0, macCatalyst 13.0, *) {
query[kSecUseDataProtectionKeychain as String] = kCFBooleanTrue
@@ -303,7 +303,7 @@ open class Keychain {
kSecAttrService as String: self.service as AnyObject,
kSecAttrAccount as String: key as AnyObject,
kSecAttrAccessGroup as String: self.accessGroup as AnyObject,
kSecAttrSynchronizable as String: kSecAttrSynchronizableAny
kSecAttrSynchronizable as String: kSecAttrSynchronizableAny,
]
if #available(macOS 10.15, tvOS 13.0, watchOS 6.0, macCatalyst 13.0, *) {
query[kSecUseDataProtectionKeychain as String] = kCFBooleanTrue
@@ -329,7 +329,7 @@ open class Keychain {
guard codeExisting == errSecItemNotFound else {
var updateAttributes: [String: AnyObject] = [
kSecAttrSynchronizable as String: NSNumber(value: false),
kSecValueData as String: value as AnyObject
kSecValueData as String: value as AnyObject,
]
self.injectAccessControlAttributes(into: &updateAttributes)
@@ -370,7 +370,7 @@ open class Keychain {
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: self.service as AnyObject,
kSecAttrAccessGroup as String: self.accessGroup as AnyObject,
kSecAttrSynchronizable as String: kSecAttrSynchronizableAny
kSecAttrSynchronizable as String: kSecAttrSynchronizableAny,
]
if #available(macOS 10.15, tvOS 13.0, watchOS 6.0, macCatalyst 13.0, *) {
query[kSecUseDataProtectionKeychain as String] = kCFBooleanTrue
@@ -21,7 +21,7 @@ import proton_app_uniffi
extension RsvpEvent {
static func testData(
id: String? = .none,
id: String? = .none,
summary: String? = .none,
startsAt: UnixTimestamp = .zero,
organizer: RsvpOrganizer = .init(name: .empty, email: .empty),
@@ -40,8 +40,8 @@ public class DispatchQueueImmediateScheduler: Scheduler {
after date: DispatchQueue.SchedulerTimeType,
tolerance: DispatchQueue.SchedulerTimeType.Stride,
options: DispatchQueue.SchedulerOptions?,
_ action: @escaping () -> Void)
{
_ action: @escaping () -> Void
) {
action()
}
@@ -7,12 +7,12 @@ let package = Package(
name: "TestableNotificationService",
platforms: [.iOS(.v17)],
products: [
.library(name: "TestableNotificationService", targets: ["TestableNotificationService"]),
.library(name: "TestableNotificationService", targets: ["TestableNotificationService"])
],
dependencies: [
.package(path: "../InboxCore"),
.package(path: "../InboxKeychain"),
.package(path: "../../ProtonPackages/proton_app_uniffi")
.package(path: "../../ProtonPackages/proton_app_uniffi"),
],
targets: [
.target(name: "TestableNotificationService", dependencies: ["InboxCore", "InboxKeychain", "proton_app_uniffi"]),
@@ -25,7 +25,8 @@ enum L10n {
static let messageSent = LocalizedStringResource("Message sent!", bundle: .module, comment: "Alert shown after the message has been sent")
}
static let needToSignIn = LocalizedStringResource("You need to sign-in to Proton Mail to share content.", bundle: .module, comment: "Error message when attempting to use the Share extension without being logged in")
static let needToSignIn = LocalizedStringResource(
"You need to sign-in to Proton Mail to share content.", bundle: .module, comment: "Error message when attempting to use the Share extension without being logged in")
static let openApp = LocalizedStringResource("Open Proton Mail", bundle: .module, comment: "Button to open the main app from the Share extension")
}
+16 -7
View File
@@ -136,7 +136,22 @@ targets:
platform: iOS
supportedDestinations:
- iOS
scheme: {}
scheme:
preActions:
- name: swift-format
script: |
if [ $ACTION == "build" ]; then
cd "$SRCROOT"
xcrun swift-format format -r Modules -p -i
fi
settingsTarget: ProtonMail
- name: Sourcery
script: |
if [ $ACTION == "build" ]; then
cd "$SRCROOT"
find sourcery/configs -name "*.yaml" -exec /opt/homebrew/bin/mint run sourcery --config {} \;
fi
settingsTarget: ProtonMail
sources:
- path: Modules/App/Sources
settings:
@@ -211,12 +226,6 @@ targets:
- package: Scrypt
- target: ShareExtension
- package: SwiftUIIntrospect
preBuildScripts:
- name: swift-format
script: xcrun swift-format lint -r Modules -p
basedOnDependencyAnalysis: false
- name: Sourcery
script: find sourcery/configs -name "*.yaml" -exec /opt/homebrew/bin/mint run sourcery --config {} \;
ProtonMailTest:
type: bundle.unit-test