diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 877fb5e..16dad67 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -540,6 +540,10 @@ C48D6C70279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; }; C48D6C71279CD2AC00F26D7E /* VersionNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */; }; C48D6C75279CD3E400F26D7E /* PhpVersionNumberTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */; }; + C48DDD0D29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; }; + C48DDD0E29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; }; + C48DDD0F29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; }; + C48DDD1029C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */; }; C490E3A729BC940D006D2DE6 /* ProgressWindowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A629BC940D006D2DE6 /* ProgressWindowView.swift */; }; C490E3AA29BC9B3E006D2DE6 /* ProgressViewSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */; }; C490E3B029BC9FE8006D2DE6 /* ProgressViewSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */; }; @@ -938,6 +942,7 @@ C48D0C9225CC804200CC7490 /* XibLoadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XibLoadable.swift; sourceTree = ""; }; C48D6C6F279CD2AC00F26D7E /* VersionNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionNumber.swift; sourceTree = ""; }; C48D6C73279CD3E400F26D7E /* PhpVersionNumberTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpVersionNumberTest.swift; sourceTree = ""; }; + C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockingOverlayView.swift; sourceTree = ""; }; C490E3A629BC940D006D2DE6 /* ProgressWindowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressWindowView.swift; sourceTree = ""; }; C490E3A929BC9B3E006D2DE6 /* ProgressViewSubject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressViewSubject.swift; sourceTree = ""; }; C4927F0A27B2DFC200C55AFD /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; @@ -1349,6 +1354,7 @@ isa = PBXGroup; children = ( C43931C429C4BD610069165B /* PhpFormulaeManager.swift */, + C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */, ); path = PhpManager; sourceTree = ""; @@ -2219,6 +2225,7 @@ C45B9149295607F400F4EC78 /* Service.swift in Sources */, 5489625828312FAD004F647A /* CreatedFromFile.swift in Sources */, C4068CA727B07A1300544CD5 /* SelectPreferenceView.swift in Sources */, + C48DDD0D29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */, C45B91532956123A00F4EC78 /* FakeServicesManager.swift in Sources */, C41C708D28AA7F7900E8D498 /* NoWarningsView.swift in Sources */, C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */, @@ -2445,6 +2452,7 @@ C471E86728F9BB650021E251 /* OnboardingWindowController.swift in Sources */, C471E86828F9BB650021E251 /* PreferencesWindowController.swift in Sources */, C471E86928F9BB650021E251 /* PreferencesWindowController+Hotkey.swift in Sources */, + C48DDD0F29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */, C4AFC4B029C4F32F00BF4E0D /* BrewFormula.swift in Sources */, C471E86A28F9BB650021E251 /* PrefsVC.swift in Sources */, C471E86B28F9BB650021E251 /* PreferenceName.swift in Sources */, @@ -2682,6 +2690,7 @@ C471E80128F9BAD40021E251 /* ActivePhpInstallation.swift in Sources */, C471E80228F9BAD40021E251 /* PhpInstallation.swift in Sources */, C471E81028F9BAE80021E251 /* StringExtension.swift in Sources */, + C48DDD1029C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */, C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */, C471E82328F9BB2E0021E251 /* ComposerJson.swift in Sources */, C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */, @@ -2898,6 +2907,7 @@ C4927F0C27B2DFC200C55AFD /* Errors.swift in Sources */, C485707628BF455100539B36 /* SectionHeaderView.swift in Sources */, C46EBC4828DB9644007ACC74 /* RealShell.swift in Sources */, + C48DDD0E29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */, C4E4404727C56F4700D225E1 /* ValetSite.swift in Sources */, C44CCD4A27AFF3BC00CE40E5 /* MainMenu+Async.swift in Sources */, C449B4F327EE7FC600C47E8A /* DomainListTypeCell.swift in Sources */, diff --git a/phpmon/Domain/SwiftUI/PhpManager/BlockingOverlayView.swift b/phpmon/Domain/SwiftUI/PhpManager/BlockingOverlayView.swift new file mode 100644 index 0000000..8128778 --- /dev/null +++ b/phpmon/Domain/SwiftUI/PhpManager/BlockingOverlayView.swift @@ -0,0 +1,62 @@ +// +// BlockingOverlayView.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 19/03/2023. +// Copyright © 2023 Nico Verbruggen. All rights reserved. +// + +import Foundation +import SwiftUI + +struct BlockingOverlayView: View { + var isBlocking: Bool + var titleText: String + var detailText: String + var content: () -> Content + + init( + busy: Bool, + title: String, + text: String, + @ViewBuilder content: @escaping () -> Content + ) { + self.isBlocking = busy + self.titleText = title + self.detailText = text + self.content = content + } + + var body: some View { + ZStack(alignment: .center) { + content().opacity(isBlocking ? 0.2 : 1) + if isBlocking { + VStack { + ActivityIndicator() + Text(titleText) + .font(.system(size: 14)) + .bold() + .foregroundColor(.primary) + .padding(.top, 8) + Text(detailText) + .font(.system(size: 11)) + .foregroundColor(.primary) + .padding(.top, -4) + } + } + } + .disabled(isBlocking) + } +} + +struct ActivityIndicator: NSViewRepresentable { + func makeNSView(context: Context) -> NSProgressIndicator { + let nsView = NSProgressIndicator() + nsView.style = .spinning + nsView.startAnimation(nil) + return nsView + } + + func updateNSView(_ nsView: NSProgressIndicator, context: Context) { + } +} diff --git a/phpmon/Domain/SwiftUI/PhpManager/PhpFormulaeManager.swift b/phpmon/Domain/SwiftUI/PhpManager/PhpFormulaeManager.swift index faca9cd..9f9bf5c 100644 --- a/phpmon/Domain/SwiftUI/PhpManager/PhpFormulaeManager.swift +++ b/phpmon/Domain/SwiftUI/PhpManager/PhpFormulaeManager.swift @@ -11,56 +11,59 @@ import SwiftUI struct PhpFormulaeManager: View { @State var formulae: [BrewFormula] - @State var busy: Bool = false + @State var busy: Bool = true + @State var title: String = "Doing a thing" + @State var description: String = "Preparing..." var body: some View { - List(Array(formulae.enumerated()), id: \.1.name) { (index, formula) in - HStack { - Image(systemName: formula.icon) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 16, height: 16) - .foregroundColor(formula.iconColor) - .padding(.horizontal, 5) - VStack(alignment: .leading) { - Text(formula.displayName).bold() + BlockingOverlayView(busy: busy, title: title, text: description) { + List(Array(formulae.enumerated()), id: \.1.name) { (index, formula) in + HStack { + Image(systemName: formula.icon) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 16, height: 16) + .foregroundColor(formula.iconColor) + .padding(.horizontal, 5) + VStack(alignment: .leading) { + Text(formula.displayName).bold() - if formula.isInstalled && formula.hasUpgrade { - Text("\(formula.installedVersion!) installed, \(formula.upgradeVersion!) available.") - .font(.system(size: 11)) - .foregroundColor(.gray) - } else if formula.isInstalled && formula.installedVersion != nil { - Text("Latest version is currently installed.").font(.system(size: 11)) - .foregroundColor(.gray) + if formula.isInstalled && formula.hasUpgrade { + Text("\(formula.installedVersion!) installed, \(formula.upgradeVersion!) available.") + .font(.system(size: 11)) + .foregroundColor(.gray) + } else if formula.isInstalled && formula.installedVersion != nil { + Text("Latest version is currently installed.").font(.system(size: 11)) + .foregroundColor(.gray) + } else { + Text("This version can be installed.") + .font(.system(size: 11)) + .foregroundColor(.gray) + } + } + .frame(maxWidth: .infinity, alignment: .leading) + if formula.isInstalled { + Button("Uninstall") { + // handle uninstall action here + } } else { - Text("This version can be installed.") - .font(.system(size: 11)) - .foregroundColor(.gray) - } - } - .frame(maxWidth: .infinity, alignment: .leading) - if formula.isInstalled { - Button("Uninstall") { - // handle uninstall action here - } - } else { - Button("Install") { - // handle install action here - } - } - if formula.hasUpgrade { - Button("Update") { - // handle uninstall action here + Button("Install") { + // handle install action here + } + } + if formula.hasUpgrade { + Button("Update") { + // handle uninstall action here + } } } + .listRowBackground(index % 2 == 0 + ? Color.gray.opacity(0) + : Color.gray.opacity(0.08) + ) + .padding(.vertical, 10) } - .listRowBackground(index % 2 == 0 - ? Color.gray.opacity(0) - : Color.gray.opacity(0.08) - ) - .padding(.vertical, 10) - } - .frame(width: 500, height: 500) + }.frame(width: 500, height: 500) } } @@ -84,6 +87,30 @@ struct PhpFormulaeManager_Previews: PreviewProvider { displayName: "PHP 8.0", installedVersion: nil, upgradeVersion: nil + ), + BrewFormula( + name: "php@7.4", + displayName: "PHP 7.4", + installedVersion: nil, + upgradeVersion: nil + ), + BrewFormula( + name: "php@7.3", + displayName: "PHP 7.3", + installedVersion: nil, + upgradeVersion: nil + ), + BrewFormula( + name: "php@7.2", + displayName: "PHP 7.2", + installedVersion: nil, + upgradeVersion: nil + ), + BrewFormula( + name: "php@7.1", + displayName: "PHP 7.1", + installedVersion: nil, + upgradeVersion: nil ) ]).frame(width: 600, height: 500) }