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:
@ -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 */,
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
81
phpmon/Domain/Notice/Notice.swift
Normal file
81
phpmon/Domain/Notice/Notice.swift
Normal 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!)
|
||||
}
|
||||
}
|
63
phpmon/Domain/Notice/NoticeVC.swift
Normal file
63
phpmon/Domain/Notice/NoticeVC.swift
Normal 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)
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user