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

Refactor static functions/entities in Library #679

Merged
merged 18 commits into from
Oct 4, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
"kind" : "remoteSourceControl",
"location" : "[email protected]:passepartoutvpn/passepartoutkit-source",
"state" : {
"revision" : "2e61214462dcf6ad9e211d8fdbd611c6755845c4",
"version" : "0.8.0"
"revision" : "779910e268e79f1004a95285ac2485255d88bb21"
}
},
{
Expand Down
5 changes: 3 additions & 2 deletions Passepartout/App/PassepartoutApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ private extension PassepartoutApp {
registry: context.registry
)
.onLoad {
CommonLibrary.configureLogging(
PassepartoutConfiguration.shared.configureLogging(
to: BundleConfiguration.urlForAppLog,
parameters: Constants.shared.log
parameters: Constants.shared.log,
logsPrivateData: UserDefaults.appGroup.bool(forKey: AppPreference.logsPrivateData.key)
)
AppUI.configure(with: context)
}
Expand Down
4 changes: 2 additions & 2 deletions Passepartout/Library/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ let package = Package(
)
],
dependencies: [
.package(url: "[email protected]:passepartoutvpn/passepartoutkit-source", from: "0.8.0"),
// .package(url: "[email protected]:passepartoutvpn/passepartoutkit-source", revision: "2e61214462dcf6ad9e211d8fdbd611c6755845c4"),
// .package(url: "[email protected]:passepartoutvpn/passepartoutkit-source", from: "0.8.0"),
.package(url: "[email protected]:passepartoutvpn/passepartoutkit-source", revision: "779910e268e79f1004a95285ac2485255d88bb21"),
// .package(path: "../../../passepartoutkit-source"),
.package(url: "[email protected]:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.8.0"),
// .package(url: "[email protected]:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ import PassepartoutKit
import UtilsLibrary

extension AppData {

// TODO: #656, make non-static
public static func cdProfileRepositoryV3(
registry: Registry,
coder: ProfileCoder,
Expand Down
14 changes: 5 additions & 9 deletions Passepartout/Library/Sources/AppUI/AppUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@
import Foundation
import PassepartoutKit

// TODO: #656, make non-static
public struct AppUI {
private init() {
}

public enum AppUI {
public static func configure(with context: AppContext) {
assertMissingModuleImplementations()
}
Expand All @@ -40,11 +36,11 @@ private extension AppUI {
static func assertMissingModuleImplementations() {
ModuleType.allCases.forEach { moduleType in
let module = moduleType.newModule()
guard module as? ModuleTypeProviding != nil else {
fatalError("\(moduleType): does not implement ModuleTypeProviding")
guard module is ModuleTypeProviding else {
fatalError("\(moduleType): is not ModuleTypeProviding")
}
guard module as? any ModuleViewProviding != nil else {
fatalError("\(moduleType): does not implement ModuleViewProviding")
guard module is any ModuleViewProviding else {
fatalError("\(moduleType): is not ModuleViewProviding")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Issue+App.swift
// Issue+Metadata.swift
// Passepartout
//
// Created by Davide De Rosa on 9/18/24.
Expand Down Expand Up @@ -28,23 +28,35 @@ import Foundation
import PassepartoutKit

extension Issue {
struct Metadata {
let configuration: PassepartoutConfiguration

// TODO: #656, make non-static
static func with(versionString: String, purchasedProducts: Set<AppProduct>, tunnel: Tunnel) async -> Self {
let appLog = CommonLibrary.currentLog(parameters: Constants.shared.log)
let versionString: String

let purchasedProducts: Set<AppProduct>

let tunnel: Tunnel

let urlForTunnelLog: URL

let parameters: Constants.Log
}

static func withMetadata(_ metadata: Metadata) async -> Issue {
let appLog = metadata.configuration.currentLog(parameters: metadata.parameters)
.joined(separator: "\n")
.data(using: .utf8)

let tunnelLog: Data?

// live tunnel log
if await tunnel.status != .inactive {
tunnelLog = await tunnel.currentLog(parameters: Constants.shared.log)
if await metadata.tunnel.status != .inactive {
tunnelLog = await metadata.tunnel.currentLog(parameters: metadata.parameters)
.joined(separator: "\n")
.data(using: .utf8)
}
// latest persisted tunnel log
else if let latestTunnelEntry = CommonLibrary.availableLogs(at: BundleConfiguration.urlForTunnelLog)
else if let latestTunnelEntry = metadata.configuration.availableLogs(at: metadata.urlForTunnelLog)
.max(by: { $0.key < $1.key }) {

tunnelLog = try? Data(contentsOf: latestTunnelEntry.value)
Expand All @@ -55,13 +67,15 @@ extension Issue {
}

return Issue(
appLine: "\(Strings.Unlocalized.appName) \(versionString)",
purchasedProducts: purchasedProducts,
appLine: "\(Strings.Unlocalized.appName) \(metadata.versionString)",
purchasedProducts: metadata.purchasedProducts,
appLog: appLog,
tunnelLog: tunnelLog
)
}
}

extension Issue {
var to: String {
Constants.shared.emails.issues
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,18 @@ import SwiftUI
import UtilsLibrary

extension DebugLogView {

// TODO: #656, make non-static
static func withApp(parameters: Constants.Log) -> DebugLogView {
DebugLogView {
CommonLibrary.currentLog(parameters: parameters)
PassepartoutConfiguration.shared.currentLog(parameters: parameters)
}
}

// TODO: #656, make non-static
static func withTunnel(_ tunnel: Tunnel, parameters: Constants.Log) -> DebugLogView {
DebugLogView {
await tunnel.currentLog(parameters: parameters)
}
}

// TODO: #656, make non-static
static func withURL(_ url: URL) -> DebugLogView {
DebugLogView {
do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ struct DiagnosticsView: View {
@EnvironmentObject
var iapManager: IAPManager

@AppStorage(AppPreference.logsPrivateData.key, store: .group)
@AppStorage(AppPreference.logsPrivateData.key, store: .appGroup)
private var logsPrivateData = false

var availableTunnelLogs: () -> [LogEntry] = {
CommonLibrary.availableLogs(at: BundleConfiguration.urlForTunnelLog)
PassepartoutConfiguration.shared.availableLogs(at: BundleConfiguration.urlForTunnelLog)
.sorted {
$0.key > $1.key
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#if os(iOS)

import CommonLibrary
import PassepartoutKit
import SwiftUI
import UIKit
Expand All @@ -33,24 +34,7 @@ import UtilsLibrary
extension ReportIssueButton: View {
var body: some View {
HStack {
Button(title) {
Task {
isPending = true
defer {
isPending = false
}
let issue = await Issue.with(
versionString: BundleConfiguration.mainVersionString,
purchasedProducts: purchasedProducts,
tunnel: tunnel
)
guard MailComposerView.canSendMail() else {
openMailTo(with: issue)
return
}
issueBeingReported = issue
}
}
Button(title, action: sendEmail)
if isPending {
Spacer()
ProgressView()
Expand All @@ -75,21 +59,29 @@ extension ReportIssueButton: View {
}
}

private extension Issue {
var attachments: [MailComposerView.Attachment] {
var list: [MailComposerView.Attachment] = []
let mimeType = Strings.Unlocalized.Issues.attachmentMimeType
if let appLog {
list.append(.init(data: appLog, mimeType: mimeType, fileName: Strings.Unlocalized.Issues.appLogFilename))
}
if let tunnelLog {
list.append(.init(data: tunnelLog, mimeType: mimeType, fileName: Strings.Unlocalized.Issues.tunnelLogFilename))
private extension ReportIssueButton {
func sendEmail() {
Task {
isPending = true
defer {
isPending = false
}
let issue = await Issue.withMetadata(.init(
configuration: .shared,
versionString: BundleConfiguration.mainVersionString,
purchasedProducts: purchasedProducts,
tunnel: tunnel,
urlForTunnelLog: BundleConfiguration.urlForTunnelLog,
parameters: Constants.shared.log
))
guard MailComposerView.canSendMail() else {
openMailTo(with: issue)
return
}
issueBeingReported = issue
}
return list
}
}

private extension ReportIssueButton {
func openMailTo(with issue: Issue) {
guard let url = URL.mailto(to: issue.to, subject: issue.subject, body: issue.body) else {
return
Expand All @@ -102,4 +94,18 @@ private extension ReportIssueButton {
}
}

private extension Issue {
var attachments: [MailComposerView.Attachment] {
var list: [MailComposerView.Attachment] = []
let mimeType = Strings.Unlocalized.Issues.attachmentMimeType
if let appLog {
list.append(.init(data: appLog, mimeType: mimeType, fileName: Strings.Unlocalized.Issues.appLogFilename))
}
if let tunnelLog {
list.append(.init(data: tunnelLog, mimeType: mimeType, fileName: Strings.Unlocalized.Issues.tunnelLogFilename))
}
return list
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,39 @@

#if os(macOS)

import CommonLibrary
import PassepartoutKit
import SwiftUI

extension ReportIssueButton: View {
var body: some View {
Button(title) {
Button(title, action: sendEmail)
.disabled(isPending)
}
}

private extension ReportIssueButton {
func sendEmail() {
Task {
guard let service = NSSharingService(named: .composeEmail) else {
isUnableToEmail = true
return
}
Task {
let issue = await Issue.with(
versionString: BundleConfiguration.mainVersionString,
purchasedProducts: purchasedProducts,
tunnel: tunnel
)
service.recipients = [issue.to]
service.subject = issue.subject
service.perform(withItems: issue.items)
isPending = true
defer {
isPending = false
}
let issue = await Issue.withMetadata(.init(
configuration: .shared,
versionString: BundleConfiguration.mainVersionString,
purchasedProducts: purchasedProducts,
tunnel: tunnel,
urlForTunnelLog: BundleConfiguration.urlForTunnelLog,
parameters: Constants.shared.log
))
service.recipients = [issue.to]
service.subject = issue.subject
service.perform(withItems: issue.items)
}
}
}
Expand Down
Loading