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

👌 Use BetterAlert API

This commit is contained in:
2022-02-16 23:51:06 +01:00
parent 50f003a2bd
commit 5a0b2f319b
7 changed files with 57 additions and 50 deletions

View File

@ -28,10 +28,10 @@
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA627B07A1300544CD5 /* SelectPreferenceView.swift */; }; C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA627B07A1300544CD5 /* SelectPreferenceView.swift */; };
C4068CAA27B0890D00544CD5 /* MenuBarIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA927B0890D00544CD5 /* MenuBarIcons.swift */; }; C4068CAA27B0890D00544CD5 /* MenuBarIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA927B0890D00544CD5 /* MenuBarIcons.swift */; };
C4068CAB27B0890D00544CD5 /* 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 */; }; C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; };
C4080FF727BD8C6400BF2C6B /* Notice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* Notice.swift */; }; C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; };
C4080FFA27BD956700BF2C6B /* NoticeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* NoticeVC.swift */; }; C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; };
C4080FFB27BD956700BF2C6B /* NoticeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* NoticeVC.swift */; }; C4080FFB27BD956700BF2C6B /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; };
C40B24F127A3106D0018C7D2 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E67279DE0540010F296 /* ServicesView.swift */; }; C40B24F127A3106D0018C7D2 /* ServicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E67279DE0540010F296 /* ServicesView.swift */; };
C40B24F227A310770018C7D2 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E72279DFCF40010F296 /* Events.swift */; }; C40B24F227A310770018C7D2 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EC1E72279DFCF40010F296 /* Events.swift */; };
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47331A1247093B7009A0597 /* StatusMenu.swift */; }; C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47331A1247093B7009A0597 /* StatusMenu.swift */; };
@ -219,8 +219,8 @@
C4068CA327B0780A00544CD5 /* CheckboxPreferenceView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CheckboxPreferenceView.xib; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetterAlert.swift; sourceTree = "<group>"; };
C4080FF927BD956700BF2C6B /* NoticeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeVC.swift; sourceTree = "<group>"; }; C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetterAlertVC.swift; sourceTree = "<group>"; };
C40C7F1D2772136000DDDCDC /* PhpEnv.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpEnv.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>"; }; 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>"; }; C40C7F2F27722E8D00DDDCDC /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
@ -394,8 +394,8 @@
C4080FF827BD955900BF2C6B /* Notice */ = { C4080FF827BD955900BF2C6B /* Notice */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C4080FF527BD8C6400BF2C6B /* Notice.swift */, C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */,
C4080FF927BD956700BF2C6B /* NoticeVC.swift */, C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */,
); );
path = Notice; path = Notice;
sourceTree = "<group>"; sourceTree = "<group>";
@ -845,7 +845,7 @@
5420395926135DC100FB00FA /* PrefsVC.swift in Sources */, 5420395926135DC100FB00FA /* PrefsVC.swift in Sources */,
C43603A0275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */, C43603A0275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */,
C4068CA727B07A1300544CD5 /* SelectPreferenceView.swift in Sources */, C4068CA727B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
C4080FF627BD8C6400BF2C6B /* Notice.swift in Sources */, C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
C49E171F27A5736E00787921 /* PMServicesView.swift in Sources */, C49E171F27A5736E00787921 /* PMServicesView.swift in Sources */,
C4EE55AD27708B9E001DF387 /* PMStatsView.swift in Sources */, C4EE55AD27708B9E001DF387 /* PMStatsView.swift in Sources */,
C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */, C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
@ -901,7 +901,7 @@
C48D0C9625CC80B100CC7490 /* HeaderView.swift in Sources */, C48D0C9625CC80B100CC7490 /* HeaderView.swift in Sources */,
C4CE3BBA27B31F670086CA49 /* MainMenu+Composer.swift in Sources */, C4CE3BBA27B31F670086CA49 /* MainMenu+Composer.swift in Sources */,
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */, C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
C4080FFA27BD956700BF2C6B /* NoticeVC.swift in Sources */, C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */, C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */,
C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */, C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */,
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */, C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */,
@ -930,7 +930,7 @@
C4F780C825D80B75000DBC97 /* DateExtension.swift in Sources */, C4F780C825D80B75000DBC97 /* DateExtension.swift in Sources */,
C493084B279F331F009C240B /* AddSiteVC.swift in Sources */, C493084B279F331F009C240B /* AddSiteVC.swift in Sources */,
C4D9ADC0277610E1007277F4 /* PhpSwitcher.swift in Sources */, C4D9ADC0277610E1007277F4 /* PhpSwitcher.swift in Sources */,
C4080FFB27BD956700BF2C6B /* NoticeVC.swift in Sources */, C4080FFB27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */, C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */,
C4F780B125D80B4D000DBC97 /* PhpExtension.swift in Sources */, C4F780B125D80B4D000DBC97 /* PhpExtension.swift in Sources */,
C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */, C4068CA827B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
@ -966,7 +966,7 @@
C4CE3BBC27B324250086CA49 /* MainMenu+Composer.swift in Sources */, C4CE3BBC27B324250086CA49 /* MainMenu+Composer.swift in Sources */,
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */, C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */,
C417DC75277614690015E6EE /* Helpers.swift in Sources */, C417DC75277614690015E6EE /* Helpers.swift in Sources */,
C4080FF727BD8C6400BF2C6B /* Notice.swift in Sources */, C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */, C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */,
C4B97B79275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */, C4B97B79275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */,
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */, C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */,

View File

@ -88,7 +88,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
startup procedure. startup procedure.
*/ */
func applicationDidFinishLaunching(_ aNotification: Notification) { func applicationDidFinishLaunching(_ aNotification: Notification) {
/* /*
let notice = Notice.make() let notice = Notice.make()
.withInformation( .withInformation(

View File

@ -488,16 +488,16 @@
</objects> </objects>
<point key="canvasLocation" x="-575" y="1624"/> <point key="canvasLocation" x="-575" y="1624"/>
</scene> </scene>
<!--NoticeVC--> <!--Better AlertVC-->
<scene sceneID="y9E-bB-wIG"> <scene sceneID="y9E-bB-wIG">
<objects> <objects>
<viewController storyboardIdentifier="noticeVC" id="hkw-9V-NxP" customClass="NoticeVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController"> <viewController storyboardIdentifier="noticeVC" id="hkw-9V-NxP" customClass="BetterAlertVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="UPH-hV-Naz"> <view key="view" misplaced="YES" id="UPH-hV-Naz">
<rect key="frame" x="0.0" y="0.0" width="524" height="205"/> <rect key="frame" x="0.0" y="0.0" width="520" height="207"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<visualEffectView blendingMode="behindWindow" material="appearanceBased" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="JVG-5w-fPd"> <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"/> <rect key="frame" x="0.0" y="0.0" width="520" height="207"/>
</visualEffectView> </visualEffectView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TCp-nS-HN2"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TCp-nS-HN2">
<rect key="frame" x="13" y="13" width="99" height="32"/> <rect key="frame" x="13" y="13" width="99" height="32"/>
@ -516,7 +516,7 @@ Gw
</connections> </connections>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8zu-cF-KCX"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8zu-cF-KCX">
<rect key="frame" x="417" y="13" width="94" height="32"/> <rect key="frame" x="413" y="13" width="94" height="32"/>
<constraints> <constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="4Uf-fh-jWJ"/> <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="4Uf-fh-jWJ"/>
</constraints> </constraints>
@ -532,7 +532,7 @@ DQ
</connections> </connections>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="U1c-qS-cIm"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="U1c-qS-cIm">
<rect key="frame" x="102" y="151" width="404" height="19"/> <rect key="frame" x="98" y="153" width="404" height="19"/>
<constraints> <constraints>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="400" id="WgB-hj-d4P"/> <constraint firstAttribute="width" relation="lessThanOrEqual" constant="400" id="WgB-hj-d4P"/>
</constraints> </constraints>
@ -543,7 +543,7 @@ DQ
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yI6-qf-htf"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yI6-qf-htf">
<rect key="frame" x="102" y="127" width="404" height="16"/> <rect key="frame" x="98" y="127" width="404" height="16"/>
<textFieldCell key="cell" selectable="YES" title="This is a slightly more expanded explanation." id="rY3-Nd-Iit"> <textFieldCell key="cell" selectable="YES" title="This is a slightly more expanded explanation." id="rY3-Nd-Iit">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -551,7 +551,7 @@ DQ
</textFieldCell> </textFieldCell>
</textField> </textField>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0rX-Ss-3Xd"> <button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0rX-Ss-3Xd">
<rect key="frame" x="12" y="137" width="48" height="48"/> <rect key="frame" x="12" y="139" width="48" height="48"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <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"> <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"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -559,7 +559,7 @@ DQ
</buttonCell> </buttonCell>
</button> </button>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="QkM-5D-ZEQ"> <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="QkM-5D-ZEQ">
<rect key="frame" x="20" y="106" width="64" height="64"/> <rect key="frame" x="20" y="111" width="64" height="64"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="64" id="VhJ-fI-IKC"/> <constraint firstAttribute="height" constant="64" id="VhJ-fI-IKC"/>
<constraint firstAttribute="width" constant="64" id="a2d-Gn-Oor"/> <constraint firstAttribute="width" constant="64" id="a2d-Gn-Oor"/>
@ -567,12 +567,12 @@ DQ
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="7eT-Hw-EL9"/> <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="7eT-Hw-EL9"/>
</imageView> </imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hml-dl-Cah"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hml-dl-Cah">
<rect key="frame" x="102" y="70" width="404" height="42"/> <rect key="frame" x="98" y="70" width="404" height="42"/>
<textFieldCell key="cell" selectable="YES" id="7iW-Lc-DqO"> <textFieldCell key="cell" selectable="YES" id="7iW-Lc-DqO">
<font key="font" metaFont="smallSystem"/> <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> <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"/> <color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="n5T-nn-k3j"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="n5T-nn-k3j">
@ -592,7 +592,7 @@ DQ
<constraints> <constraints>
<constraint firstItem="hml-dl-Cah" firstAttribute="leading" secondItem="yI6-qf-htf" secondAttribute="leading" id="1Lh-ve-rwK"/> <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 firstAttribute="trailing" secondItem="8zu-cF-KCX" secondAttribute="trailing" constant="20" symbolic="YES" id="1Wo-BO-MIr"/>
<constraint firstItem="U1c-qS-cIm" firstAttribute="leading" secondItem="QkM-5D-ZEQ" secondAttribute="trailing" constant="20" id="2xX-Ma-iQZ"/> <constraint firstItem="U1c-qS-cIm" firstAttribute="leading" secondItem="QkM-5D-ZEQ" secondAttribute="trailing" constant="16" id="2xX-Ma-iQZ"/>
<constraint firstAttribute="trailing" secondItem="U1c-qS-cIm" secondAttribute="trailing" constant="20" symbolic="YES" id="39u-Uk-TDI"/> <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 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="n5T-nn-k3j" firstAttribute="top" secondItem="TCp-nS-HN2" secondAttribute="top" id="BlS-Yb-ME8"/>
@ -605,13 +605,13 @@ DQ
<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="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="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="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="QkM-5D-ZEQ" firstAttribute="top" secondItem="U1c-qS-cIm" secondAttribute="top" constant="-3" id="WAj-rw-srg"/>
<constraint firstItem="yI6-qf-htf" firstAttribute="leading" secondItem="U1c-qS-cIm" secondAttribute="leading" id="bng-pH-jSG"/> <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 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 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 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 firstItem="QkM-5D-ZEQ" firstAttribute="leading" secondItem="UPH-hV-Naz" secondAttribute="leading" constant="20" symbolic="YES" id="jG8-dt-l4x"/>
<constraint firstItem="yI6-qf-htf" firstAttribute="top" secondItem="U1c-qS-cIm" secondAttribute="bottom" constant="8" symbolic="YES" id="kqR-yg-zdG"/> <constraint firstItem="yI6-qf-htf" firstAttribute="top" secondItem="U1c-qS-cIm" secondAttribute="bottom" constant="10" id="kqR-yg-zdG"/>
<constraint firstAttribute="bottom" secondItem="TCp-nS-HN2" secondAttribute="bottom" constant="20" symbolic="YES" id="sm1-Qr-6iV"/> <constraint firstAttribute="bottom" secondItem="TCp-nS-HN2" secondAttribute="bottom" constant="20" symbolic="YES" id="sm1-Qr-6iV"/>
</constraints> </constraints>
</view> </view>

View File

@ -49,13 +49,15 @@ class Startup {
private func showAlert(for check: EnvironmentCheck) { private func showAlert(for check: EnvironmentCheck) {
DispatchQueue.main.async { DispatchQueue.main.async {
if check.requiresAppRestart { if check.requiresAppRestart {
Alert.notify( _ = BetterAlert.make()
message: check.titleText, .withInformation(
info: check.descriptionText, title: check.titleText,
button: check.buttonText, subtitle: check.subtitleText,
style: .critical description: check.descriptionText
) )
.withPrimary(text: check.buttonText, action: { _ in
exit(1) exit(1)
}).present()
} }
Alert.notify( Alert.notify(
@ -84,6 +86,7 @@ class Startup {
command: { return !FileManager.default.fileExists(atPath: Paths.brew) }, command: { return !FileManager.default.fileExists(atPath: Paths.brew) },
name: "`\(Paths.brew)` exists", name: "`\(Paths.brew)` exists",
titleText: "alert.homebrew_missing.title".localized, titleText: "alert.homebrew_missing.title".localized,
subtitleText: "alert.homebrew_missing.subtitle".localized,
descriptionText: "alert.homebrew_missing.info".localized( descriptionText: "alert.homebrew_missing.info".localized(
App.architecture App.architecture
.replacingOccurrences(of: "x86_64", with: "Intel") .replacingOccurrences(of: "x86_64", with: "Intel")
@ -161,6 +164,7 @@ class Startup {
let command: () async -> Bool let command: () async -> Bool
let name: String let name: String
let titleText: String let titleText: String
let subtitleText: String
let descriptionText: String let descriptionText: String
let buttonText: String let buttonText: String
let requiresAppRestart: Bool let requiresAppRestart: Bool
@ -169,6 +173,7 @@ class Startup {
command: @escaping () async -> Bool, command: @escaping () async -> Bool,
name: String, name: String,
titleText: String, titleText: String,
subtitleText: String = "",
descriptionText: String, descriptionText: String,
buttonText: String = "OK", buttonText: String = "OK",
requiresAppRestart: Bool = false requiresAppRestart: Bool = false
@ -176,6 +181,7 @@ class Startup {
self.command = command self.command = command
self.name = name self.name = name
self.titleText = titleText self.titleText = titleText
self.subtitleText = subtitleText
self.descriptionText = descriptionText self.descriptionText = descriptionText
self.buttonText = buttonText self.buttonText = buttonText
self.requiresAppRestart = requiresAppRestart self.requiresAppRestart = requiresAppRestart

View File

@ -9,18 +9,18 @@
import Foundation import Foundation
import Cocoa import Cocoa
class Notice { class BetterAlert {
var windowController: NSWindowController! var windowController: NSWindowController!
var noticeVC: NoticeVC { var noticeVC: BetterAlertVC {
return self.windowController.contentViewController as! NoticeVC return self.windowController.contentViewController as! BetterAlertVC
} }
public static func make() -> Notice { public static func make() -> BetterAlert {
let storyboard = NSStoryboard(name: "Main" , bundle : nil) let storyboard = NSStoryboard(name: "Main" , bundle : nil)
let notice = Notice() let notice = BetterAlert()
notice.windowController = storyboard.instantiateController( notice.windowController = storyboard.instantiateController(
withIdentifier: "noticeWindow" withIdentifier: "noticeWindow"
) as? NSWindowController ) as? NSWindowController
@ -29,7 +29,7 @@ class Notice {
public func withPrimary( public func withPrimary(
text: String, text: String,
action: @escaping (NoticeVC) -> Void = { action: @escaping (BetterAlertVC) -> Void = {
vc in vc.close(with: .alertFirstButtonReturn) vc in vc.close(with: .alertFirstButtonReturn)
} }
) -> Self { ) -> Self {
@ -40,7 +40,7 @@ class Notice {
public func withSecondary( public func withSecondary(
text: String, text: String,
action: ((NoticeVC) -> Void)? = nil action: ((BetterAlertVC) -> Void)? = nil
) -> Self { ) -> Self {
self.noticeVC.buttonSecondary.title = text self.noticeVC.buttonSecondary.title = text
self.noticeVC.actionSecondary = action self.noticeVC.actionSecondary = action
@ -49,7 +49,7 @@ class Notice {
public func withTertiary( public func withTertiary(
text: String, text: String,
action: ((NoticeVC) -> Void)? = nil action: ((BetterAlertVC) -> Void)? = nil
) -> Self { ) -> Self {
self.noticeVC.buttonTertiary.title = text self.noticeVC.buttonTertiary.title = text
self.noticeVC.actionTertiary = action self.noticeVC.actionTertiary = action

View File

@ -9,7 +9,7 @@
import Foundation import Foundation
import Cocoa import Cocoa
class NoticeVC: NSViewController { class BetterAlertVC: NSViewController {
@IBOutlet weak var labelTitle: NSTextField! @IBOutlet weak var labelTitle: NSTextField!
@IBOutlet weak var labelSubtitle: NSTextField! @IBOutlet weak var labelSubtitle: NSTextField!
@ -19,9 +19,9 @@ class NoticeVC: NSViewController {
@IBOutlet weak var buttonSecondary: NSButton! @IBOutlet weak var buttonSecondary: NSButton!
@IBOutlet weak var buttonTertiary: NSButton! @IBOutlet weak var buttonTertiary: NSButton!
var actionPrimary: (NoticeVC) -> Void = { _ in } var actionPrimary: (BetterAlertVC) -> Void = { _ in }
var actionSecondary: ((NoticeVC) -> Void)? var actionSecondary: ((BetterAlertVC) -> Void)?
var actionTertiary: ((NoticeVC) -> Void)? var actionTertiary: ((BetterAlertVC) -> Void)?
@IBOutlet weak var imageView: NSImageView! @IBOutlet weak var imageView: NSImageView!

View File

@ -254,8 +254,10 @@ You can do this by running `composer global update` in your terminal. After that
/// 0. Architecture mismatch /// 0. Architecture mismatch
"alert.homebrew_missing.title" = "PHP Monitor cannot start"; "alert.homebrew_missing.title" = "PHP Monitor cannot start!";
"alert.homebrew_missing.info" = "You are running PHP Monitor with the following architecture: %@.\n\nA working Homebrew binary is expected in `%@`, but was not found, so PHP Monitor cannot work.\n\nIf you have not installed Homebrew yet, please do so. (If you are on Apple Silicon, make sure your Homebrew and PHP Monitor use the same architecture, by enabling or disabling Rosetta where needed.)\n\nPHP Monitor will now quit, please restart the app after fixing this issue."; "alert.homebrew_missing.subtitle" = "A working Homebrew binary could not be found in the usual location. Please restart the app after fixing this issue.";
"alert.homebrew_missing.info" = "You are running PHP Monitor with the following architecture: %@. As a result, a working Homebrew binary is expected in `%@`, but was not found. This is why PHP Monitor cannot work.\n\nIf you have not installed Homebrew yet, please do so. If you are on Apple Silicon, make sure your Homebrew and PHP Monitor use the same architecture, by enabling or disabling Rosetta where needed.";
"alert.homebrew_missing.quit" = "Quit"; "alert.homebrew_missing.quit" = "Quit";
/// 1. PHP binary not found /// 1. PHP binary not found