1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-06 11:30:08 +02:00
Files
app/phpmon/Domain/Notice/BetterAlert.swift
2023-11-21 18:19:17 +01:00

123 lines
3.5 KiB
Swift

//
// Notice.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 16/02/2022.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
@MainActor
class BetterAlert {
var windowController: NSWindowController!
var noticeVC: BetterAlertVC {
return self.windowController.contentViewController as! BetterAlertVC
}
init() {
let storyboard = NSStoryboard(name: "Main", bundle: nil)
self.windowController = storyboard.instantiateController(
withIdentifier: "noticeWindow"
) as? NSWindowController
}
public static func make() -> BetterAlert {
return BetterAlert()
}
public func withPrimary(
text: String,
action: @MainActor @escaping (BetterAlertVC) -> Void = { vc in
vc.close(with: .alertFirstButtonReturn)
}
) -> Self {
self.noticeVC.buttonPrimary.title = text
self.noticeVC.actionPrimary = action
return self
}
public func withSecondary(
text: String,
action: (@MainActor (BetterAlertVC) -> Void)? = { vc in
vc.close(with: .alertSecondButtonReturn)
}
) -> Self {
self.noticeVC.buttonSecondary.title = text
self.noticeVC.actionSecondary = action
return self
}
public func withTertiary(
text: String = "",
action: (@MainActor (BetterAlertVC) -> Void)? = nil
) -> Self {
if text == "" {
self.noticeVC.buttonTertiary.bezelStyle = .helpButton
}
self.noticeVC.buttonTertiary.title = text
self.noticeVC.actionTertiary = action
return self
}
public func withInformation(
title: String,
subtitle: String,
description: String = ""
) -> Self {
self.noticeVC.labelTitle.stringValue = title
self.noticeVC.labelSubtitle.stringValue = subtitle
self.noticeVC.labelDescription.stringValue = description
// If the description is missing, handle the excess space and change the top margin
if description == "" {
self.noticeVC.labelDescription.isHidden = true
self.noticeVC.primaryButtonTopMargin.constant = 0
}
return self
}
/**
Shows the modal and returns a ModalResponse.
If you wish to simply show the alert and disregard the outcome, use `show`.
*/
@MainActor public func runModal() -> NSApplication.ModalResponse {
if !Thread.isMainThread {
fatalError("You should always present alerts on the main thread!")
}
NSApp.activate(ignoringOtherApps: true)
windowController.window?.makeKeyAndOrderFront(nil)
windowController.window?.setCenterPosition(offsetY: 70)
return NSApplication.shared.runModal(for: windowController.window!)
}
/** Shows the modal and returns true if the user pressed the primary button. */
@MainActor public func didSelectPrimary() -> Bool {
return self.runModal() == .alertFirstButtonReturn
}
/**
Shows the modal and does not return anything.
*/
@MainActor public func show() {
_ = self.runModal()
}
/**
Shows the modal for a particular error.
*/
@MainActor public static func show(for error: Error & AlertableError) {
let key = error.getErrorMessageKey()
return BetterAlert().withInformation(
title: "\(key).title".localized,
subtitle: "\(key).description".localized
).withPrimary(text: "generic.ok".localized).show()
}
}