diff --git a/InfoPlist.xcstrings b/InfoPlist.xcstrings index 93ef15b..49ba53d 100644 --- a/InfoPlist.xcstrings +++ b/InfoPlist.xcstrings @@ -8,7 +8,7 @@ "en" : { "stringUnit" : { "state" : "new", - "value" : "addy.io (DEBUG)" + "value" : "addy.io" } } } diff --git a/addy.xcodeproj/project.pbxproj b/addy.xcodeproj/project.pbxproj index 8be3cbb..b66967b 100644 --- a/addy.xcodeproj/project.pbxproj +++ b/addy.xcodeproj/project.pbxproj @@ -1606,7 +1606,7 @@ CODE_SIGN_ENTITLEMENTS = AddyStatisticWidgetExtension.debug.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 83RFSJ6CUP; ENABLE_USER_SCRIPT_SANDBOXING = YES; GENERATE_INFOPLIST_FILE = YES; @@ -1620,7 +1620,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 0.3; + MARKETING_VERSION = 0.4; PRODUCT_BUNDLE_IDENTIFIER = host.stjin.addy.debug.AddyStatisticWidget; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -1638,7 +1638,7 @@ CODE_SIGN_ENTITLEMENTS = AddyStatisticWidgetExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 83RFSJ6CUP; ENABLE_USER_SCRIPT_SANDBOXING = YES; GENERATE_INFOPLIST_FILE = YES; @@ -1652,7 +1652,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 0.3; + MARKETING_VERSION = 0.4; PRODUCT_BUNDLE_IDENTIFIER = host.stjin.addy.AddyStatisticWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1669,7 +1669,7 @@ CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.debug.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 83RFSJ6CUP; ENABLE_USER_SCRIPT_SANDBOXING = YES; GENERATE_INFOPLIST_FILE = YES; @@ -1683,7 +1683,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 0.3; + MARKETING_VERSION = 0.4; PRODUCT_BUNDLE_IDENTIFIER = host.stjin.addy.debug.AddyShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1700,7 +1700,7 @@ CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 83RFSJ6CUP; ENABLE_USER_SCRIPT_SANDBOXING = YES; GENERATE_INFOPLIST_FILE = YES; @@ -1714,7 +1714,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 0.3; + MARKETING_VERSION = 0.4; PRODUCT_BUNDLE_IDENTIFIER = host.stjin.addy.AddyShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1859,7 +1859,7 @@ CODE_SIGN_ENTITLEMENTS = addy/addy.debug.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_ASSET_PATHS = "\"addy/Preview Content\""; DEVELOPMENT_TEAM = 83RFSJ6CUP; ENABLE_PREVIEWS = YES; @@ -1879,7 +1879,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 0.3; + MARKETING_VERSION = 0.4; PRODUCT_BUNDLE_IDENTIFIER = host.stjin.addy.debug; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1898,13 +1898,13 @@ CODE_SIGN_ENTITLEMENTS = addy/addy.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_ASSET_PATHS = "\"addy/Preview Content\""; DEVELOPMENT_TEAM = 83RFSJ6CUP; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = addy/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "addy.io (DEBUG)"; + INFOPLIST_KEY_CFBundleDisplayName = addy.io; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; INFOPLIST_KEY_NSCameraUsageDescription = "This allows for scanning the QR code so that you can quickly set-up the app"; INFOPLIST_KEY_NSFaceIDUsageDescription = "This permissions is required to protect the app using FaceID"; @@ -1918,7 +1918,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 0.3; + MARKETING_VERSION = 0.4; PRODUCT_BUNDLE_IDENTIFIER = host.stjin.addy; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/addy.xcodeproj/project.xcworkspace/xcuserdata/stjin.xcuserdatad/UserInterfaceState.xcuserstate b/addy.xcodeproj/project.xcworkspace/xcuserdata/stjin.xcuserdatad/UserInterfaceState.xcuserstate index a7ce7a9..5e31b9d 100644 Binary files a/addy.xcodeproj/project.xcworkspace/xcuserdata/stjin.xcuserdatad/UserInterfaceState.xcuserstate and b/addy.xcodeproj/project.xcworkspace/xcuserdata/stjin.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/addy.xcodeproj/xcuserdata/stjin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/addy.xcodeproj/xcuserdata/stjin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 2a6eb0c..55f2d15 100644 --- a/addy.xcodeproj/xcuserdata/stjin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/addy.xcodeproj/xcuserdata/stjin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -4894,8 +4894,8 @@ filePath = "addy/View/aliases/AliasesView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "579" - endingLineNumber = "579" + startingLineNumber = "616" + endingLineNumber = "616" landmarkName = "onPressSend(client:sendToRecipients:)" landmarkType = "7"> @@ -4910,8 +4910,8 @@ filePath = "addy/View/aliases/AliasesView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "582" - endingLineNumber = "582" + startingLineNumber = "619" + endingLineNumber = "619" landmarkName = "onPressSend(client:sendToRecipients:)" landmarkType = "7"> @@ -4926,8 +4926,8 @@ filePath = "addy/View/aliases/AliasesView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "133" - endingLineNumber = "133" + startingLineNumber = "170" + endingLineNumber = "170" landmarkName = "body" landmarkType = "24"> @@ -4942,8 +4942,8 @@ filePath = "addy/View/aliases/AliasesView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "566" - endingLineNumber = "566" + startingLineNumber = "603" + endingLineNumber = "603" landmarkName = "onPressSend(client:sendToRecipients:)" landmarkType = "7"> @@ -4958,8 +4958,8 @@ filePath = "addy/View/aliases/AliasesView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "567" - endingLineNumber = "567" + startingLineNumber = "604" + endingLineNumber = "604" landmarkName = "onPressSend(client:sendToRecipients:)" landmarkType = "7"> @@ -4974,8 +4974,8 @@ filePath = "addy/View/aliases/AliasesView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "572" - endingLineNumber = "572" + startingLineNumber = "609" + endingLineNumber = "609" landmarkName = "onPressSend(client:sendToRecipients:)" landmarkType = "7"> @@ -4990,8 +4990,8 @@ filePath = "addy/View/aliases/AliasesView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "575" - endingLineNumber = "575" + startingLineNumber = "612" + endingLineNumber = "612" landmarkName = "onPressSend(client:sendToRecipients:)" landmarkType = "7"> @@ -5006,8 +5006,8 @@ filePath = "addy/View/aliases/AliasesView.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "576" - endingLineNumber = "576" + startingLineNumber = "613" + endingLineNumber = "613" landmarkName = "onPressSend(client:sendToRecipients:)" landmarkType = "7"> diff --git a/addy.xcodeproj/xcuserdata/stjin.xcuserdatad/xcschemes/xcschememanagement.plist b/addy.xcodeproj/xcuserdata/stjin.xcuserdatad/xcschemes/xcschememanagement.plist index c48ead7..6be0c19 100644 --- a/addy.xcodeproj/xcuserdata/stjin.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/addy.xcodeproj/xcuserdata/stjin.xcuserdatad/xcschemes/xcschememanagement.plist @@ -19,7 +19,7 @@ Periphery.xcscheme_^#shared#^_ orderHint - 5 + 6 Playground (Playground) 1.xcscheme @@ -45,7 +45,7 @@ Privacy Manifest.xcscheme_^#shared#^_ orderHint - 6 + 5 ShareExtension.xcscheme_^#shared#^_ diff --git a/addy/AppIntent/CreateNewCustomAliasIntent.swift b/addy/AppIntent/CreateNewCustomAliasIntent.swift index 230b282..2759e46 100644 --- a/addy/AppIntent/CreateNewCustomAliasIntent.swift +++ b/addy/AppIntent/CreateNewCustomAliasIntent.swift @@ -15,7 +15,7 @@ import UniformTypeIdentifiers struct CreateNewCustomAliasIntent: AppIntent { static var title: LocalizedStringResource = "app_intent_add_alias_custom" - static var description: IntentDescription = .init("app_intent_add_alias_desc", categoryName: "app_intent_category_name", searchKeywords: ["add", "create", "alias", "email"]) + static var description: IntentDescription = .init("app_intent_add_alias_desc", categoryName: "app_intent_category_name", searchKeywords: ["add", "create", "alias", "email"], resultValueName: "app_intent_alias_output") static var openAppWhenRun: Bool = false @Parameter(title: "app_intent_add_alias_parameter_domain", diff --git a/addy/Localizable.xcstrings b/addy/Localizable.xcstrings index e4c686c..9503f11 100644 --- a/addy/Localizable.xcstrings +++ b/addy/Localizable.xcstrings @@ -904,7 +904,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "new alias email address" + "value" : "email address" } } } @@ -3299,17 +3299,6 @@ } } }, - "hold_the_drag_handle_and_drag_to_change_order" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Hold the drag handle and drag to change order" - } - } - } - }, "home" : { "extractionState" : "manual", "localizations" : { @@ -4857,6 +4846,17 @@ } } }, + "rules_view_explanation" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Hold the drag handle and drag to change order\nSwipe right on a rule to enable or disable this rule" + } + } + } + }, "run_rule_on" : { "extractionState" : "manual", "localizations" : { @@ -5771,6 +5771,17 @@ } } }, + "system_default" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "System default" + } + } + } + }, "tap_here_to_see_the_error" : { "extractionState" : "manual", "localizations" : { diff --git a/addy/View/aliases/AliasesView.swift b/addy/View/aliases/AliasesView.swift index 77567a0..9331e48 100644 --- a/addy/View/aliases/AliasesView.swift +++ b/addy/View/aliases/AliasesView.swift @@ -43,7 +43,7 @@ struct AliasesView: View { @State private var sendToRecipients: String? = nil @State private var clients: [ThirdPartyMailClient] = [] @State private var isPresentingEmailSelectionDialog: Bool = false - + @Environment(\.scenePhase) var scenePhase @@ -76,19 +76,56 @@ struct AliasesView: View { ForEach(aliasList.data) { alias in createAliasRow(alias: alias) - }.onDelete(perform: deleteAlias) + .swipeActions { + Button(role: .destructive) { + if let index = aliasList.data.firstIndex(of: alias) { + if alias.deleted_at != nil { + forgetAlias(at: IndexSet(integer: index)) + } else { + deleteAlias(at: IndexSet(integer: index)) + } + } + } label: { + if alias.deleted_at != nil { + Text(String(localized: "forget")) + } else { + Text(String(localized: "delete")) + } + + } + } + } -// let columns = Array(repeating: GridItem(.flexible(), spacing: 20), count: 2) -// LazyVGrid(columns: columns, spacing: 20) { -// ForEach(aliasList.data) { alias in -// createAliasRow(alias: alias) -// }.onDelete(perform: deleteAlias) -// } + // let columns = Array(repeating: GridItem(.flexible(), spacing: 20), count: 2) + // LazyVGrid(columns: columns, spacing: 20) { + // ForEach(aliasList.data) { alias in + // createAliasRow(alias: alias) + // }.onDelete(perform: deleteAlias) + // } } else { // iPhone and smaller devices ForEach(aliasList.data) { alias in createAliasRow(alias: alias) - }.onDelete(perform: deleteAlias) + .swipeActions { + Button(role: .destructive) { + if let index = aliasList.data.firstIndex(of: alias) { + if alias.deleted_at != nil { + forgetAlias(at: IndexSet(integer: index)) + } else { + deleteAlias(at: IndexSet(integer: index)) + } + } + } label: { + if alias.deleted_at != nil { + Text(String(localized: "forget")) + } else { + Text(String(localized: "delete")) + } + + } + } + } + } }header: { @@ -270,9 +307,9 @@ struct AliasesView: View { .textInputAutocapitalization(.never) .navigationDestination(item: $mainViewState.aliasToDisable, destination: { aliasToDisable in NavigationStack(){ - AliasDetailView(aliasId: aliasToDisable, aliasEmail: nil, shouldReloadDataInParent: nil, shouldDisableAlias: true) - .environmentObject(mainViewState) - } + AliasDetailView(aliasId: aliasToDisable, aliasEmail: nil, shouldReloadDataInParent: nil, shouldDisableAlias: true) + .environmentObject(mainViewState) + } }) .navigationDestination(item: $mainViewState.showAliasWithId, destination: { showAliasWithId in NavigationStack(){ @@ -554,7 +591,7 @@ struct AliasesView: View { aliasesViewModel.aliasSortFilterRequest.filter = self.aliasesViewModel.searchQuery } - + private func onPressSend(client: ThirdPartyMailClient? = nil, sendToRecipients: String) { @@ -562,7 +599,7 @@ struct AliasesView: View { // return if both are nil guard let alias = aliasToSendMailFrom ?? aliasToSendMailFromCopy else {return} - + if client == nil { isPresentingEmailSelectionDialog = true self.sendToRecipients = sendToRecipients @@ -621,23 +658,23 @@ struct AliasesView: View { } private func deleteAlias(alias: Aliases) async { - let networkHelper = NetworkHelper() - do { - let result = try await networkHelper.deleteAlias(aliasId: alias.id) - if result == "204" { - await aliasesViewModel.getAliases(forceReload: true) - } else { - activeAlert = .error - showAlert = true - errorAlertTitle = String(localized: "error_forgetting_alias") - errorAlertMessage = result - } - } catch { + let networkHelper = NetworkHelper() + do { + let result = try await networkHelper.deleteAlias(aliasId: alias.id) + if result == "204" { + await aliasesViewModel.getAliases(forceReload: true) + } else { activeAlert = .error showAlert = true errorAlertTitle = String(localized: "error_forgetting_alias") - errorAlertMessage = error.localizedDescription + errorAlertMessage = result } + } catch { + activeAlert = .error + showAlert = true + errorAlertTitle = String(localized: "error_forgetting_alias") + errorAlertMessage = error.localizedDescription + } } @@ -661,25 +698,37 @@ struct AliasesView: View { errorAlertMessage = error.localizedDescription } } - - - func deleteAlias(at offsets: IndexSet) { + + + + private func deleteAlias(at offsets: IndexSet) { for index in offsets.sorted(by: >) { + if let aliases = aliasesViewModel.aliasList?.data { let item = aliases[index] aliasInContextMenu = item - - if item.deleted_at != nil { - // Alias already deleted, prompt user to forget alias - activeAlert = .forgetAlias - } else { - activeAlert = .deleteAlias - } + + activeAlert = .deleteAlias showAlert = true // Remove from the collection for the smooth animation aliasesViewModel.aliasList?.data.remove(atOffsets: offsets) + } + } + } + + private func forgetAlias(at offsets: IndexSet) { + for index in offsets.sorted(by: >) { + + if let aliases = aliasesViewModel.aliasList?.data { + let item = aliases[index] + aliasInContextMenu = item + + activeAlert = .forgetAlias + showAlert = true + // Remove from the collection for the smooth animation + aliasesViewModel.aliasList?.data.remove(atOffsets: offsets) } } } diff --git a/addy/View/rules/RulesView.swift b/addy/View/rules/RulesView.swift index c78cfe7..9bc1271 100644 --- a/addy/View/rules/RulesView.swift +++ b/addy/View/rules/RulesView.swift @@ -212,7 +212,7 @@ struct RulesView: View { Text(String(format: String(localized: "you_ve_used_d_out_of_d_rules"), String(rule_count), (mainViewState.userResource!.subscription != nil ? String(rule_limit! /* Cannot be nil since subscription is not nil */ ) : String(localized: "unlimited")))) - Text(String(localized: "hold_the_drag_handle_and_drag_to_change_order")) + Text(String(localized: "rules_view_explanation")).padding(.top) }.padding(.top) } diff --git a/addy_shared/addy_shared/managers/SettingsManager.swift b/addy_shared/addy_shared/managers/SettingsManager.swift index 0de7f26..6b03a1b 100644 --- a/addy_shared/addy_shared/managers/SettingsManager.swift +++ b/addy_shared/addy_shared/managers/SettingsManager.swift @@ -239,7 +239,6 @@ public class SettingsManager { public func clearSettingsAndCloseApp(){ // Clear shortcuts - DispatchQueue.main.async { UIApplication.shared.shortcutItems = [] }