1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-07 20:10:08 +02:00

New notice alert API

This commit is contained in:
2022-02-16 22:42:43 +01:00
parent bc0b50f5bf
commit 50f003a2bd
6 changed files with 245 additions and 37 deletions

View File

@ -28,6 +28,10 @@
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA627B07A1300544CD5 /* SelectPreferenceView.swift */; };
C4068CAA27B0890D00544CD5 /* MenuBarIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA927B0890D00544CD5 /* MenuBarIcons.swift */; };
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA927B0890D00544CD5 /* MenuBarIcons.swift */; };
C4080FF627BD8C6400BF2C6B /* Notice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* Notice.swift */; };
C4080FF727BD8C6400BF2C6B /* Notice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* Notice.swift */; };
C4080FFA27BD956700BF2C6B /* NoticeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* NoticeVC.swift */; };
C4080FFB27BD956700BF2C6B /* NoticeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* NoticeVC.swift */; };
C40B24F127A3106D0018C7D2 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E67279DE0540010F296 /* ServicesView.swift */; };
C40B24F227A310770018C7D2 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E72279DFCF40010F296 /* Events.swift */; };
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47331A1247093B7009A0597 /* StatusMenu.swift */; };
@ -215,6 +219,8 @@
C4068CA327B0780A00544CD5 /* CheckboxPreferenceView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CheckboxPreferenceView.xib; sourceTree = "<group>"; };
C4068CA627B07A1300544CD5 /* SelectPreferenceView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectPreferenceView.swift; sourceTree = "<group>"; };
C4068CA927B0890D00544CD5 /* MenuBarIcons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBarIcons.swift; sourceTree = "<group>"; };
C4080FF527BD8C6400BF2C6B /* Notice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notice.swift; sourceTree = "<group>"; };
C4080FF927BD956700BF2C6B /* NoticeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeVC.swift; sourceTree = "<group>"; };
C40C7F1D2772136000DDDCDC /* PhpEnv.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpEnv.swift; sourceTree = "<group>"; };
C40C7F2727721FF600DDDCDC /* ActivePhpInstallation+Checks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ActivePhpInstallation+Checks.swift"; sourceTree = "<group>"; };
C40C7F2F27722E8D00DDDCDC /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
@ -385,6 +391,15 @@
path = IAP;
sourceTree = "<group>";
};
C4080FF827BD955900BF2C6B /* Notice */ = {
isa = PBXGroup;
children = (
C4080FF527BD8C6400BF2C6B /* Notice.swift */,
C4080FF927BD956700BF2C6B /* NoticeVC.swift */,
);
path = Notice;
sourceTree = "<group>";
};
C40C7F1C27720E1400DDDCDC /* Test Files */ = {
isa = PBXGroup;
children = (
@ -460,6 +475,7 @@
C41E181722CB61EB0072CF09 /* Domain */ = {
isa = PBXGroup;
children = (
C4080FF827BD955900BF2C6B /* Notice */,
C4AF9F6B275445D300D44ED0 /* Integrations */,
C4B13B1D25C4915000548C3A /* App */,
C4D9ADBD27761084007277F4 /* PHP */,
@ -829,6 +845,7 @@
5420395926135DC100FB00FA /* PrefsVC.swift in Sources */,
C43603A0275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */,
C4068CA727B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
C4080FF627BD8C6400BF2C6B /* Notice.swift in Sources */,
C49E171F27A5736E00787921 /* PMServicesView.swift in Sources */,
C4EE55AD27708B9E001DF387 /* PMStatsView.swift in Sources */,
C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
@ -884,6 +901,7 @@
C48D0C9625CC80B100CC7490 /* HeaderView.swift in Sources */,
C4CE3BBA27B31F670086CA49 /* MainMenu+Composer.swift in Sources */,
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
C4080FFA27BD956700BF2C6B /* NoticeVC.swift in Sources */,
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */,
C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */,
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */,
@ -912,6 +930,7 @@
C4F780C825D80B75000DBC97 /* DateExtension.swift in Sources */,
C493084B279F331F009C240B /* AddSiteVC.swift in Sources */,
C4D9ADC0277610E1007277F4 /* PhpSwitcher.swift in Sources */,
C4080FFB27BD956700BF2C6B /* NoticeVC.swift in Sources */,
C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */,
C4F780B125D80B4D000DBC97 /* PhpExtension.swift in Sources */,
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
@ -947,6 +966,7 @@
C4CE3BBC27B324250086CA49 /* MainMenu+Composer.swift in Sources */,
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */,
C417DC75277614690015E6EE /* Helpers.swift in Sources */,
C4080FF727BD8C6400BF2C6B /* Notice.swift in Sources */,
C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */,
C4B97B79275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */,
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */,

View File

@ -116,6 +116,8 @@ class Actions {
Detects all currently available PHP versions,
and unlinks each and every one of them.
This all happens in sequence, nothing runs in parallel.
After this, the brew services are also stopped,
the latest PHP version is linked, and php + nginx are restarted.

View File

@ -88,6 +88,25 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
startup procedure.
*/
func applicationDidFinishLaunching(_ aNotification: Notification) {
/*
let notice = Notice.make()
.withInformation(
title: "Oh no, your PHP is kaput?!",
subtitle: "Unfortunately, PHP Monitor has detected an issue. You can find more info below."
// description: "brew install php@8.0 has returned error code -35"
)
.withPrimary(text: "Retry")
.withSecondary(text: "Quit", action: { _ in
exit(1)
})
.withTertiary(text: "Copy to Clipboard", action: { _ in
// Do something here
})
print(notice.present() == .alertFirstButtonReturn)
*/
// Make sure notifications will work
setupNotifications()
// Make sure the menu performs its initial checks

View File

@ -467,10 +467,9 @@
<!--Window Controller-->
<scene sceneID="BD0-La-ygq">
<objects>
<windowController id="nfT-AN-9ZW" sceneMemberID="viewController">
<window key="window" title="Notice" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" titleVisibility="hidden" id="AoF-SN-xB0">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<windowController storyboardIdentifier="noticeWindow" id="nfT-AN-9ZW" sceneMemberID="viewController">
<window key="window" title="Notice" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" titlebarAppearsTransparent="YES" toolbarStyle="unified" titleVisibility="hidden" id="AoF-SN-xB0">
<windowStyleMask key="styleMask" titled="YES" fullSizeContentView="YES"/>
<rect key="contentRect" x="425" y="462" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
<view key="contentView" id="Src-7L-4Z4">
@ -489,24 +488,22 @@
</objects>
<point key="canvasLocation" x="-575" y="1624"/>
</scene>
<!--View Controller-->
<!--NoticeVC-->
<scene sceneID="y9E-bB-wIG">
<objects>
<viewController storyboardIdentifier="noticeVC" id="hkw-9V-NxP" sceneMemberID="viewController">
<viewController storyboardIdentifier="noticeVC" id="hkw-9V-NxP" customClass="NoticeVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="UPH-hV-Naz">
<rect key="frame" x="0.0" y="0.0" width="508" height="207"/>
<rect key="frame" x="0.0" y="0.0" width="524" height="205"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="6U0-c0-4UL">
<rect key="frame" x="0.0" y="0.0" width="508" height="207"/>
<view key="contentView" id="aM7-ch-j0D">
<rect key="frame" x="0.0" y="0.0" width="508" height="207"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</view>
<color key="fillColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
</box>
<visualEffectView blendingMode="behindWindow" material="appearanceBased" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="JVG-5w-fPd">
<rect key="frame" x="0.0" y="0.0" width="524" height="205"/>
</visualEffectView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TCp-nS-HN2">
<rect key="frame" x="13" y="13" width="99" height="32"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="QWZ-BA-0g9"/>
</constraints>
<buttonCell key="cell" type="push" title="Secondary" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="eCk-FC-9Zr">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -514,9 +511,15 @@
Gw
</string>
</buttonCell>
<connections>
<action selector="secondaryButtonAction:" target="hkw-9V-NxP" id="YJs-Hu-lFP"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8zu-cF-KCX">
<rect key="frame" x="414" y="13" width="81" height="32"/>
<rect key="frame" x="417" y="13" width="94" height="32"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="4Uf-fh-jWJ"/>
</constraints>
<buttonCell key="cell" type="push" title="Primary" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="F26-vf-hFH">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -524,28 +527,31 @@ Gw
DQ
</string>
</buttonCell>
<connections>
<action selector="primaryButtonAction:" target="hkw-9V-NxP" id="W7d-3b-pZT"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="U1c-qS-cIm">
<rect key="frame" x="86" y="171" width="404" height="16"/>
<rect key="frame" x="102" y="151" width="404" height="19"/>
<constraints>
<constraint firstAttribute="width" constant="400" id="WgB-hj-d4P"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="400" id="WgB-hj-d4P"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="clipping" title="This is the title of the notice window." id="bzW-MI-jXb">
<font key="font" metaFont="systemBold"/>
<textFieldCell key="cell" selectable="YES" title="This is the title of the notice window." id="bzW-MI-jXb">
<font key="font" metaFont="systemBold" size="16"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yI6-qf-htf">
<rect key="frame" x="86" y="147" width="404" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="This is a slightly more expanded explanation." id="rY3-Nd-Iit">
<rect key="frame" x="102" y="127" width="404" height="16"/>
<textFieldCell key="cell" selectable="YES" title="This is a slightly more expanded explanation." id="rY3-Nd-Iit">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0rX-Ss-3Xd">
<rect key="frame" x="12" y="139" width="48" height="48"/>
<rect key="frame" x="12" y="137" width="48" height="48"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="Uib-R1-GEx">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -553,16 +559,16 @@ DQ
</buttonCell>
</button>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="QkM-5D-ZEQ">
<rect key="frame" x="17" y="136" width="54" height="54"/>
<rect key="frame" x="20" y="106" width="64" height="64"/>
<constraints>
<constraint firstAttribute="height" constant="48" id="VhJ-fI-IKC"/>
<constraint firstAttribute="width" constant="48" id="a2d-Gn-Oor"/>
<constraint firstAttribute="height" constant="64" id="VhJ-fI-IKC"/>
<constraint firstAttribute="width" constant="64" id="a2d-Gn-Oor"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" imageFrameStyle="grayBezel" id="7eT-Hw-EL9"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="7eT-Hw-EL9"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hml-dl-Cah">
<rect key="frame" x="86" y="90" width="404" height="42"/>
<textFieldCell key="cell" id="7iW-Lc-DqO">
<rect key="frame" x="102" y="70" width="404" height="42"/>
<textFieldCell key="cell" selectable="YES" id="7iW-Lc-DqO">
<font key="font" metaFont="smallSystem"/>
<string key="title">Sometimes you need a really long explanation and in that case you can get a really, really long description here, along with, for example, various steps you can take. This allows for a lot of text to be displayed, yay!</string>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -570,38 +576,55 @@ DQ
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="n5T-nn-k3j">
<rect key="frame" x="110" y="13" width="81" height="32"/>
<rect key="frame" x="110" y="13" width="94" height="32"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="JEC-0F-zaa"/>
</constraints>
<buttonCell key="cell" type="push" title="Tertiary" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mzA-Uu-gyf">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="tertiaryButtonAction:" target="hkw-9V-NxP" id="o1C-av-ifx"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="hml-dl-Cah" firstAttribute="leading" secondItem="yI6-qf-htf" secondAttribute="leading" id="1Lh-ve-rwK"/>
<constraint firstAttribute="trailing" secondItem="8zu-cF-KCX" secondAttribute="trailing" constant="20" symbolic="YES" id="1Wo-BO-MIr"/>
<constraint firstItem="6U0-c0-4UL" firstAttribute="top" secondItem="UPH-hV-Naz" secondAttribute="top" id="2Kx-K5-QHR"/>
<constraint firstItem="U1c-qS-cIm" firstAttribute="leading" secondItem="QkM-5D-ZEQ" secondAttribute="trailing" constant="20" id="2xX-Ma-iQZ"/>
<constraint firstAttribute="trailing" secondItem="U1c-qS-cIm" secondAttribute="trailing" constant="20" symbolic="YES" id="39u-Uk-TDI"/>
<constraint firstAttribute="bottom" secondItem="8zu-cF-KCX" secondAttribute="bottom" constant="20" symbolic="YES" id="9tE-WS-TgA"/>
<constraint firstItem="n5T-nn-k3j" firstAttribute="top" secondItem="TCp-nS-HN2" secondAttribute="top" id="BlS-Yb-ME8"/>
<constraint firstItem="JVG-5w-fPd" firstAttribute="top" secondItem="UPH-hV-Naz" secondAttribute="top" id="CE7-54-G09"/>
<constraint firstItem="hml-dl-Cah" firstAttribute="trailing" secondItem="yI6-qf-htf" secondAttribute="trailing" id="DBa-7d-sS3"/>
<constraint firstItem="n5T-nn-k3j" firstAttribute="leading" secondItem="TCp-nS-HN2" secondAttribute="trailing" constant="12" symbolic="YES" id="H9Z-Cc-sZr"/>
<constraint firstItem="yI6-qf-htf" firstAttribute="trailing" secondItem="U1c-qS-cIm" secondAttribute="trailing" id="NvJ-vf-wEl"/>
<constraint firstItem="TCp-nS-HN2" firstAttribute="leading" secondItem="UPH-hV-Naz" secondAttribute="leading" constant="20" symbolic="YES" id="Oxa-b8-QSZ"/>
<constraint firstItem="hml-dl-Cah" firstAttribute="top" secondItem="yI6-qf-htf" secondAttribute="bottom" constant="15" id="Pmz-I9-2up"/>
<constraint firstItem="8zu-cF-KCX" firstAttribute="top" secondItem="hml-dl-Cah" secondAttribute="bottom" constant="50" id="Uah-cm-AeJ"/>
<constraint firstAttribute="bottom" secondItem="6U0-c0-4UL" secondAttribute="bottom" id="Z9d-4l-X8c"/>
<constraint firstItem="U1c-qS-cIm" firstAttribute="top" secondItem="UPH-hV-Naz" secondAttribute="top" constant="20" symbolic="YES" id="b8P-f5-G6s"/>
<constraint firstItem="8zu-cF-KCX" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="n5T-nn-k3j" secondAttribute="trailing" constant="12" symbolic="YES" id="SrE-Z3-bDB"/>
<constraint firstItem="8zu-cF-KCX" firstAttribute="top" secondItem="hml-dl-Cah" secondAttribute="bottom" constant="30" id="Uah-cm-AeJ"/>
<constraint firstItem="U1c-qS-cIm" firstAttribute="top" secondItem="UPH-hV-Naz" secondAttribute="top" constant="35" id="Uqt-sc-vxn"/>
<constraint firstItem="QkM-5D-ZEQ" firstAttribute="top" secondItem="U1c-qS-cIm" secondAttribute="top" id="WAj-rw-srg"/>
<constraint firstItem="yI6-qf-htf" firstAttribute="leading" secondItem="U1c-qS-cIm" secondAttribute="leading" id="bng-pH-jSG"/>
<constraint firstAttribute="trailing" secondItem="JVG-5w-fPd" secondAttribute="trailing" id="dRt-Pq-6n0"/>
<constraint firstItem="JVG-5w-fPd" firstAttribute="leading" secondItem="UPH-hV-Naz" secondAttribute="leading" id="ejC-of-zjN"/>
<constraint firstAttribute="bottom" secondItem="JVG-5w-fPd" secondAttribute="bottom" id="hGp-DD-cKr"/>
<constraint firstItem="QkM-5D-ZEQ" firstAttribute="leading" secondItem="UPH-hV-Naz" secondAttribute="leading" constant="20" symbolic="YES" id="jG8-dt-l4x"/>
<constraint firstAttribute="trailing" secondItem="6U0-c0-4UL" secondAttribute="trailing" id="khc-R8-fWk"/>
<constraint firstItem="yI6-qf-htf" firstAttribute="top" secondItem="U1c-qS-cIm" secondAttribute="bottom" constant="8" symbolic="YES" id="kqR-yg-zdG"/>
<constraint firstItem="6U0-c0-4UL" firstAttribute="leading" secondItem="UPH-hV-Naz" secondAttribute="leading" id="qiT-SB-MSz"/>
<constraint firstItem="QkM-5D-ZEQ" firstAttribute="top" secondItem="UPH-hV-Naz" secondAttribute="top" constant="20" symbolic="YES" id="rVw-A2-0JC"/>
<constraint firstAttribute="bottom" secondItem="TCp-nS-HN2" secondAttribute="bottom" constant="20" symbolic="YES" id="sm1-Qr-6iV"/>
</constraints>
</view>
<connections>
<outlet property="buttonPrimary" destination="8zu-cF-KCX" id="MT5-Px-K97"/>
<outlet property="buttonSecondary" destination="TCp-nS-HN2" id="nPn-OX-Z4m"/>
<outlet property="buttonTertiary" destination="n5T-nn-k3j" id="UnB-8x-s3D"/>
<outlet property="imageView" destination="QkM-5D-ZEQ" id="zsW-l7-eH0"/>
<outlet property="labelDescription" destination="hml-dl-Cah" id="ehw-zs-EPc"/>
<outlet property="labelSubtitle" destination="yI6-qf-htf" id="m7A-bX-HE8"/>
<outlet property="labelTitle" destination="U1c-qS-cIm" id="oM3-kl-PL8"/>
<outlet property="primaryButtonTopMargin" destination="Uah-cm-AeJ" id="bQ0-Us-LKh"/>
</connections>
</viewController>
<customObject id="5Ts-EZ-bJh" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>

View File

@ -0,0 +1,81 @@
//
// Notice.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 16/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
class Notice {
var windowController: NSWindowController!
var noticeVC: NoticeVC {
return self.windowController.contentViewController as! NoticeVC
}
public static func make() -> Notice {
let storyboard = NSStoryboard(name: "Main" , bundle : nil)
let notice = Notice()
notice.windowController = storyboard.instantiateController(
withIdentifier: "noticeWindow"
) as? NSWindowController
return notice
}
public func withPrimary(
text: String,
action: @escaping (NoticeVC) -> 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: ((NoticeVC) -> Void)? = nil
) -> Self {
self.noticeVC.buttonSecondary.title = text
self.noticeVC.actionSecondary = action
return self
}
public func withTertiary(
text: String,
action: ((NoticeVC) -> Void)? = nil
) -> Self {
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
}
public func present() -> NSApplication.ModalResponse {
NSApp.activate(ignoringOtherApps: true)
windowController.window?.makeKeyAndOrderFront(nil)
return NSApplication.shared.runModal(for: windowController.window!)
}
}

View File

@ -0,0 +1,63 @@
//
// NoticeVC.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 16/02/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
class NoticeVC: NSViewController {
@IBOutlet weak var labelTitle: NSTextField!
@IBOutlet weak var labelSubtitle: NSTextField!
@IBOutlet weak var labelDescription: NSTextField!
@IBOutlet weak var buttonPrimary: NSButton!
@IBOutlet weak var buttonSecondary: NSButton!
@IBOutlet weak var buttonTertiary: NSButton!
var actionPrimary: (NoticeVC) -> Void = { _ in }
var actionSecondary: ((NoticeVC) -> Void)?
var actionTertiary: ((NoticeVC) -> Void)?
@IBOutlet weak var imageView: NSImageView!
@IBOutlet weak var primaryButtonTopMargin: NSLayoutConstraint!
override func viewWillAppear() {
imageView.image = NSApp.applicationIconImage
if actionSecondary == nil {
buttonSecondary.isHidden = true
}
if actionTertiary == nil {
buttonTertiary.isHidden = true
}
}
@IBAction func primaryButtonAction(_ sender: Any) {
self.actionPrimary(self)
}
@IBAction func secondaryButtonAction(_ sender: Any) {
if self.actionSecondary != nil {
self.actionSecondary!(self)
} else {
self.close(with: .alertSecondButtonReturn)
}
}
@IBAction func tertiaryButtonAction(_ sender: Any) {
if self.actionSecondary != nil {
self.actionTertiary!(self)
}
}
public func close(with code: NSApplication.ModalResponse) {
self.view.window?.close()
NSApplication.shared.stopModal(withCode: code)
}
}