1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2026-04-02 17:40:08 +02:00

♻️ WIP: Refactoring

This commit is contained in:
2026-02-27 14:09:23 +01:00
parent 69c72269f5
commit 091c026231
3 changed files with 100 additions and 55 deletions

View File

@@ -29,7 +29,6 @@ struct StartupAlertButtonRow: View {
onQuit() onQuit()
} }
.focused($focusedButton, equals: .quit) .focused($focusedButton, equals: .quit)
.disabled(state == .running)
Spacer() Spacer()
@@ -64,6 +63,22 @@ struct StartupAlertButtonRow: View {
.font(.subheadline) .font(.subheadline)
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
} }
case .failed:
HStack(spacing: 6) {
Image(systemName: "xmark.circle.fill")
.foregroundStyle(.red)
Text("Fix did not resolve the issue.")
.font(.subheadline)
.foregroundStyle(.secondary)
}
Spacer()
Button("startup.alert.retry".localized) {
onRetry()
}
.focused($focusedButton, equals: .retry)
} }
} }
.padding(20) .padding(20)
@@ -99,10 +114,18 @@ struct StartupAlertButtonRow: View {
.frame(width: 460) .frame(width: 460)
} }
#Preview("Fix succeeded") { #Preview("Fix Succeeded") {
StartupAlertButtonRow( StartupAlertButtonRow(
state: .completed, hasFix: true, state: .completed, hasFix: true,
onQuit: {}, onRetry: {}, onFix: {} onQuit: {}, onRetry: {}, onFix: {}
) )
.frame(width: 460) .frame(width: 460)
} }
#Preview("Fix Failed") {
StartupAlertButtonRow(
state: .failed, hasFix: true,
onQuit: {}, onRetry: {}, onFix: {}
)
.frame(width: 460)
}

View File

@@ -30,14 +30,16 @@ struct StartupAlertView: View {
subtitleText: viewModel.check.subtitleText subtitleText: viewModel.check.subtitleText
) )
if viewModel.state == .running || (viewModel.hasFix && viewModel.state == .idle) { if viewModel.state == .running
|| viewModel.state == .failed
|| (viewModel.hasFix && viewModel.state == .idle) {
Divider() Divider()
VStack(alignment: .leading, spacing: 12) { VStack(alignment: .leading, spacing: 12) {
if viewModel.state == .running { if viewModel.state == .running || viewModel.state == .failed {
StartupOutputView( StartupOutputView(
lines: viewModel.outputLines, lines: viewModel.outputLines,
isRunning: true isRunning: viewModel.state == .running
) )
} else { } else {
StartupFixCommandView( StartupFixCommandView(
@@ -86,8 +88,24 @@ struct StartupAlertView: View {
// MARK: - Previews // MARK: - Previews
#Preview("Fix Available — brew link php") { #Preview("No Fix Available") {
let check = EnvironmentCheck( return StartupAlertView(
viewModel: StartupAlertViewModel(check: EnvironmentCheck(
command: { _ in return true },
fix: nil,
name: "preview_php_binary",
titleText: "startup.errors.php_binary.title".localized,
subtitleText: "startup.errors.php_binary.subtitle".localized,
descriptionText: "startup.errors.php_binary.desc".localized(
App.shared.container.paths.php
)
))
)
}
#Preview("Fix Available") {
return StartupAlertView(
viewModel: StartupAlertViewModel(check: EnvironmentCheck(
command: { _ in return true }, command: { _ in return true },
fix: { _, output in output("Running brew link php...", .stdOut) }, fix: { _, output in output("Running brew link php...", .stdOut) },
fixDescription: "brew link php", fixDescription: "brew link php",
@@ -97,26 +115,11 @@ struct StartupAlertView: View {
descriptionText: "startup.errors.php_binary.desc".localized( descriptionText: "startup.errors.php_binary.desc".localized(
App.shared.container.paths.php App.shared.container.paths.php
) )
))
) )
let vm = StartupAlertViewModel(check: check)
return StartupAlertView(viewModel: vm)
} }
#Preview("Fix Available — valet trust") { #Preview("Fix Running") {
let check = EnvironmentCheck(
command: { _ in return true },
fix: { _, output in output("Password required...", .stdOut) },
fixDescription: "valet trust",
name: "preview_sudoers_brew",
titleText: "startup.errors.sudoers_brew.title".localized,
subtitleText: "startup.errors.sudoers_brew.subtitle".localized,
descriptionText: "startup.errors.sudoers_brew.desc".localized
)
let vm = StartupAlertViewModel(check: check)
return StartupAlertView(viewModel: vm)
}
#Preview("Fix Running — brew link php") {
StartupAlertView(viewModel: StartupAlertViewModel( StartupAlertView(viewModel: StartupAlertViewModel(
check: EnvironmentCheck( check: EnvironmentCheck(
command: { _ in return true }, command: { _ in return true },
@@ -132,34 +135,52 @@ struct StartupAlertView: View {
state: .running, state: .running,
outputLines: [ outputLines: [
OutputLine(text: "==> Linking Binary 'php' to '/opt/homebrew/bin/php'", stream: .stdOut), OutputLine(text: "==> Linking Binary 'php' to '/opt/homebrew/bin/php'", stream: .stdOut),
OutputLine(text: "==> Downloading https://formulae.brew.sh/api/formula.jws.json", stream: .stdOut),
OutputLine(text: "Already downloaded: /Users/nico/Library/Caches/Homebrew/downloads/abc123.json", stream: .stdOut),
OutputLine(text: "Warning: php is keg-only and must be linked with --force", stream: .stdErr),
OutputLine(text: "==> Linking php... linked 25 files", stream: .stdOut) OutputLine(text: "==> Linking php... linked 25 files", stream: .stdOut)
] ]
)) ))
} }
#Preview("No Fix — Valet version unsupported") { #Preview("Fix Failed") {
let check = EnvironmentCheck( StartupAlertView(viewModel: StartupAlertViewModel(
check: EnvironmentCheck(
command: { _ in return true }, command: { _ in return true },
name: "preview_valet_version", fix: { _, output in output("Running brew link php...", .stdOut) },
titleText: "startup.errors.valet_version_not_supported.title".localized, fixDescription: "brew link php",
subtitleText: "startup.errors.valet_version_not_supported.subtitle".localized, name: "preview_php_binary_failed",
descriptionText: "startup.errors.valet_version_not_supported.desc".localized titleText: "startup.errors.php_binary.title".localized,
subtitleText: "startup.errors.php_binary.subtitle".localized,
descriptionText: "startup.errors.php_binary.desc".localized(
App.shared.container.paths.php
) )
let vm = StartupAlertViewModel(check: check) ),
return StartupAlertView(viewModel: vm) state: .failed,
outputLines: [
OutputLine(text: "==> Linking Binary 'php' to '/opt/homebrew/bin/php'", stream: .stdOut),
OutputLine(text: "Warning: php is keg-only and must be linked with --force", stream: .stdErr),
OutputLine(text: "", stream: .stdOut),
OutputLine(text: "---\nFix did not resolve the issue.", stream: .stdOut)
]
))
} }
#Preview("No Fix — Herd running") { #Preview("Fix Completed") {
let check = EnvironmentCheck( StartupAlertView(viewModel: StartupAlertViewModel(
check: EnvironmentCheck(
command: { _ in return true }, command: { _ in return true },
name: "preview_herd_running", fix: { _, output in output("Running brew link php...", .stdOut) },
titleText: "startup.errors.herd_running.title".localized, fixDescription: "brew link php",
subtitleText: "startup.errors.herd_running.subtitle".localized, name: "preview_php_binary_completed",
descriptionText: "startup.errors.herd_running.desc".localized titleText: "startup.errors.php_binary.title".localized,
subtitleText: "startup.errors.php_binary.subtitle".localized,
descriptionText: "startup.errors.php_binary.desc".localized(
App.shared.container.paths.php
) )
let vm = StartupAlertViewModel(check: check) ),
return StartupAlertView(viewModel: vm) state: .completed,
outputLines: [
OutputLine(text: "==> Linking Binary 'php' to '/opt/homebrew/bin/php'", stream: .stdOut),
OutputLine(text: "==> Linking php... linked 25 files", stream: .stdOut),
OutputLine(text: "---\nFix applied successfully! Continuing...", stream: .stdOut)
]
))
} }

View File

@@ -13,6 +13,7 @@ class StartupAlertViewModel: ObservableObject {
case idle case idle
case running case running
case completed case completed
case failed
} }
/// The actual check that is associated with this alert modal /// The actual check that is associated with this alert modal
@@ -97,12 +98,12 @@ class StartupAlertViewModel: ObservableObject {
} }
@MainActor private func fail() { @MainActor private func fail() {
self.state = .idle self.state = .failed
self.outputLines.append(OutputLine(text: "---\nFix did not resolve the issue.", stream: .stdErr)) self.outputLines.append(OutputLine(text: "---\nFix did not resolve the issue.", stream: .stdErr))
} }
@MainActor private func errorAndIdle(_ error: Error) { @MainActor private func errorAndIdle(_ error: Error) {
self.state = .idle self.state = .failed
self.outputLines.append(OutputLine(text: "---\nError: \(error.localizedDescription)", stream: .stdErr)) self.outputLines.append(OutputLine(text: "---\nError: \(error.localizedDescription)", stream: .stdErr))
} }