mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
🏗 More SwiftUI experiments
This commit is contained in:
@ -109,7 +109,7 @@
|
|||||||
<EnvironmentVariable
|
<EnvironmentVariable
|
||||||
key = "PAINT_PHPMON_SWIFTUI_VIEWS"
|
key = "PAINT_PHPMON_SWIFTUI_VIEWS"
|
||||||
value = ""
|
value = ""
|
||||||
isEnabled = "YES">
|
isEnabled = "NO">
|
||||||
</EnvironmentVariable>
|
</EnvironmentVariable>
|
||||||
</EnvironmentVariables>
|
</EnvironmentVariables>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
|
@ -9,25 +9,23 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class FakeServicesManager: ServicesManager {
|
class FakeServicesManager: ServicesManager {
|
||||||
override init() {
|
var fixedFormulae: [String] = []
|
||||||
|
var fixedStatus: ServiceStatus = .loading
|
||||||
|
|
||||||
|
init(
|
||||||
|
formulae: [String] = ["php", "nginx", "dnsmasq"],
|
||||||
|
status: ServiceStatus = .loading
|
||||||
|
) {
|
||||||
Log.warn("A fake services manager is being used, so Homebrew formula resolver is set to act in fake mode.")
|
Log.warn("A fake services manager is being used, so Homebrew formula resolver is set to act in fake mode.")
|
||||||
Log.warn("If you do not want this behaviour, never instantiate FakeServicesManager!")
|
Log.warn("If you do not want this behaviour, never instantiate FakeServicesManager!")
|
||||||
Homebrew.fake = true
|
|
||||||
|
self.fixedFormulae = formulae
|
||||||
|
self.fixedStatus = status
|
||||||
}
|
}
|
||||||
|
|
||||||
override var formulae: [HomebrewFormula] {
|
override var formulae: [HomebrewFormula] {
|
||||||
var formulae = [
|
return fixedFormulae.map { formula in
|
||||||
Homebrew.Formulae.php,
|
return HomebrewFormula.init(formula, elevated: false)
|
||||||
Homebrew.Formulae.nginx,
|
}
|
||||||
Homebrew.Formulae.dnsmasq
|
|
||||||
]
|
|
||||||
|
|
||||||
let additionalFormulae = ["mailhog", "coolio"].map({ name in
|
|
||||||
return HomebrewFormula(name, elevated: false)
|
|
||||||
})
|
|
||||||
|
|
||||||
formulae.append(contentsOf: additionalFormulae)
|
|
||||||
|
|
||||||
return formulae
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ public class ServiceWrapper: ObservableObject, Identifiable, Hashable {
|
|||||||
|
|
||||||
init(formula: HomebrewFormula) {
|
init(formula: HomebrewFormula) {
|
||||||
self.formula = formula
|
self.formula = formula
|
||||||
|
self.isBusy = true
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func == (lhs: ServiceWrapper, rhs: ServiceWrapper) -> Bool {
|
public static func == (lhs: ServiceWrapper, rhs: ServiceWrapper) -> Bool {
|
||||||
|
@ -10,6 +10,7 @@ import Foundation
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct ServicesView: View {
|
struct ServicesView: View {
|
||||||
|
|
||||||
static func asMenuItem(perRow: Int = 4) -> NSMenuItem {
|
static func asMenuItem(perRow: Int = 4) -> NSMenuItem {
|
||||||
let item = NSMenuItem()
|
let item = NSMenuItem()
|
||||||
|
|
||||||
@ -23,8 +24,9 @@ struct ServicesView: View {
|
|||||||
let view = NSHostingView(rootView: rootView)
|
let view = NSHostingView(rootView: rootView)
|
||||||
view.autoresizingMask = [.width, .height]
|
view.autoresizingMask = [.width, .height]
|
||||||
view.setFrameSize(
|
view.setFrameSize(
|
||||||
CGSize(width: view.frame.width, height: rootView.height)
|
CGSize(width: view.frame.width, height: rootView.height + 30)
|
||||||
)
|
)
|
||||||
|
view.layer?.backgroundColor = CGColor.init(red: 255, green: 0, blue: 0, alpha: 0)
|
||||||
view.focusRingType = .none
|
view.focusRingType = .none
|
||||||
|
|
||||||
item.view = view
|
item.view = view
|
||||||
@ -44,21 +46,33 @@ struct ServicesView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
GeometryReader { geometry in
|
|
||||||
VStack {
|
VStack {
|
||||||
|
VStack(alignment: .leading) {
|
||||||
ForEach(manager.services.chunked(by: perRow), id: \.self) { chunk in
|
ForEach(manager.services.chunked(by: perRow), id: \.self) { chunk in
|
||||||
HStack {
|
HStack {
|
||||||
ForEach(chunk) { service in
|
ForEach(chunk) { service in
|
||||||
ServiceView(service: service)
|
ServiceView(service: service).frame(minWidth: 70)
|
||||||
.frame(width: abs((geometry.size.width - 15) / CGFloat(perRow)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.padding(.top, 10)
|
|
||||||
}
|
}
|
||||||
.frame(height: self.height)
|
.frame(height: self.height)
|
||||||
.background(Color.debug)
|
.frame(maxWidth: .infinity, alignment: .center)
|
||||||
|
// .background(Color.red)
|
||||||
|
|
||||||
|
VStack(alignment: .center) {
|
||||||
|
HStack {
|
||||||
|
Circle()
|
||||||
|
.frame(width: 12, height: 12)
|
||||||
|
.foregroundColor(.yellow)
|
||||||
|
Text("Determining services status...")
|
||||||
|
.font(.system(size: 12))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(height: 25)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .center)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,22 +80,34 @@ struct ServiceView: View {
|
|||||||
@ObservedObject var service: ServiceWrapper
|
@ObservedObject var service: ServiceWrapper
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
Text(service.name.uppercased())
|
Text(service.name.uppercased())
|
||||||
.font(.system(size: 10))
|
.font(.system(size: 10))
|
||||||
.frame(minWidth: 0, maxWidth: .infinity)
|
.frame(minWidth: 70, alignment: .center)
|
||||||
.padding(.bottom, 4)
|
.padding(.top, 4)
|
||||||
.background(Color.debug)
|
.padding(.bottom, 2)
|
||||||
if service.status == .loading {
|
if service.status == .loading {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
.scaleEffect(x: 0.5, y: 0.5, anchor: .center)
|
.scaleEffect(x: 0.5, y: 0.5, anchor: .center)
|
||||||
.frame(width: 16.0, height: 20.0)
|
.frame(minWidth: 70, alignment: .center)
|
||||||
}
|
}
|
||||||
if service.status == .missing {
|
if service.status == .missing {
|
||||||
Button { print("we pressed da button ")} label: {
|
Button {
|
||||||
|
Task { @MainActor in
|
||||||
|
BetterAlert().withInformation(
|
||||||
|
title: "alert.warnings.service_missing.title".localized,
|
||||||
|
subtitle: "alert.warnings.service_missing.subtitle".localized,
|
||||||
|
description: "alert.warnings.service_missing.description".localized
|
||||||
|
)
|
||||||
|
.withPrimary(text: "OK")
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
Text("?")
|
Text("?")
|
||||||
}
|
}
|
||||||
|
.focusable(false)
|
||||||
.buttonStyle(BlueButton())
|
.buttonStyle(BlueButton())
|
||||||
|
.frame(minWidth: 70, alignment: .center)
|
||||||
}
|
}
|
||||||
if service.status == .active {
|
if service.status == .active {
|
||||||
Button {
|
Button {
|
||||||
@ -103,18 +129,18 @@ struct ServiceView: View {
|
|||||||
.foregroundColor(Color("IconColorRed"))
|
.foregroundColor(Color("IconColorRed"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}.frame(minWidth: 70)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct BlueButton: ButtonStyle {
|
public struct BlueButton: ButtonStyle {
|
||||||
public func makeBody(configuration: Configuration) -> some View {
|
public func makeBody(configuration: Configuration) -> some View {
|
||||||
configuration.label
|
configuration.label
|
||||||
.padding(.bottom, 5)
|
.frame(width: 30, height: 30)
|
||||||
.padding(.top, 5)
|
.background(configuration.isPressed
|
||||||
.padding(.leading, 10)
|
? Color(red: 0, green: 0, blue: 0.9)
|
||||||
.padding(.trailing, 10)
|
: Color(red: 0, green: 0, blue: 0.5)
|
||||||
.background(Color(red: 0, green: 0, blue: 0.5))
|
)
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
.clipShape(Capsule())
|
.clipShape(Capsule())
|
||||||
}
|
}
|
||||||
@ -122,17 +148,8 @@ public struct BlueButton: ButtonStyle {
|
|||||||
|
|
||||||
struct ServicesView_Previews: PreviewProvider {
|
struct ServicesView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ServicesView(manager: FakeServicesManager(), perRow: 3)
|
ServicesView(manager: FakeServicesManager(), perRow: 4)
|
||||||
.frame(width: 330.0)
|
.frame(width: 330.0)
|
||||||
.previewDisplayName("Loading")
|
.previewDisplayName("Loading")
|
||||||
|
|
||||||
ServicesView(manager: FakeServicesManager(), perRow: 3)
|
|
||||||
.frame(width: 330.0)
|
|
||||||
.previewDisplayName("Light Mode")
|
|
||||||
|
|
||||||
ServicesView(manager: FakeServicesManager(), perRow: 3)
|
|
||||||
.frame(width: 330.0)
|
|
||||||
.previewDisplayName("Dark Mode")
|
|
||||||
.preferredColorScheme(.dark)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user