Refactor and move entities around (#698)

Do some housekeeping in AppLibrary/AppUI.
This commit is contained in:
Davide 2024-10-06 19:19:16 +02:00 committed by GitHub
parent f4505d0efd
commit 504bcbdbd2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 117 additions and 34 deletions

View File

@ -1,5 +1,5 @@
// //
// ProfileManagerProviding.swift // ProfileManager+Extensions.swift
// Passepartout // Passepartout
// //
// Created by Davide De Rosa on 9/3/24. // Created by Davide De Rosa on 9/3/24.
@ -27,22 +27,16 @@ import AppLibrary
import Foundation import Foundation
import PassepartoutKit import PassepartoutKit
protocol ProfileManagerProviding {
var profileManager: ProfileManager { get }
}
@MainActor @MainActor
extension ProfileManagerProviding { extension ProfileManager {
func removeProfiles(at offsets: IndexSet) { func removeProfiles(at offsets: IndexSet) async {
let idsToRemove = profileManager.headers let idsToRemove = headers
.enumerated() .enumerated()
.filter { .filter {
offsets.contains($0.offset) offsets.contains($0.offset)
} }
.map(\.element.id) .map(\.element.id)
Task { await remove(withIds: idsToRemove)
await profileManager.remove(withIds: idsToRemove)
}
} }
} }

View File

@ -0,0 +1,31 @@
//
// ProfileProcessor.swift
// Passepartout
//
// Created by Davide De Rosa on 10/6/24.
// Copyright (c) 2024 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 Foundation
import PassepartoutKit
protocol ProfileProcessor {
func processedProfile(_ profile: Profile) throws -> Profile
}

View File

@ -27,10 +27,7 @@ import CommonLibrary
import Foundation import Foundation
import PassepartoutKit import PassepartoutKit
protocol ProfileProcessor { @MainActor
func processedProfile(_ profile: Profile) throws -> Profile
}
extension Tunnel { extension Tunnel {
func install(_ profile: Profile, processor: ProfileProcessor) async throws { func install(_ profile: Profile, processor: ProfileProcessor) async throws {
let newProfile = try processor.processedProfile(profile) let newProfile = try processor.processedProfile(profile)

View File

@ -25,7 +25,7 @@
import Foundation import Foundation
public enum ProfilesLayout: String, RawRepresentable, CaseIterable, Codable { enum ProfilesLayout: String, RawRepresentable, CaseIterable, Codable {
case list case list
case grid case grid

View File

@ -0,0 +1,33 @@
//
// TunnelInstallation.swift
// Passepartout
//
// Created by Davide De Rosa on 10/6/24.
// Copyright (c) 2024 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 Foundation
import PassepartoutKit
struct TunnelInstallation {
let header: ProfileHeader
let onDemand: Bool
}

View File

@ -28,7 +28,7 @@ import PassepartoutKit
import SwiftUI import SwiftUI
import UtilsLibrary import UtilsLibrary
struct ProfileGridView: View, ProfileManagerProviding, TunnelInstallationProviding { struct ProfileGridView: View, TunnelInstallationProviding {
@Environment(\.isSearching) @Environment(\.isSearching)
private var isSearching private var isSearching
@ -61,7 +61,11 @@ struct ProfileGridView: View, ProfileManagerProviding, TunnelInstallationProvidi
} }
LazyVGrid(columns: columns) { LazyVGrid(columns: columns) {
ForEach(allHeaders, content: profileView) ForEach(allHeaders, content: profileView)
.onDelete(perform: removeProfiles) .onDelete { offsets in
Task {
await profileManager.removeProfiles(at: offsets)
}
}
} }
.themeGridHeader(title: Strings.Views.Profiles.Folders.default) .themeGridHeader(title: Strings.Views.Profiles.Folders.default)
} }

View File

@ -28,7 +28,7 @@ import PassepartoutKit
import SwiftUI import SwiftUI
import UtilsLibrary import UtilsLibrary
struct ProfileListView: View, ProfileManagerProviding, TunnelInstallationProviding { struct ProfileListView: View, TunnelInstallationProviding {
@Environment(\.horizontalSizeClass) @Environment(\.horizontalSizeClass)
private var hsClass private var hsClass
@ -63,7 +63,11 @@ struct ProfileListView: View, ProfileManagerProviding, TunnelInstallationProvidi
} }
Group { Group {
ForEach(allHeaders, content: profileView) ForEach(allHeaders, content: profileView)
.onDelete(perform: removeProfiles) .onDelete { offsets in
Task {
await profileManager.removeProfiles(at: offsets)
}
}
} }
.themeSection(header: Strings.Views.Profiles.Folders.default) .themeSection(header: Strings.Views.Profiles.Folders.default)
} }

View File

@ -0,0 +1,33 @@
//
// InteractiveViewProviding.swift
// Passepartout
//
// Created by Davide De Rosa on 10/6/24.
// Copyright (c) 2024 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 SwiftUI
protocol InteractiveViewProviding {
associatedtype InteractiveContent: View
@MainActor
func interactiveView(with editor: ProfileEditor) -> InteractiveContent
}

View File

@ -31,10 +31,3 @@ protocol ModuleViewProviding {
@MainActor @MainActor
func moduleView(with editor: ProfileEditor) -> Content func moduleView(with editor: ProfileEditor) -> Content
} }
protocol InteractiveViewProviding {
associatedtype InteractiveContent: View
@MainActor
func interactiveView(with editor: ProfileEditor) -> InteractiveContent
}

View File

@ -33,12 +33,6 @@ protocol TunnelInstallationProviding {
var tunnel: Tunnel { get } var tunnel: Tunnel { get }
} }
struct TunnelInstallation {
let header: ProfileHeader
let onDemand: Bool
}
@MainActor @MainActor
extension TunnelInstallationProviding { extension TunnelInstallationProviding {
var installation: TunnelInstallation? { var installation: TunnelInstallation? {

View File

@ -34,7 +34,7 @@ extension OpenVPNModule.Builder: ModuleViewProviding {
extension OpenVPNModule.Builder: InteractiveViewProviding { extension OpenVPNModule.Builder: InteractiveViewProviding {
func interactiveView(with editor: ProfileEditor) -> some View { func interactiveView(with editor: ProfileEditor) -> some View {
let draft: Binding<OpenVPNModule.Builder> = editor.binding(forModule: self) let draft = editor.binding(forModule: self)
return OpenVPNView.CredentialsView( return OpenVPNView.CredentialsView(
isInteractive: draft.isInteractive, isInteractive: draft.isInteractive,