mirror of https://github.com/buresdv/Cork
~ Finally compiles
This commit is contained in:
parent
1ded3d13c1
commit
7b7175c3c9
|
|
@ -133,146 +133,19 @@ struct CorkApp: App
|
||||||
}
|
}
|
||||||
.onAppear
|
.onAppear
|
||||||
{
|
{
|
||||||
print("Licensing state: \(appDelegate.appState.licensingState)")
|
handleLicensing()
|
||||||
|
|
||||||
#if SELF_COMPILED
|
|
||||||
AppConstants.shared.logger.debug("Will set licensing state to Self Compiled")
|
|
||||||
appDelegate.appState.licensingState = .selfCompiled
|
|
||||||
#else
|
|
||||||
if !hasValidatedEmail
|
|
||||||
{
|
|
||||||
if appDelegate.appState.licensingState != .selfCompiled
|
|
||||||
{
|
|
||||||
if let demoActivatedAt
|
|
||||||
{
|
|
||||||
let timeDemoWillRunOutAt: Date = demoActivatedAt + AppConstants.shared.demoLengthInSeconds
|
|
||||||
|
|
||||||
AppConstants.shared.logger.debug("There is \(demoActivatedAt.timeIntervalSinceNow.formatted()) to go on the demo")
|
|
||||||
|
|
||||||
AppConstants.shared.logger.debug("Demo will time out at \(timeDemoWillRunOutAt.formatted(date: .complete, time: .complete))")
|
|
||||||
|
|
||||||
if ((demoActivatedAt.timeIntervalSinceNow) + AppConstants.shared.demoLengthInSeconds) > 0
|
|
||||||
{ // Check if there is still time on the demo
|
|
||||||
/// do stuff if there is
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hasFinishedLicensingWorkflow = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
.onAppear
|
.onAppear
|
||||||
{
|
{
|
||||||
// Start the background update scheduler when the app starts
|
handleBackgroundUpdating()
|
||||||
backgroundUpdateTimer.schedule
|
|
||||||
{ (completion: NSBackgroundActivityScheduler.CompletionHandler) in
|
|
||||||
AppConstants.shared.logger.log("Scheduled event fired at \(Date(), privacy: .auto)")
|
|
||||||
|
|
||||||
Task
|
|
||||||
{
|
|
||||||
var updateResult: TerminalOutput = await shell(AppConstants.shared.brewExecutablePath, ["update"])
|
|
||||||
|
|
||||||
AppConstants.shared.logger.debug("Update result:\nStandard output: \(updateResult.standardOutput, privacy: .public)\nStandard error: \(updateResult.standardError, privacy: .public)")
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
let temporaryOutdatedPackageTracker: OutdatedPackagesTracker = await .init()
|
|
||||||
|
|
||||||
try await temporaryOutdatedPackageTracker.getOutdatedPackages(brewPackagesTracker: brewPackagesTracker)
|
|
||||||
|
|
||||||
var newOutdatedPackages: Set<OutdatedPackage> = await temporaryOutdatedPackageTracker.outdatedPackages
|
|
||||||
|
|
||||||
AppConstants.shared.logger.debug("Outdated packages checker output: \(newOutdatedPackages, privacy: .public)")
|
|
||||||
|
|
||||||
defer
|
|
||||||
{
|
|
||||||
AppConstants.shared.logger.log("Will purge temporary update trackers")
|
|
||||||
|
|
||||||
updateResult = .init(standardOutput: "", standardError: "")
|
|
||||||
newOutdatedPackages = .init()
|
|
||||||
}
|
|
||||||
|
|
||||||
if await newOutdatedPackages.count > outdatedPackagesTracker.outdatedPackages.count
|
|
||||||
{
|
|
||||||
AppConstants.shared.logger.log("New updates found")
|
|
||||||
|
|
||||||
/// Set this to `true` so the normal notification doesn't get sent
|
|
||||||
await setWhetherToSendStandardUpdatesAvailableNotification(to: false)
|
|
||||||
|
|
||||||
let differentPackages: Set<OutdatedPackage> = await newOutdatedPackages.subtracting(outdatedPackagesTracker.displayableOutdatedPackages)
|
|
||||||
AppConstants.shared.logger.debug("Changed packages: \(differentPackages, privacy: .auto)")
|
|
||||||
|
|
||||||
sendNotification(title: String(localized: "notification.new-outdated-packages-found.title"), subtitle: differentPackages.map(\.package.name).formatted(.list(type: .and)))
|
|
||||||
|
|
||||||
await outdatedPackagesTracker.setOutdatedPackages(to: newOutdatedPackages)
|
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1)
|
|
||||||
{
|
|
||||||
sendStandardUpdatesAvailableNotification = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AppConstants.shared.logger.log("No new updates found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
AppConstants.shared.logger.error("Something got fucked up about checking for outdated packages")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
completion(NSBackgroundActivityScheduler.Result.finished)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.onChange(of: demoActivatedAt) // React to when the user activates the demo
|
.onChange(of: demoActivatedAt) // React to when the user activates the demo
|
||||||
{ _, newValue in
|
{ _, newValue in
|
||||||
if let newValue
|
handleDemoTiming(newValue: newValue)
|
||||||
{ // If the demo has not been activated, `demoActivatedAt` is nil. So, when it's not nil anymore, it means the user activated it
|
|
||||||
AppConstants.shared.logger.debug("The user activated the demo at \(newValue.formatted(date: .complete, time: .complete), privacy: .public)")
|
|
||||||
hasFinishedLicensingWorkflow = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.onChange(of: outdatedPackagesTracker.displayableOutdatedPackages.count)
|
.onChange(of: outdatedPackagesTracker.displayableOutdatedPackages.count)
|
||||||
{ _, outdatedPackageCount in
|
{ _, outdatedPackageCount in
|
||||||
AppConstants.shared.logger.debug("Number of displayable outdated packages changed (\(outdatedPackageCount))")
|
handleOutdatedPackageChangeAppBadge(outdatedPackageCount: outdatedPackageCount)
|
||||||
|
|
||||||
// TODO: Remove this once I figure out why the updating spinner sometimes doesn't disappear
|
|
||||||
withAnimation
|
|
||||||
{
|
|
||||||
outdatedPackagesTracker.isCheckingForPackageUpdates = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if outdatedPackageCount == 0
|
|
||||||
{
|
|
||||||
NSApp.dockTile.badgeLabel = ""
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if areNotificationsEnabled
|
|
||||||
{
|
|
||||||
if outdatedPackageNotificationType == .badge || outdatedPackageNotificationType == .both
|
|
||||||
{
|
|
||||||
NSApp.dockTile.badgeLabel = String(outdatedPackageCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Changing the package display type sends a notificaiton, which is not visible since the app is in the foreground. Once macOS 15 comes out, move `sendStandardUpdatesAvailableNotification` into the AppState and suppress it
|
|
||||||
if outdatedPackageNotificationType == .notification || outdatedPackageNotificationType == .both
|
|
||||||
{
|
|
||||||
AppConstants.shared.logger.log("Will try to send notification")
|
|
||||||
|
|
||||||
/// This needs to be checked because when the background update system finds an update, we don't want to send this normal notification.
|
|
||||||
/// Instead, we want to send a more succinct notification that includes only the new package
|
|
||||||
if sendStandardUpdatesAvailableNotification
|
|
||||||
{
|
|
||||||
sendNotification(title: String(localized: "notification.outdated-packages-found.title"), subtitle: String(localized: "notification.outdated-packages-found.body-\(outdatedPackageCount)"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.onChange(of: outdatedPackageNotificationType) // Set the correct app badge number when the user changes their notification settings
|
.onChange(of: outdatedPackageNotificationType) // Set the correct app badge number when the user changes their notification settings
|
||||||
{ _, newValue in
|
{ _, newValue in
|
||||||
|
|
@ -417,7 +290,7 @@ struct CorkApp: App
|
||||||
WindowGroup(id: .previewWindowID, for: MinimalHomebrewPackage.self)
|
WindowGroup(id: .previewWindowID, for: MinimalHomebrewPackage.self)
|
||||||
{ $packageToPreview in
|
{ $packageToPreview in
|
||||||
|
|
||||||
let convertedMinimalPackage: BrewPackage? = .init(from: packageToPreview)
|
let convertedMinimalPackage: BrewPackage? = BrewPackage(using: packageToPreview)
|
||||||
|
|
||||||
PackagePreview(packageToPreview: convertedMinimalPackage)
|
PackagePreview(packageToPreview: convertedMinimalPackage)
|
||||||
.navigationTitle(packageToPreview?.name ?? "")
|
.navigationTitle(packageToPreview?.name ?? "")
|
||||||
|
|
@ -726,9 +599,10 @@ struct CorkApp: App
|
||||||
Text("debug.action.ui")
|
Text("debug.action.ui")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Functions
|
// MARK: - Functions
|
||||||
|
|
||||||
|
// MARK: - App badge
|
||||||
func setAppBadge(outdatedPackageNotificationType: OutdatedPackageNotificationType)
|
func setAppBadge(outdatedPackageNotificationType: OutdatedPackageNotificationType)
|
||||||
{
|
{
|
||||||
if outdatedPackageNotificationType == .badge || outdatedPackageNotificationType == .both
|
if outdatedPackageNotificationType == .badge || outdatedPackageNotificationType == .both
|
||||||
|
|
@ -743,9 +617,160 @@ struct CorkApp: App
|
||||||
NSApp.dockTile.badgeLabel = ""
|
NSApp.dockTile.badgeLabel = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setWhetherToSendStandardUpdatesAvailableNotification(to newValue: Bool)
|
private func setWhetherToSendStandardUpdatesAvailableNotification(to newValue: Bool)
|
||||||
{
|
{
|
||||||
self.sendStandardUpdatesAvailableNotification = newValue
|
self.sendStandardUpdatesAvailableNotification = newValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleOutdatedPackageChangeAppBadge(outdatedPackageCount: Int)
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.debug("Number of displayable outdated packages changed (\(outdatedPackageCount))")
|
||||||
|
|
||||||
|
// TODO: Remove this once I figure out why the updating spinner sometimes doesn't disappear
|
||||||
|
withAnimation
|
||||||
|
{
|
||||||
|
outdatedPackagesTracker.isCheckingForPackageUpdates = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if outdatedPackageCount == 0
|
||||||
|
{
|
||||||
|
NSApp.dockTile.badgeLabel = ""
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if areNotificationsEnabled
|
||||||
|
{
|
||||||
|
if outdatedPackageNotificationType == .badge || outdatedPackageNotificationType == .both
|
||||||
|
{
|
||||||
|
NSApp.dockTile.badgeLabel = String(outdatedPackageCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Changing the package display type sends a notificaiton, which is not visible since the app is in the foreground. Once macOS 15 comes out, move `sendStandardUpdatesAvailableNotification` into the AppState and suppress it
|
||||||
|
if outdatedPackageNotificationType == .notification || outdatedPackageNotificationType == .both
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.log("Will try to send notification")
|
||||||
|
|
||||||
|
/// This needs to be checked because when the background update system finds an update, we don't want to send this normal notification.
|
||||||
|
/// Instead, we want to send a more succinct notification that includes only the new package
|
||||||
|
if sendStandardUpdatesAvailableNotification
|
||||||
|
{
|
||||||
|
sendNotification(title: String(localized: "notification.outdated-packages-found.title"), subtitle: String(localized: "notification.outdated-packages-found.body-\(outdatedPackageCount)"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Background updating
|
||||||
|
|
||||||
|
func handleBackgroundUpdating()
|
||||||
|
{
|
||||||
|
// Start the background update scheduler when the app starts
|
||||||
|
backgroundUpdateTimer.schedule
|
||||||
|
{ (completion: NSBackgroundActivityScheduler.CompletionHandler) in
|
||||||
|
AppConstants.shared.logger.log("Scheduled event fired at \(Date(), privacy: .auto)")
|
||||||
|
|
||||||
|
Task
|
||||||
|
{
|
||||||
|
var updateResult: TerminalOutput = await shell(AppConstants.shared.brewExecutablePath, ["update"])
|
||||||
|
|
||||||
|
AppConstants.shared.logger.debug("Update result:\nStandard output: \(updateResult.standardOutput, privacy: .public)\nStandard error: \(updateResult.standardError, privacy: .public)")
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
let temporaryOutdatedPackageTracker: OutdatedPackagesTracker = await .init()
|
||||||
|
|
||||||
|
try await temporaryOutdatedPackageTracker.getOutdatedPackages(brewPackagesTracker: brewPackagesTracker)
|
||||||
|
|
||||||
|
var newOutdatedPackages: Set<OutdatedPackage> = await temporaryOutdatedPackageTracker.outdatedPackages
|
||||||
|
|
||||||
|
AppConstants.shared.logger.debug("Outdated packages checker output: \(newOutdatedPackages, privacy: .public)")
|
||||||
|
|
||||||
|
defer
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.log("Will purge temporary update trackers")
|
||||||
|
|
||||||
|
updateResult = .init(standardOutput: "", standardError: "")
|
||||||
|
newOutdatedPackages = .init()
|
||||||
|
}
|
||||||
|
|
||||||
|
if await newOutdatedPackages.count > outdatedPackagesTracker.outdatedPackages.count
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.log("New updates found")
|
||||||
|
|
||||||
|
/// Set this to `true` so the normal notification doesn't get sent
|
||||||
|
await setWhetherToSendStandardUpdatesAvailableNotification(to: false)
|
||||||
|
|
||||||
|
let differentPackages: Set<OutdatedPackage> = await newOutdatedPackages.subtracting(outdatedPackagesTracker.displayableOutdatedPackages)
|
||||||
|
AppConstants.shared.logger.debug("Changed packages: \(differentPackages, privacy: .auto)")
|
||||||
|
|
||||||
|
sendNotification(title: String(localized: "notification.new-outdated-packages-found.title"), subtitle: differentPackages.map(\.package.name).formatted(.list(type: .and)))
|
||||||
|
|
||||||
|
await outdatedPackagesTracker.setOutdatedPackages(to: newOutdatedPackages)
|
||||||
|
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1)
|
||||||
|
{
|
||||||
|
sendStandardUpdatesAvailableNotification = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.log("No new updates found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.error("Something got fucked up about checking for outdated packages")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(NSBackgroundActivityScheduler.Result.finished)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Licensing
|
||||||
|
func handleLicensing()
|
||||||
|
{
|
||||||
|
print("Licensing state: \(appDelegate.appState.licensingState)")
|
||||||
|
|
||||||
|
#if SELF_COMPILED
|
||||||
|
AppConstants.shared.logger.debug("Will set licensing state to Self Compiled")
|
||||||
|
appDelegate.appState.licensingState = .selfCompiled
|
||||||
|
#else
|
||||||
|
if !hasValidatedEmail
|
||||||
|
{
|
||||||
|
if appDelegate.appState.licensingState != .selfCompiled
|
||||||
|
{
|
||||||
|
if let demoActivatedAt
|
||||||
|
{
|
||||||
|
let timeDemoWillRunOutAt: Date = demoActivatedAt + AppConstants.shared.demoLengthInSeconds
|
||||||
|
|
||||||
|
AppConstants.shared.logger.debug("There is \(demoActivatedAt.timeIntervalSinceNow.formatted()) to go on the demo")
|
||||||
|
|
||||||
|
AppConstants.shared.logger.debug("Demo will time out at \(timeDemoWillRunOutAt.formatted(date: .complete, time: .complete))")
|
||||||
|
|
||||||
|
if ((demoActivatedAt.timeIntervalSinceNow) + AppConstants.shared.demoLengthInSeconds) > 0
|
||||||
|
{ // Check if there is still time on the demo
|
||||||
|
/// do stuff if there is
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hasFinishedLicensingWorkflow = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDemoTiming(newValue: Date?)
|
||||||
|
{
|
||||||
|
if let newValue
|
||||||
|
{ // If the demo has not been activated, `demoActivatedAt` is nil. So, when it's not nil anymore, it means the user activated it
|
||||||
|
AppConstants.shared.logger.debug("The user activated the demo at \(newValue.formatted(date: .complete, time: .complete), privacy: .public)")
|
||||||
|
hasFinishedLicensingWorkflow = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -375,9 +375,9 @@ public struct BrewPackage: Identifiable, Equatable, Hashable, Codable, Sendable,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert between ``MinimalHomebrewPackage`` and ``BrewPackage``
|
/// Convert between ``MinimalHomebrewPackage`` and ``BrewPackage``
|
||||||
extension BrewPackage
|
public extension BrewPackage
|
||||||
{
|
{
|
||||||
init?(from minimalPackage: MinimalHomebrewPackage?)
|
init?(using minimalPackage: MinimalHomebrewPackage?)
|
||||||
{
|
{
|
||||||
guard let minimalPackage = minimalPackage else { return nil }
|
guard let minimalPackage = minimalPackage else { return nil }
|
||||||
|
|
||||||
|
|
@ -400,3 +400,4 @@ public extension FormatStyle where Self == Date.FormatStyle
|
||||||
dateTime.day().month(.wide).year().weekday(.wide).hour().minute()
|
dateTime.day().month(.wide).year().weekday(.wide).hour().minute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue