Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Delete profile" in profile editor #1160

Merged
merged 5 commits into from
Feb 10, 2025
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 @@ -34,8 +34,21 @@ extension EnvironmentValues {
self[NavigationPathKey.self] = newValue
}
}

var dismissProfile: () -> Void {
get {
self[DismissProfileKey.self]
}
set {
self[DismissProfileKey.self] = newValue
}
}
}

private struct NavigationPathKey: EnvironmentKey {
static let defaultValue: Binding<NavigationPath> = .constant(NavigationPath())
}

private struct DismissProfileKey: EnvironmentKey {
static let defaultValue: () -> Void = {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,11 @@ private extension ProfileContextMenu {
}

var profileRemoveButton: some View {
ProfileRemoveButton(
profileManager: profileManager,
preview: preview
) {
Button(role: .destructive) {
Task {
await profileManager.remove(withId: preview.id)
}
} label: {
ThemeImageLabel(Strings.Global.Actions.remove, .contextRemove)
}
}
Expand Down
45 changes: 0 additions & 45 deletions Packages/App/Sources/AppUIMain/Views/App/ProfileRemoveButton.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ struct ModuleViewModifier<T>: ViewModifier where T: ModuleBuilder & Equatable {
content
#if DEBUG
if !isUITesting {
UUIDSection(uuid: draft.id)
Section {
UUIDText(uuid: draft.id)
}
}
#endif
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// ProfileActionsSection.swift
// Passepartout
//
// Created by Davide De Rosa on 2/10/25.
// Copyright (c) 2025 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of Passepartout.
//
// Passepartout is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Passepartout is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
//

import CommonLibrary
import PassepartoutKit
import SwiftUI

struct ProfileActionsSection: View {

@Environment(\.dismissProfile)
private var dismissProfile

let profileManager: ProfileManager

let profileEditor: ProfileEditor

@State
private var isConfirmingDeletion = false

var body: some View {
#if os(iOS)
Section {
UUIDText(uuid: profileId)
}
Section {
removeContent
.frame(maxWidth: .infinity, alignment: .center)
}
#else
UUIDText(uuid: profileId)
.asSectionWithTrailingContent {
removeContent
}
#endif
}
}

private extension ProfileActionsSection {
var removeContent: some View {
profileManager.profile(withId: profileId)
.map { _ in
removeButton
.themeConfirmation(
isPresented: $isConfirmingDeletion,
title: Strings.Global.Actions.delete,
isDestructive: true,
action: {
Task {
dismissProfile()
await profileManager.remove(withId: profileId)
}
}
)
}
}

var removeButton: some View {
Button(Strings.Views.Profile.Rows.deleteProfile, role: .destructive) {
isConfirmingDeletion = true
}
}
}

private extension ProfileActionsSection {
var profileId: Profile.ID {
profileEditor.profile.id
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ struct ProfileCoordinator: View {
var body: some View {
contentView
.modifier(PaywallModifier(reason: $paywallReason))
.environment(\.dismissProfile, onDismiss)
.withErrorHandler(errorHandler)
}
}
Expand All @@ -80,6 +81,7 @@ private extension ProfileCoordinator {
var contentView: some View {
#if os(iOS)
ProfileEditView(
profileManager: profileManager,
profileEditor: profileEditor,
initialModuleId: initialModuleId,
moduleViewFactory: moduleViewFactory,
Expand All @@ -95,6 +97,7 @@ private extension ProfileCoordinator {
.themeNavigationStack(path: $path)
#else
ProfileSplitView(
profileManager: profileManager,
profileEditor: profileEditor,
initialModuleId: initialModuleId,
moduleViewFactory: moduleViewFactory,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// UUIDSection.swift
// UUIDText.swift
// Passepartout
//
// Created by Davide De Rosa on 11/4/24.
Expand All @@ -25,19 +25,17 @@

import SwiftUI

struct UUIDSection: View {
struct UUIDText: View {
let uuid: UUID

var body: some View {
Section {
ThemeCopiableText(
title: Strings.Unlocalized.uuid,
value: uuid,
valueView: {
Text($0.flatString.localizedDescription(style: .quartets))
.monospaced()
}
)
}
ThemeCopiableText(
title: Strings.Unlocalized.uuid,
value: uuid,
valueView: {
Text($0.flatString.localizedDescription(style: .quartets))
.monospaced()
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import PassepartoutKit
import SwiftUI

struct ProfileEditView: View, Routable {
let profileManager: ProfileManager

@ObservedObject
var profileEditor: ProfileEditor
Expand Down Expand Up @@ -62,7 +63,10 @@ struct ProfileEditView: View, Routable {
paywallReason: $paywallReason
)
ProfileBehaviorSection(profileEditor: profileEditor)
UUIDSection(uuid: profileEditor.profile.id)
ProfileActionsSection(
profileManager: profileManager,
profileEditor: profileEditor
)
}
.toolbar(content: toolbarContent)
.navigationTitle(Strings.Global.Nouns.profile)
Expand Down Expand Up @@ -187,6 +191,7 @@ private extension ProfileEditView {
#Preview {
NavigationStack {
ProfileEditView(
profileManager: .forPreviews,
profileEditor: ProfileEditor(profile: .newMockProfile()),
initialModuleId: nil,
moduleViewFactory: DefaultModuleViewFactory(registry: Registry()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import CommonLibrary
import SwiftUI

struct ProfileGeneralView: View {
let profileManager: ProfileManager

@ObservedObject
var profileEditor: ProfileEditor
Expand All @@ -44,14 +45,18 @@ struct ProfileGeneralView: View {
paywallReason: $paywallReason
)
ProfileBehaviorSection(profileEditor: profileEditor)
UUIDSection(uuid: profileEditor.profile.id)
ProfileActionsSection(
profileManager: profileManager,
profileEditor: profileEditor
)
}
.themeForm()
}
}

#Preview {
ProfileGeneralView(
profileManager: .forPreviews,
profileEditor: ProfileEditor(),
paywallReason: .constant(nil)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import PassepartoutKit
import SwiftUI

struct ProfileSplitView: View, Routable {
let profileManager: ProfileManager

let profileEditor: ProfileEditor

let initialModuleId: UUID?
Expand Down Expand Up @@ -124,6 +126,7 @@ private extension ProfileSplitView {
switch detail {
case .general:
ProfileGeneralView(
profileManager: profileManager,
profileEditor: profileEditor,
paywallReason: $paywallReason
)
Expand All @@ -140,6 +143,7 @@ private extension ProfileSplitView {

#Preview {
ProfileSplitView(
profileManager: .forPreviews,
profileEditor: ProfileEditor(profile: .newMockProfile()),
initialModuleId: nil,
moduleViewFactory: DefaultModuleViewFactory(registry: Registry()),
Expand Down
2 changes: 2 additions & 0 deletions Packages/App/Sources/UILibrary/L10n/SwiftGen+Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,8 @@ public enum Strings {
public enum Rows {
/// Add module
public static let addModule = Strings.tr("Localizable", "views.profile.rows.add_module", fallback: "Add module")
/// Delete profile
public static let deleteProfile = Strings.tr("Localizable", "views.profile.rows.delete_profile", fallback: "Delete profile")
}
public enum Sections {
public enum Name {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"views.profile.alerts.purchase.buttons.ok" = "Trotzdem speichern";
"views.profile.module_list.section.footer" = "Tippen Sie auf Module, um ihre Einstellungen zu bearbeiten. Module können gezogen werden, um die Priorität festzulegen.";
"views.profile.rows.add_module" = "Modul hinzufügen";
"views.profile.rows.delete_profile" = "Profil löschen";
"views.profile.sections.name.footer" = "Verwenden Sie diesen Namen, um Ihre VPN-Automationen in der Kurzbefehle-App zu erstellen.";
"views.providers.clear_filters" = "Filter löschen";
"views.providers.last_updated" = "Zuletzt aktualisiert am %@";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"views.profile.alerts.purchase.buttons.ok" = "Αποθήκευση ούτως ή άλλως";
"views.profile.module_list.section.footer" = "Πατήστε σε ένα module για να επεξεργαστείτε τις ρυθμίσεις του. Τα modules μπορούν να μετακινηθούν για να καθορίσετε την προτεραιότητά τους.";
"views.profile.rows.add_module" = "Προσθήκη μονάδας";
"views.profile.rows.delete_profile" = "Διαγραφή προφίλ";
"views.profile.sections.name.footer" = "Χρησιμοποιήστε αυτό το όνομα για να δημιουργήσετε αυτοματισμούς VPN στην εφαρμογή Συντομεύσεις.";
"views.providers.clear_filters" = "Καθαρισμός φίλτρων";
"views.providers.last_updated" = "Τελευταία ενημέρωση στις %@";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@

"views.profile.sections.name.footer" = "Use this name to create your VPN automations from the Shortcuts app.";
"views.profile.rows.add_module" = "Add module";
"views.profile.rows.delete_profile" = "Delete profile";
"views.profile.module_list.section.footer" = "Tap modules to edit their settings. Modules may be dragged to determine priority.";
"views.profile.alerts.purchase.buttons.ok" = "Save anyway";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"views.profile.alerts.purchase.buttons.ok" = "Guardar de todos modos";
"views.profile.module_list.section.footer" = "Toca los módulos para editar su configuración. Se pueden arrastrar para establecer la prioridad.";
"views.profile.rows.add_module" = "Añadir módulo";
"views.profile.rows.delete_profile" = "Eliminar perfil";
"views.profile.sections.name.footer" = "Usa este nombre para crear automatizaciones VPN en la app Atajos.";
"views.providers.clear_filters" = "Borrar filtros";
"views.providers.last_updated" = "Última actualización el %@";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"views.profile.alerts.purchase.buttons.ok" = "Enregistrer quand même";
"views.profile.module_list.section.footer" = "Touchez les modules pour modifier leurs paramètres. Ils peuvent être glissés pour définir leur priorité.";
"views.profile.rows.add_module" = "Ajouter un module";
"views.profile.rows.delete_profile" = "Supprimer le profil";
"views.profile.sections.name.footer" = "Utilisez ce nom pour créer vos automatisations VPN dans l'app Raccourcis.";
"views.providers.clear_filters" = "Effacer les filtres";
"views.providers.last_updated" = "Dernière mise à jour le %@";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"views.profile.alerts.purchase.buttons.ok" = "Salva comunque";
"views.profile.module_list.section.footer" = "Tocca i moduli per modificarne le impostazioni. Possono essere trascinati per determinare la priorità.";
"views.profile.rows.add_module" = "Aggiungi modulo";
"views.profile.rows.delete_profile" = "Elimina profilo";
"views.profile.sections.name.footer" = "Usa questo nome per creare le automazioni VPN nell'app Comandi Rapidi.";
"views.providers.clear_filters" = "Cancella filtri";
"views.providers.last_updated" = "Ultimo aggiornamento il %@";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"views.profile.alerts.purchase.buttons.ok" = "Toch opslaan";
"views.profile.module_list.section.footer" = "Tik op modules om hun instellingen te bewerken. Modules kunnen worden versleept om de prioriteit te bepalen.";
"views.profile.rows.add_module" = "Module toevoegen";
"views.profile.rows.delete_profile" = "Verwijder profiel";
"views.profile.sections.name.footer" = "Gebruik deze naam om uw VPN-automatiseringen in de app Opdrachten te maken.";
"views.providers.clear_filters" = "Filters wissen";
"views.providers.last_updated" = "Laatst bijgewerkt op %@";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"views.profile.alerts.purchase.buttons.ok" = "Zapisz mimo to";
"views.profile.module_list.section.footer" = "Stuknij moduły, aby edytować ich ustawienia. Można je przeciągnąć, aby ustalić priorytet.";
"views.profile.rows.add_module" = "Dodaj moduł";
"views.profile.rows.delete_profile" = "Usuń profil";
"views.profile.sections.name.footer" = "Użyj tej nazwy, aby tworzyć automatyzacje VPN w aplikacji Skróty.";
"views.providers.clear_filters" = "Wyczyść filtry";
"views.providers.last_updated" = "Ostatnia aktualizacja: %@";
Expand Down
Loading
Loading