mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-11-06 04:40:07 +01:00
⬆️ Adopt #Preview, cleanup PHP Version Manager
This commit is contained in:
@@ -122,6 +122,10 @@
|
|||||||
C41F3D08298AED0D0042ACBF /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660A29113F20006BD146 /* System.swift */; };
|
C41F3D08298AED0D0042ACBF /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D3660A29113F20006BD146 /* System.swift */; };
|
||||||
C4205A7E27F4D21800191A39 /* ValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4205A7D27F4D21800191A39 /* ValetProxy.swift */; };
|
C4205A7E27F4D21800191A39 /* ValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4205A7D27F4D21800191A39 /* ValetProxy.swift */; };
|
||||||
C4205A7F27F4D21800191A39 /* ValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4205A7D27F4D21800191A39 /* ValetProxy.swift */; };
|
C4205A7F27F4D21800191A39 /* ValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4205A7D27F4D21800191A39 /* ValetProxy.swift */; };
|
||||||
|
C42106662AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */; };
|
||||||
|
C42106672AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */; };
|
||||||
|
C42106682AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */; };
|
||||||
|
C42106692AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */; };
|
||||||
C422DDAA28A2C49900CEAC97 /* PhpDoctorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C422DDA928A2C49900CEAC97 /* PhpDoctorView.swift */; };
|
C422DDAA28A2C49900CEAC97 /* PhpDoctorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C422DDA928A2C49900CEAC97 /* PhpDoctorView.swift */; };
|
||||||
C4232EE52612526500158FC6 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = C4232EE42612526500158FC6 /* Credits.html */; };
|
C4232EE52612526500158FC6 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = C4232EE42612526500158FC6 /* Credits.html */; };
|
||||||
C42337A3281F19F000459A48 /* Xdebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42337A2281F19F000459A48 /* Xdebug.swift */; };
|
C42337A3281F19F000459A48 /* Xdebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42337A2281F19F000459A48 /* Xdebug.swift */; };
|
||||||
@@ -938,6 +942,7 @@
|
|||||||
C41CD0282628D8EE0065BBED /* GlobalKeybindPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalKeybindPreference.swift; sourceTree = "<group>"; };
|
C41CD0282628D8EE0065BBED /* GlobalKeybindPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalKeybindPreference.swift; sourceTree = "<group>"; };
|
||||||
C41E87192763D42300161EE0 /* DomainListVC+ContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DomainListVC+ContextMenu.swift"; sourceTree = "<group>"; };
|
C41E87192763D42300161EE0 /* DomainListVC+ContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DomainListVC+ContextMenu.swift"; sourceTree = "<group>"; };
|
||||||
C4205A7D27F4D21800191A39 /* ValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetProxy.swift; sourceTree = "<group>"; };
|
C4205A7D27F4D21800191A39 /* ValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetProxy.swift; sourceTree = "<group>"; };
|
||||||
|
C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PhpVersionManagerView+Actions.swift"; sourceTree = "<group>"; };
|
||||||
C422DDA928A2C49900CEAC97 /* PhpDoctorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpDoctorView.swift; sourceTree = "<group>"; };
|
C422DDA928A2C49900CEAC97 /* PhpDoctorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpDoctorView.swift; sourceTree = "<group>"; };
|
||||||
C422DDAC28A2DAC600CEAC97 /* PhpDoctorWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpDoctorWindowController.swift; sourceTree = "<group>"; };
|
C422DDAC28A2DAC600CEAC97 /* PhpDoctorWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpDoctorWindowController.swift; sourceTree = "<group>"; };
|
||||||
C4232EE42612526500158FC6 /* Credits.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = Credits.html; sourceTree = "<group>"; };
|
C4232EE42612526500158FC6 /* Credits.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = Credits.html; sourceTree = "<group>"; };
|
||||||
@@ -1494,6 +1499,7 @@
|
|||||||
children = (
|
children = (
|
||||||
C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */,
|
C4D5576329C77CC5001A44CD /* PhpVersionManagerWindowController.swift */,
|
||||||
C43931C429C4BD610069165B /* PhpVersionManagerView.swift */,
|
C43931C429C4BD610069165B /* PhpVersionManagerView.swift */,
|
||||||
|
C42106652AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift */,
|
||||||
C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */,
|
C48DDD0C29C75C9E00D032D9 /* BlockingOverlayView.swift */,
|
||||||
);
|
);
|
||||||
path = UI;
|
path = UI;
|
||||||
@@ -2586,6 +2592,7 @@
|
|||||||
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */,
|
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */,
|
||||||
54D9E0BA27E4F51E003B9AD9 /* ModifierFlagsExtension.swift in Sources */,
|
54D9E0BA27E4F51E003B9AD9 /* ModifierFlagsExtension.swift in Sources */,
|
||||||
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */,
|
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */,
|
||||||
|
C42106662AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C40508AF28ADA23D008FAC1F /* NoDomainResultsView.swift in Sources */,
|
C40508AF28ADA23D008FAC1F /* NoDomainResultsView.swift in Sources */,
|
||||||
C4B79ECB29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
C4B79ECB29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
||||||
C40D725F2A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
C40D725F2A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
||||||
@@ -2775,6 +2782,7 @@
|
|||||||
C471E81428F9BAE80021E251 /* NSWindowExtension.swift in Sources */,
|
C471E81428F9BAE80021E251 /* NSWindowExtension.swift in Sources */,
|
||||||
C43BCD4629FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */,
|
C43BCD4629FBEF40001547BC /* InstallAndUpgradeCommand.swift in Sources */,
|
||||||
C471E7D328F9BA8F0021E251 /* ActiveShell.swift in Sources */,
|
C471E7D328F9BA8F0021E251 /* ActiveShell.swift in Sources */,
|
||||||
|
C42106682AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C4B79EC829CA474200A483EE /* FakeCommand.swift in Sources */,
|
C4B79EC829CA474200A483EE /* FakeCommand.swift in Sources */,
|
||||||
C471E7DE28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
C471E7DE28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
|
||||||
C471E81B28F9BB250021E251 /* BetterAlertVC.swift in Sources */,
|
C471E81B28F9BB250021E251 /* BetterAlertVC.swift in Sources */,
|
||||||
@@ -2831,6 +2839,7 @@
|
|||||||
C471E89F28F9BB8F0021E251 /* ValetDomainScanner.swift in Sources */,
|
C471E89F28F9BB8F0021E251 /* ValetDomainScanner.swift in Sources */,
|
||||||
C471E8A028F9BB8F0021E251 /* FakeDomainScanner.swift in Sources */,
|
C471E8A028F9BB8F0021E251 /* FakeDomainScanner.swift in Sources */,
|
||||||
C471E8A228F9BB8F0021E251 /* AppDelegate.swift in Sources */,
|
C471E8A228F9BB8F0021E251 /* AppDelegate.swift in Sources */,
|
||||||
|
C42106692AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C43931CD29C4C03F0069165B /* Brew.swift in Sources */,
|
C43931CD29C4C03F0069165B /* Brew.swift in Sources */,
|
||||||
C451AFF92969E40F0078E617 /* HelpButton.swift in Sources */,
|
C451AFF92969E40F0078E617 /* HelpButton.swift in Sources */,
|
||||||
C4ACE9E429F84EDD00110766 /* PhpGuard.swift in Sources */,
|
C4ACE9E429F84EDD00110766 /* PhpGuard.swift in Sources */,
|
||||||
@@ -3083,6 +3092,7 @@
|
|||||||
C4611E5F2AEAD2FB0010BE24 /* ConfigManagerView.swift in Sources */,
|
C4611E5F2AEAD2FB0010BE24 /* ConfigManagerView.swift in Sources */,
|
||||||
C4F780AE25D80B37000DBC97 /* PhpExtensionTest.swift in Sources */,
|
C4F780AE25D80B37000DBC97 /* PhpExtensionTest.swift in Sources */,
|
||||||
C456A0C72AA614BD0080144F /* PhpPreference.swift in Sources */,
|
C456A0C72AA614BD0080144F /* PhpPreference.swift in Sources */,
|
||||||
|
C42106672AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
|
||||||
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
|
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
|
||||||
C4FC21B128391F8E00D368BB /* MainMenu+Actions.swift in Sources */,
|
C4FC21B128391F8E00D368BB /* MainMenu+Actions.swift in Sources */,
|
||||||
54D9E0B927E4F51E003B9AD9 /* KeyCombo.swift in Sources */,
|
54D9E0B927E4F51E003B9AD9 /* KeyCombo.swift in Sources */,
|
||||||
|
|||||||
@@ -27,15 +27,15 @@ struct HelpButton: View {
|
|||||||
.buttonStyle(BorderlessButtonStyle())
|
.buttonStyle(BorderlessButtonStyle())
|
||||||
.focusable(false)
|
.focusable(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
struct HelpButton_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
#Preview("Light Mode") {
|
||||||
Group {
|
HelpButton(action: {})
|
||||||
HelpButton(action: {}).padding()
|
.padding(100)
|
||||||
.previewDisplayName("Light Mode")
|
}
|
||||||
HelpButton(action: {}).padding().preferredColorScheme(.dark)
|
|
||||||
.previewDisplayName("Dark Mode")
|
#Preview("Dark Mode") {
|
||||||
}
|
HelpButton(action: {})
|
||||||
}
|
.padding(100)
|
||||||
}
|
.preferredColorScheme(.dark)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ struct NoDomainResults: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoDomainResults_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
NoDomainResults()
|
||||||
NoDomainResults()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,78 +126,82 @@ struct DisclaimerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VersionPopoverView_Previews: PreviewProvider {
|
#Preview("Unknown Requirement") {
|
||||||
static var previews: some View {
|
VersionPopoverView(
|
||||||
VersionPopoverView(
|
site: FakeValetSite(
|
||||||
site: FakeValetSite(
|
fakeWithName: "amazingwebsite",
|
||||||
fakeWithName: "amazingwebsite",
|
tld: "test",
|
||||||
tld: "test",
|
secure: true,
|
||||||
secure: true,
|
path: "/path/to/site",
|
||||||
path: "/path/to/site",
|
linked: true,
|
||||||
linked: true,
|
constraint: ""
|
||||||
constraint: ""
|
),
|
||||||
),
|
validPhpVersions: [],
|
||||||
validPhpVersions: [],
|
parent: nil
|
||||||
parent: nil
|
)
|
||||||
)
|
}
|
||||||
.previewDisplayName("Unknown Requirement")
|
|
||||||
|
#Preview("Requirement Matches") {
|
||||||
VersionPopoverView(
|
VersionPopoverView(
|
||||||
site: FakeValetSite(
|
site: FakeValetSite(
|
||||||
fakeWithName: "amazingwebsite",
|
fakeWithName: "amazingwebsite",
|
||||||
tld: "test",
|
tld: "test",
|
||||||
secure: true,
|
secure: true,
|
||||||
path: "/path/to/site",
|
path: "/path/to/site",
|
||||||
linked: true,
|
linked: true,
|
||||||
constraint: "^8.1"
|
constraint: "^8.1"
|
||||||
),
|
),
|
||||||
validPhpVersions: [],
|
validPhpVersions: [],
|
||||||
parent: nil
|
parent: nil
|
||||||
)
|
)
|
||||||
.previewDisplayName("Requirement Matches")
|
}
|
||||||
VersionPopoverView(
|
|
||||||
site: FakeValetSite(
|
#Preview("Isolated") {
|
||||||
fakeWithName: "anothersite",
|
VersionPopoverView(
|
||||||
tld: "test",
|
site: FakeValetSite(
|
||||||
secure: true,
|
fakeWithName: "anothersite",
|
||||||
path: "/path/to/site",
|
tld: "test",
|
||||||
linked: true,
|
secure: true,
|
||||||
constraint: "^8.0",
|
path: "/path/to/site",
|
||||||
isolated: "8.0"
|
linked: true,
|
||||||
),
|
constraint: "^8.0",
|
||||||
validPhpVersions: [],
|
isolated: "8.0"
|
||||||
parent: nil
|
),
|
||||||
)
|
validPhpVersions: [],
|
||||||
.previewDisplayName("Isolated")
|
parent: nil
|
||||||
VersionPopoverView(
|
)
|
||||||
site: FakeValetSite(
|
}
|
||||||
fakeWithName: "anothersite",
|
|
||||||
tld: "test",
|
#Preview("Isolated Mismatch") {
|
||||||
secure: true,
|
VersionPopoverView(
|
||||||
path: "/path/to/site",
|
site: FakeValetSite(
|
||||||
linked: true,
|
fakeWithName: "anothersite",
|
||||||
constraint: "^8.0",
|
tld: "test",
|
||||||
isolated: "7.4"
|
secure: true,
|
||||||
),
|
path: "/path/to/site",
|
||||||
validPhpVersions: [],
|
linked: true,
|
||||||
parent: nil
|
constraint: "^8.0",
|
||||||
)
|
isolated: "7.4"
|
||||||
.previewDisplayName("Isolated Mismatch")
|
),
|
||||||
VersionPopoverView(
|
validPhpVersions: [],
|
||||||
site: FakeValetSite(
|
parent: nil
|
||||||
fakeWithName: "anothersite",
|
)
|
||||||
tld: "test",
|
}
|
||||||
secure: true,
|
|
||||||
path: "/path/to/site",
|
#Preview("Recommend Alternatives") {
|
||||||
linked: true,
|
VersionPopoverView(
|
||||||
constraint: "^8.0"
|
site: FakeValetSite(
|
||||||
),
|
fakeWithName: "anothersite",
|
||||||
validPhpVersions: [
|
tld: "test",
|
||||||
VersionNumber(major: 8, minor: 0, patch: 0),
|
secure: true,
|
||||||
VersionNumber(major: 8, minor: 1, patch: 0)
|
path: "/path/to/site",
|
||||||
],
|
linked: true,
|
||||||
parent: nil
|
constraint: "^8.0"
|
||||||
)
|
),
|
||||||
.previewDisplayName("Recommend Alternatives")
|
validPhpVersions: [
|
||||||
}
|
VersionNumber(major: 8, minor: 0, patch: 0),
|
||||||
|
VersionNumber(major: 8, minor: 1, patch: 0)
|
||||||
|
],
|
||||||
|
parent: nil
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ struct HeaderView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HeaderView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
HeaderView(text: "Hello world")
|
||||||
HeaderView(text: "Hello world")
|
.frame(width: 330.0)
|
||||||
.frame(width: 330.0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,23 +172,21 @@ struct ServiceView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ServicesView_Previews: PreviewProvider {
|
#Preview("Active 1") {
|
||||||
static var previews: some View {
|
ServicesView(manager: FakeServicesManager(
|
||||||
ServicesView(manager: FakeServicesManager(
|
formulae: ["php", "nginx", "dnsmasq"],
|
||||||
formulae: ["php", "nginx", "dnsmasq"],
|
status: .active
|
||||||
status: .active
|
), perRow: 4)
|
||||||
), perRow: 4)
|
.frame(width: 330.0)
|
||||||
.frame(width: 330.0)
|
}
|
||||||
.previewDisplayName("Active 1")
|
|
||||||
|
#Preview("Active 2") {
|
||||||
ServicesView(manager: FakeServicesManager(
|
ServicesView(manager: FakeServicesManager(
|
||||||
formulae: [
|
formulae: [
|
||||||
"php", "nginx", "dnsmasq", "thing1",
|
"php", "nginx", "dnsmasq", "thing1",
|
||||||
"thing2", "thing3", "thing4", "thing5"
|
"thing2", "thing3", "thing4", "thing5"
|
||||||
],
|
],
|
||||||
status: .inactive
|
status: .inactive
|
||||||
), perRow: 4)
|
), perRow: 4)
|
||||||
.frame(width: 330.0)
|
.frame(width: 330.0)
|
||||||
.previewDisplayName("Active 2")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,12 +98,10 @@ struct StatsView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StatsView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
StatsView(
|
||||||
StatsView(
|
memoryLimit: "1024 MB",
|
||||||
memoryLimit: "1024 MB",
|
maxPostSize: "1024 MB",
|
||||||
maxPostSize: "1024 MB",
|
maxUploadSize: "1024 MB"
|
||||||
maxUploadSize: "1024 MB"
|
).frame(height: 100)
|
||||||
).frame(height: 100)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,13 +53,11 @@ struct ProgressWindowView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProgressWindowView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
ProgressWindowView(
|
||||||
ProgressWindowView(
|
subject: ProgressViewSubject(
|
||||||
subject: ProgressViewSubject(
|
title: "Long running task",
|
||||||
title: "Long running task",
|
description: "Please be patient"
|
||||||
description: "Please be patient"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,10 +136,6 @@ struct OnboardingView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OnboardingView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
OnboardingView()
|
||||||
Group {
|
|
||||||
OnboardingView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,19 +98,19 @@ struct ByteLimitView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ByteLimitView_Previews: PreviewProvider {
|
#Preview("Byte Limit View") {
|
||||||
static var previews: some View {
|
PreferenceContainer(
|
||||||
PreferenceContainer(
|
name: "Max Size",
|
||||||
name: "Max Size",
|
description:
|
||||||
description:
|
"Here's an extensive description that is obviously way too long but it should wrap." +
|
||||||
"Here's an extensive description that is obviously way too long but it should wrap." +
|
"The point of the wrapping text is that is allows us to see what's going on with the layout here."
|
||||||
"The point of the wrapping text is that is allows us to see what's going on with the layout here."
|
) {
|
||||||
) {
|
ByteLimitView(preference: BytePhpPreference(key: "max_memory"))
|
||||||
ByteLimitView(preference: BytePhpPreference(key: "max_memory"))
|
}.frame(width: 600, height: 200)
|
||||||
}.frame(width: 600, height: 200)
|
}
|
||||||
|
|
||||||
ConfigManagerView()
|
#Preview("Config Manager") {
|
||||||
.frame(width: 600, height: .infinity)
|
ConfigManagerView()
|
||||||
.previewDisplayName("Config Manager")
|
.frame(width: 600, height: .infinity)
|
||||||
}
|
.previewDisplayName("Config Manager")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,10 +84,6 @@ struct ConfigManagerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConfigManagerView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
ConfigManagerView().frame(width: 600)
|
||||||
ConfigManagerView()
|
|
||||||
.frame(width: 600)
|
|
||||||
.previewDisplayName("Live Preview")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ class WarningManager: ObservableObject {
|
|||||||
.trimmingCharacters(in: .whitespacesAndNewlines) == "1"
|
.trimmingCharacters(in: .whitespacesAndNewlines) == "1"
|
||||||
},
|
},
|
||||||
name: "Running PHP Monitor with Rosetta on M1",
|
name: "Running PHP Monitor with Rosetta on M1",
|
||||||
title: "warnings.arm_compatibility.title".localized,
|
title: "warnings.arm_compatibility.title",
|
||||||
paragraphs: { return ["warnings.arm_compatibility.description".localized] },
|
paragraphs: { return ["warnings.arm_compatibility.description"] },
|
||||||
url: "https://github.com/nicoverbruggen/phpmon/wiki/PHP-Monitor-and-Apple-Silicon"
|
url: "https://github.com/nicoverbruggen/phpmon/wiki/PHP-Monitor-and-Apple-Silicon"
|
||||||
),
|
),
|
||||||
Warning(
|
Warning(
|
||||||
@@ -44,11 +44,11 @@ class WarningManager: ObservableObject {
|
|||||||
!FileSystem.isWriteableFile("/usr/local/bin/")
|
!FileSystem.isWriteableFile("/usr/local/bin/")
|
||||||
},
|
},
|
||||||
name: "Helpers cannot be symlinked and not in PATH",
|
name: "Helpers cannot be symlinked and not in PATH",
|
||||||
title: "warnings.helper_permissions.title".localized,
|
title: "warnings.helper_permissions.title",
|
||||||
paragraphs: { return [
|
paragraphs: { return [
|
||||||
"warnings.helper_permissions.description".localized,
|
"warnings.helper_permissions.description",
|
||||||
"warnings.helper_permissions.unavailable".localized,
|
"warnings.helper_permissions.unavailable",
|
||||||
"warnings.helper_permissions.symlink".localized
|
"warnings.helper_permissions.symlink"
|
||||||
] },
|
] },
|
||||||
url: "https://github.com/nicoverbruggen/phpmon/wiki/PHP-Monitor-helper-binaries"
|
url: "https://github.com/nicoverbruggen/phpmon/wiki/PHP-Monitor-helper-binaries"
|
||||||
),
|
),
|
||||||
@@ -58,7 +58,7 @@ class WarningManager: ObservableObject {
|
|||||||
return !PhpConfigChecker.shared.missing.isEmpty
|
return !PhpConfigChecker.shared.missing.isEmpty
|
||||||
},
|
},
|
||||||
name: "Your PHP installation is missing configuration files",
|
name: "Your PHP installation is missing configuration files",
|
||||||
title: "warnings.files_missing.title".localized,
|
title: "warnings.files_missing.title",
|
||||||
paragraphs: { return [
|
paragraphs: { return [
|
||||||
"warnings.files_missing.description".localized(
|
"warnings.files_missing.description".localized(
|
||||||
PhpConfigChecker.shared.missing.joined(separator: "\n• ")
|
PhpConfigChecker.shared.missing.joined(separator: "\n• ")
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ struct NoWarningsView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoWarningsView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
NoWarningsView().padding()
|
||||||
NoWarningsView()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,14 +94,12 @@ struct PhpDoctorView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WarningListView_Previews: PreviewProvider {
|
#Preview("Empty List") {
|
||||||
static var previews: some View {
|
PhpDoctorView(empty: true, fake: true, manager: WarningManager())
|
||||||
PhpDoctorView(empty: true, fake: true, manager: WarningManager())
|
.frame(width: 600, height: 480)
|
||||||
.frame(width: 600, height: 480)
|
}
|
||||||
.previewDisplayName("Empty List")
|
|
||||||
|
#Preview("List With All Warnings") {
|
||||||
PhpDoctorView(empty: false, fake: true, manager: WarningManager())
|
PhpDoctorView(empty: false, fake: true, manager: WarningManager())
|
||||||
.frame(width: 600, height: 480)
|
.frame(width: 600, height: 480)
|
||||||
.previewDisplayName("List With All Warnings")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ struct WarningView: View {
|
|||||||
Text(title.localizedForSwiftUI)
|
Text(title.localizedForSwiftUI)
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
ForEach(paragraphs, id: \.self) { paragraph in
|
ForEach(paragraphs, id: \.self) { paragraph in
|
||||||
Text(paragraph)
|
Text(paragraph.localizedForSwiftUI)
|
||||||
.font(.system(size: 13))
|
.font(.system(size: 13))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,23 +47,23 @@ struct WarningView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WarningView_Previews: PreviewProvider {
|
#Preview("Light Mode") {
|
||||||
static var previews: some View {
|
WarningView(
|
||||||
WarningView(
|
title: "warnings.helper_permissions.title",
|
||||||
title: "warnings.helper_permissions.title",
|
paragraphs: ["warnings.helper_permissions.description"],
|
||||||
paragraphs: ["warnings.helper_permissions.description"],
|
documentationUrl: "https://nicoverbruggen.be"
|
||||||
documentationUrl: "https://nicoverbruggen.be"
|
)
|
||||||
)
|
.frame(width: 600, height: 105)
|
||||||
.frame(width: 600, height: 105)
|
.padding(25)
|
||||||
|
}
|
||||||
WarningView(
|
|
||||||
title: "warnings.helper_permissions.title",
|
#Preview("Dark Mode") {
|
||||||
paragraphs: ["warnings.helper_permissions.description"],
|
WarningView(
|
||||||
documentationUrl: "https://nicoverbruggen.be"
|
title: "warnings.helper_permissions.title",
|
||||||
)
|
paragraphs: ["warnings.helper_permissions.description"],
|
||||||
.preferredColorScheme(.dark)
|
documentationUrl: "https://nicoverbruggen.be"
|
||||||
.frame(width: 600, height: 105)
|
)
|
||||||
|
.preferredColorScheme(.dark)
|
||||||
// WarningListView().frame(width: 600, height: 580)
|
.frame(width: 600, height: 105)
|
||||||
}
|
.padding(25)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,21 @@ class FakeBrewFormulaeHandler: HandlesBrewPhpFormulae {
|
|||||||
prerelease: true
|
prerelease: true
|
||||||
),
|
),
|
||||||
BrewPhpFormula(
|
BrewPhpFormula(
|
||||||
name: "php@8.3",
|
name: "php@8.4",
|
||||||
|
displayName: "PHP 8.4",
|
||||||
|
installedVersion: nil,
|
||||||
|
upgradeVersion: "8.4.0",
|
||||||
|
prerelease: true
|
||||||
|
),
|
||||||
|
BrewPhpFormula(
|
||||||
|
name: "php",
|
||||||
displayName: "PHP 8.3",
|
displayName: "PHP 8.3",
|
||||||
installedVersion: nil,
|
installedVersion: nil,
|
||||||
upgradeVersion: "8.3.0",
|
upgradeVersion: "8.3.0",
|
||||||
prerelease: true
|
prerelease: true
|
||||||
),
|
),
|
||||||
BrewPhpFormula(
|
BrewPhpFormula(
|
||||||
name: "php",
|
name: "php@8.2",
|
||||||
displayName: "PHP 8.2",
|
displayName: "PHP 8.2",
|
||||||
installedVersion: "8.2.3",
|
installedVersion: "8.2.3",
|
||||||
upgradeVersion: "8.2.4"
|
upgradeVersion: "8.2.4"
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
//
|
||||||
|
// PhpVersionManagerView+Interactivity.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 07/11/2023.
|
||||||
|
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
extension PhpVersionManagerView {
|
||||||
|
public func runCommand(_ command: InstallAndUpgradeCommand) async {
|
||||||
|
if PhpEnvironments.shared.isBusy {
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.action_prevented_busy.title".localized,
|
||||||
|
description: "phpman.action_prevented_busy.desc".localized,
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
self.setBusyStatus(true)
|
||||||
|
try await command.execute { progress in
|
||||||
|
Task { @MainActor in
|
||||||
|
self.status.title = progress.title
|
||||||
|
self.status.description = progress.description
|
||||||
|
self.status.busy = progress.value != 1
|
||||||
|
|
||||||
|
// Whenever a key step is finished, refresh the PHP versions
|
||||||
|
if progress.value == 1 {
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Finally, after completing the command, also refresh PHP versions
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
// and mark the app as no longer busy
|
||||||
|
self.setBusyStatus(false)
|
||||||
|
} catch let error {
|
||||||
|
let error = error as! BrewCommandError
|
||||||
|
let messages = error.log.suffix(2).joined(separator: "\n")
|
||||||
|
|
||||||
|
self.setBusyStatus(false)
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.failures.install.title".localized,
|
||||||
|
description: "phpman.failures.install.desc".localized(messages),
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func repairAll() async {
|
||||||
|
await self.runCommand(InstallAndUpgradeCommand(
|
||||||
|
title: "phpman.operations.repairing".localized,
|
||||||
|
upgrading: [],
|
||||||
|
installing: []
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func upgradeAll(_ formulae: [BrewPhpFormula]) async {
|
||||||
|
await self.runCommand(InstallAndUpgradeCommand(
|
||||||
|
title: "phpman.operations.updating".localized,
|
||||||
|
upgrading: formulae,
|
||||||
|
installing: []
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func install(_ formula: BrewPhpFormula) async {
|
||||||
|
await self.runCommand(InstallAndUpgradeCommand(
|
||||||
|
title: "phpman.operations.installing".localized(formula.displayName),
|
||||||
|
upgrading: [],
|
||||||
|
installing: [formula]
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func confirmUninstall(_ formula: BrewPhpFormula) async {
|
||||||
|
// Disallow removal of the currently active versipn
|
||||||
|
if formula.installedVersion == PhpEnvironments.shared.currentInstall?.version.text {
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.uninstall_prevented.title".localized,
|
||||||
|
description: "phpman.uninstall_prevented.desc".localized,
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Alert.confirm(
|
||||||
|
onWindow: App.shared.phpVersionManagerWindowController!.window!,
|
||||||
|
messageText: "phpman.warnings.removal.title".localized(formula.displayName),
|
||||||
|
informativeText: "phpman.warnings.removal.desc".localized(formula.displayName),
|
||||||
|
buttonTitle: "phpman.warnings.removal.button".localized,
|
||||||
|
buttonIsDestructive: true,
|
||||||
|
secondButtonTitle: "generic.cancel".localized,
|
||||||
|
style: .warning,
|
||||||
|
onFirstButtonPressed: {
|
||||||
|
Task { await self.uninstall(formula) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func uninstall(_ formula: BrewPhpFormula) async {
|
||||||
|
let command = RemovePhpVersionCommand(formula: formula.name)
|
||||||
|
|
||||||
|
do {
|
||||||
|
self.setBusyStatus(true)
|
||||||
|
try await command.execute { progress in
|
||||||
|
Task { @MainActor in
|
||||||
|
self.status.title = progress.title
|
||||||
|
self.status.description = progress.description
|
||||||
|
self.status.busy = progress.value != 1
|
||||||
|
|
||||||
|
if progress.value == 1 {
|
||||||
|
await self.handler.refreshPhpVersions(loadOutdated: false)
|
||||||
|
self.setBusyStatus(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
self.setBusyStatus(false)
|
||||||
|
self.presentErrorAlert(
|
||||||
|
title: "phpman.failures.uninstall.title".localized,
|
||||||
|
description: "phpman.failures.uninstall.desc".localized(
|
||||||
|
"brew uninstall \(formula.name) --force"
|
||||||
|
),
|
||||||
|
button: "generic.ok".localized
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setBusyStatus(_ busy: Bool) {
|
||||||
|
Task { @MainActor in
|
||||||
|
PhpEnvironments.shared.isBusy = busy
|
||||||
|
self.status.busy = busy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func presentErrorAlert(
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
button: String,
|
||||||
|
style: NSAlert.Style = .critical
|
||||||
|
) {
|
||||||
|
Alert.confirm(
|
||||||
|
onWindow: App.shared.phpVersionManagerWindowController!.window!,
|
||||||
|
messageText: title,
|
||||||
|
informativeText: description,
|
||||||
|
buttonTitle: button,
|
||||||
|
secondButtonTitle: "",
|
||||||
|
style: style,
|
||||||
|
onFirstButtonPressed: {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasUpdates: Bool {
|
||||||
|
return self.formulae.phpVersions.contains { formula in
|
||||||
|
return formula.hasUpgrade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
// swiftlint:disable type_body_length
|
|
||||||
struct PhpVersionManagerView: View {
|
struct PhpVersionManagerView: View {
|
||||||
@ObservedObject var formulae: BrewFormulaeObservable
|
@ObservedObject var formulae: BrewFormulaeObservable
|
||||||
@ObservedObject var status: PhpFormulaeStatus
|
@ObservedObject var status: PhpFormulaeStatus
|
||||||
@@ -132,240 +131,133 @@ struct PhpVersionManagerView: View {
|
|||||||
.padding(10)
|
.padding(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockingOverlayView(busy: self.status.busy, title: self.status.title, text: self.status.description) {
|
BlockingOverlayView(
|
||||||
List(Array(formulae.phpVersions.enumerated()), id: \.1.name) { (index, formula) in
|
busy: self.status.busy,
|
||||||
HStack(alignment: .center, spacing: 7.0) {
|
title: self.status.title,
|
||||||
Image(systemName: formula.icon)
|
text: self.status.description
|
||||||
.resizable()
|
) {
|
||||||
.aspectRatio(contentMode: .fit)
|
if #available(macOS 13, *) {
|
||||||
.frame(width: 16, height: 16)
|
List(Array(formulae.phpVersions.enumerated()), id: \.1.name) { (index, formula) in
|
||||||
.foregroundColor(formula.iconColor)
|
listContent(for: formula)
|
||||||
.padding(.horizontal, 5)
|
.listRowBackground(
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
index % 2 == 0
|
||||||
HStack {
|
? Color.gray.opacity(0)
|
||||||
Text(formula.displayName).bold()
|
: Color.gray.opacity(0.08)
|
||||||
|
)
|
||||||
if formula.prerelease {
|
.padding(.vertical, 8)
|
||||||
Text("phpman.version.prerelease".localized.uppercased())
|
.padding(.horizontal, 8)
|
||||||
.font(.system(size: 9))
|
.listRowSeparator(.hidden)
|
||||||
.padding(.horizontal, 5)
|
|
||||||
.padding(.vertical, 1)
|
|
||||||
.background(Color.appPrimary)
|
|
||||||
.foregroundColor(Color.white)
|
|
||||||
.clipShape(Capsule())
|
|
||||||
.fixedSize(horizontal: true, vertical: true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if formula.isInstalled && formula.hasUpgrade {
|
|
||||||
Text("phpman.version.has_update".localized(
|
|
||||||
formula.installedVersion!,
|
|
||||||
formula.upgradeVersion!
|
|
||||||
))
|
|
||||||
.font(.system(size: 11))
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
} else if formula.isInstalled && formula.installedVersion != nil {
|
|
||||||
Text("phpman.version.installed".localized(formula.installedVersion!))
|
|
||||||
.font(.system(size: 11))
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
} else {
|
|
||||||
Text("phpman.version.available_for_installation".localizedForSwiftUI)
|
|
||||||
.font(.system(size: 11))
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !formula.healthy {
|
|
||||||
Text("phpman.version.broken".localizedForSwiftUI)
|
|
||||||
.font(.system(size: 11))
|
|
||||||
.foregroundColor(.red)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
|
|
||||||
if !formula.healthy {
|
|
||||||
Button("phpman.buttons.repair".localizedForSwiftUI, role: .destructive) {
|
|
||||||
Task { await self.repairAll() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if formula.isInstalled {
|
|
||||||
Button("phpman.buttons.uninstall".localizedForSwiftUI, role: .destructive) {
|
|
||||||
Task { await self.confirmUninstall(formula) }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Button("phpman.buttons.install".localizedForSwiftUI) {
|
|
||||||
Task { await self.install(formula) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.listRowBackground(index % 2 == 0 ? Color.gray.opacity(0): Color.gray.opacity(0.08))
|
.edgesIgnoringSafeArea(.top)
|
||||||
.padding(.vertical, 8)
|
.listStyle(PlainListStyle())
|
||||||
.padding(.horizontal, 8)
|
} else {
|
||||||
|
List(Array(formulae.phpVersions.enumerated()), id: \.1.name) { (index, formula) in
|
||||||
|
listContent(for: formula)
|
||||||
|
.listRowBackground(
|
||||||
|
index % 2 == 0
|
||||||
|
? Color.gray.opacity(0)
|
||||||
|
: Color.gray.opacity(0.08)
|
||||||
|
)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
}
|
||||||
|
.edgesIgnoringSafeArea(.top)
|
||||||
|
.listStyle(PlainListStyle())
|
||||||
}
|
}
|
||||||
.edgesIgnoringSafeArea(.top)
|
|
||||||
.listStyle(PlainListStyle())
|
|
||||||
}
|
}
|
||||||
}.frame(width: 600, height: 600)
|
}.frame(width: 600, height: 600)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func runCommand(_ command: InstallAndUpgradeCommand) async {
|
// MARK: View Functions
|
||||||
if PhpEnvironments.shared.isBusy {
|
|
||||||
self.presentErrorAlert(
|
|
||||||
title: "phpman.action_prevented_busy.title".localized,
|
|
||||||
description: "phpman.action_prevented_busy.desc".localized,
|
|
||||||
button: "generic.ok".localized
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
private var prereleaseBadge: some View {
|
||||||
self.setBusyStatus(true)
|
Text("phpman.version.prerelease".localized.uppercased())
|
||||||
try await command.execute { progress in
|
.font(.system(size: 9))
|
||||||
Task { @MainActor in
|
.padding(.horizontal, 5)
|
||||||
self.status.title = progress.title
|
.padding(.vertical, 1)
|
||||||
self.status.description = progress.description
|
.background(Color.appPrimary)
|
||||||
self.status.busy = progress.value != 1
|
.foregroundColor(Color.white)
|
||||||
|
.clipShape(Capsule())
|
||||||
|
.fixedSize(horizontal: true, vertical: true)
|
||||||
|
}
|
||||||
|
|
||||||
// Whenever a key step is finished, refresh the PHP versions
|
private func formulaButtons(for formula: BrewPhpFormula) -> some View {
|
||||||
if progress.value == 1 {
|
HStack {
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
if !formula.healthy {
|
||||||
}
|
Button("phpman.buttons.repair".localizedForSwiftUI, role: .destructive) {
|
||||||
|
Task { await self.repairAll() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Finally, after completing the command, also refresh PHP versions
|
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
|
||||||
// and mark the app as no longer busy
|
|
||||||
self.setBusyStatus(false)
|
|
||||||
} catch let error {
|
|
||||||
let error = error as! BrewCommandError
|
|
||||||
let messages = error.log.suffix(2).joined(separator: "\n")
|
|
||||||
|
|
||||||
self.setBusyStatus(false)
|
if formula.isInstalled {
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
Button("phpman.buttons.uninstall".localizedForSwiftUI, role: .destructive) {
|
||||||
|
Task { await self.confirmUninstall(formula) }
|
||||||
self.presentErrorAlert(
|
}
|
||||||
title: "phpman.failures.install.title".localized,
|
} else {
|
||||||
description: "phpman.failures.install.desc".localized(messages),
|
Button("phpman.buttons.install".localizedForSwiftUI) {
|
||||||
button: "generic.ok".localized
|
Task { await self.install(formula) }
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func repairAll() async {
|
|
||||||
await self.runCommand(InstallAndUpgradeCommand(
|
|
||||||
title: "phpman.operations.repairing".localized,
|
|
||||||
upgrading: [],
|
|
||||||
installing: []
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func upgradeAll(_ formulae: [BrewPhpFormula]) async {
|
|
||||||
await self.runCommand(InstallAndUpgradeCommand(
|
|
||||||
title: "phpman.operations.updating".localized,
|
|
||||||
upgrading: formulae,
|
|
||||||
installing: []
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func install(_ formula: BrewPhpFormula) async {
|
|
||||||
await self.runCommand(InstallAndUpgradeCommand(
|
|
||||||
title: "phpman.operations.installing".localized(formula.displayName),
|
|
||||||
upgrading: [],
|
|
||||||
installing: [formula]
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func confirmUninstall(_ formula: BrewPhpFormula) async {
|
|
||||||
// Disallow removal of the currently active versipn
|
|
||||||
if formula.installedVersion == PhpEnvironments.shared.currentInstall?.version.text {
|
|
||||||
self.presentErrorAlert(
|
|
||||||
title: "phpman.uninstall_prevented.title".localized,
|
|
||||||
description: "phpman.uninstall_prevented.desc".localized,
|
|
||||||
button: "generic.ok".localized
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Alert.confirm(
|
|
||||||
onWindow: App.shared.phpVersionManagerWindowController!.window!,
|
|
||||||
messageText: "phpman.warnings.removal.title".localized(formula.displayName),
|
|
||||||
informativeText: "phpman.warnings.removal.desc".localized(formula.displayName),
|
|
||||||
buttonTitle: "phpman.warnings.removal.button".localized,
|
|
||||||
buttonIsDestructive: true,
|
|
||||||
secondButtonTitle: "generic.cancel".localized,
|
|
||||||
style: .warning,
|
|
||||||
onFirstButtonPressed: {
|
|
||||||
Task { await self.uninstall(formula) }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func uninstall(_ formula: BrewPhpFormula) async {
|
|
||||||
let command = RemovePhpVersionCommand(formula: formula.name)
|
|
||||||
|
|
||||||
do {
|
|
||||||
self.setBusyStatus(true)
|
|
||||||
try await command.execute { progress in
|
|
||||||
Task { @MainActor in
|
|
||||||
self.status.title = progress.title
|
|
||||||
self.status.description = progress.description
|
|
||||||
self.status.busy = progress.value != 1
|
|
||||||
|
|
||||||
if progress.value == 1 {
|
|
||||||
await self.handler.refreshPhpVersions(loadOutdated: false)
|
|
||||||
self.setBusyStatus(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
self.setBusyStatus(false)
|
|
||||||
self.presentErrorAlert(
|
|
||||||
title: "phpman.failures.uninstall.title".localized,
|
|
||||||
description: "phpman.failures.uninstall.desc".localized(
|
|
||||||
"brew uninstall \(formula.name) --force"
|
|
||||||
),
|
|
||||||
button: "generic.ok".localized
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setBusyStatus(_ busy: Bool) {
|
private func formulaDescription(for formula: BrewPhpFormula) -> some View {
|
||||||
Task { @MainActor in
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
PhpEnvironments.shared.isBusy = busy
|
HStack {
|
||||||
self.status.busy = busy
|
Text(formula.displayName).bold()
|
||||||
|
|
||||||
|
if formula.prerelease {
|
||||||
|
prereleaseBadge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if formula.isInstalled && formula.hasUpgrade {
|
||||||
|
Text("phpman.version.has_update".localized(
|
||||||
|
formula.installedVersion!,
|
||||||
|
formula.upgradeVersion!
|
||||||
|
))
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
} else if formula.isInstalled && formula.installedVersion != nil {
|
||||||
|
Text("phpman.version.installed".localized(formula.installedVersion!))
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
} else {
|
||||||
|
Text("phpman.version.available_for_installation".localizedForSwiftUI)
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !formula.healthy {
|
||||||
|
Text("phpman.version.broken".localizedForSwiftUI)
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundColor(.red)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func presentErrorAlert(
|
private func formulaIcon(for formula: BrewPhpFormula) -> some View {
|
||||||
title: String,
|
Image(systemName: formula.icon)
|
||||||
description: String,
|
.resizable()
|
||||||
button: String,
|
.aspectRatio(contentMode: .fit)
|
||||||
style: NSAlert.Style = .critical
|
.frame(width: 16, height: 16)
|
||||||
) {
|
.foregroundColor(formula.iconColor)
|
||||||
Alert.confirm(
|
.padding(.horizontal, 5)
|
||||||
onWindow: App.shared.phpVersionManagerWindowController!.window!,
|
|
||||||
messageText: title,
|
|
||||||
informativeText: description,
|
|
||||||
buttonTitle: button,
|
|
||||||
secondButtonTitle: "",
|
|
||||||
style: style,
|
|
||||||
onFirstButtonPressed: {}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasUpdates: Bool {
|
private func listContent(for formula: BrewPhpFormula) -> some View {
|
||||||
return self.formulae.phpVersions.contains { formula in
|
HStack(alignment: .center, spacing: 7.0) {
|
||||||
return formula.hasUpgrade
|
formulaIcon(for: formula)
|
||||||
|
formulaDescription(for: formula)
|
||||||
|
formulaButtons(for: formula)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// swiftlint:enable type_body_length
|
|
||||||
|
|
||||||
struct PhpVersionManagerView_Previews: PreviewProvider {
|
#Preview {
|
||||||
static var previews: some View {
|
PhpVersionManagerView(
|
||||||
PhpVersionManagerView(
|
formulae: Brew.shared.formulae,
|
||||||
formulae: Brew.shared.formulae,
|
handler: FakeBrewFormulaeHandler()
|
||||||
handler: FakeBrewFormulaeHandler()
|
).frame(width: 600, height: 600)
|
||||||
).frame(width: 600, height: 600)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user