From 0ca2f22cef2b14fc49723cf5fb643c464bb801e3 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Wed, 17 Jun 2020 13:26:27 -0500 Subject: [PATCH 01/37] Calendar alerts in compact mode! --- .../CalendarHandler.swift | 34 +++++++++++++++++++ .../Data Layer/TimezoneDataOperations.swift | 34 +++++++++++++++++++ .../Calendar/CalendarViewController.swift | 3 -- 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/Clocker/Events and Reminders/CalendarHandler.swift b/Clocker/Events and Reminders/CalendarHandler.swift index 904b726..85fa7a4 100644 --- a/Clocker/Events and Reminders/CalendarHandler.swift +++ b/Clocker/Events and Reminders/CalendarHandler.swift @@ -53,6 +53,40 @@ extension EventCenter { return sourcesAndCalendars } + func separateFormat(event: EKEvent) -> (String, String)? { + guard let truncateLength = DataStore.shared().retrieve(key: CLTruncateTextLength) as? NSNumber, let eventTitle = event.title else { + return nil + } + + let seconds = event.startDate.timeIntervalSinceNow + var formattedTitle: String = CLEmptyString + + if eventTitle.count > truncateLength.intValue { + let truncateIndex = eventTitle.index(eventTitle.startIndex, offsetBy: truncateLength.intValue) + let truncatedTitle = String(eventTitle[.. 2 { + let suffix = String(format: " in %0.f mins", minutes) + menubarText.append(suffix) + } else if minutes == 1 { + let suffix = String(format: " in %0.f min", minutes) + menubarText.append(suffix) + } else { + menubarText.append(" starts now.") + } + + return (formattedTitle, menubarText) + } + func format(event: EKEvent) -> String { guard let truncateLength = DataStore.shared().retrieve(key: CLTruncateTextLength) as? NSNumber, let eventTitle = event.title else { return CLEmptyString diff --git a/Clocker/Panel/Data Layer/TimezoneDataOperations.swift b/Clocker/Panel/Data Layer/TimezoneDataOperations.swift index ee70ba7..cae17bc 100644 --- a/Clocker/Panel/Data Layer/TimezoneDataOperations.swift +++ b/Clocker/Panel/Data Layer/TimezoneDataOperations.swift @@ -33,7 +33,37 @@ extension TimezoneDataOperations { return dateFormatter.string(from: newDate) } + private func checkForUpcomingEvents() -> (String, String)? { + if DataStore.shared().shouldDisplay(.showMeetingInMenubar) { + let filteredDates = EventCenter.sharedCenter().eventsForDate + let autoupdatingCal = EventCenter.sharedCenter().autoupdatingCalendar + guard let events = filteredDates[autoupdatingCal.startOfDay(for: Date())] else { + return nil + } + + for event in events { + if event.event.startDate.timeIntervalSinceNow > 0, !event.isAllDay { + let timeForEventToStart = event.event.startDate.timeIntervalSinceNow / 60 + + if timeForEventToStart > 30 { + print("Our next event: \(event.event.title ?? "Error") starts in \(timeForEventToStart) mins") + + continue + } + + return EventCenter.sharedCenter().separateFormat(event: event.event) + } + } + } + + return nil + } + func compactMenuTitle() -> String { + if let upcomingEvent = checkForUpcomingEvents() { + return upcomingEvent.0 + } + var subtitle = CLEmptyString let shouldDayBeShown = DataStore.shared().shouldShowDayInMenubar() @@ -54,6 +84,10 @@ extension TimezoneDataOperations { } func compactMenuSubtitle() -> String { + if let upcomingEvent = checkForUpcomingEvents() { + return upcomingEvent.1 + } + var subtitle = CLEmptyString let shouldDayBeShown = DataStore.shared().shouldShowDayInMenubar() diff --git a/Clocker/Preferences/Calendar/CalendarViewController.swift b/Clocker/Preferences/Calendar/CalendarViewController.swift index 197c93d..1b6196c 100644 --- a/Clocker/Preferences/Calendar/CalendarViewController.swift +++ b/Clocker/Preferences/Calendar/CalendarViewController.swift @@ -87,9 +87,6 @@ class CalendarViewController: ParentViewController { } else { showSegmentedControl.selectedSegment = 1 } - - // If the menubar mode is compact, we can't show meetings in the menubar. So disable toggling that option. - showNextMeetingInMenubarControl.isEnabled = !DataStore.shared().shouldDisplay(.menubarCompactMode) } private func verifyCalendarAccess() { From d9cbeac3b6765623f7670b7dc54af39071edfb9d Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sun, 21 Jun 2020 00:02:24 -0500 Subject: [PATCH 02/37] Updating floating icon! --- .../Pin/Float-White.imageset/Contents.json | 9 ++++--- .../Pin/Float-White.imageset/PinIconWhite.png | Bin 3162 -> 0 bytes .../Pin/Float-White.imageset/Pin_1x.png | Bin 0 -> 852 bytes .../info panel detach button_Normal@2x.png | Bin 0 -> 1098 bytes .../Pin/Float.imageset/Contents.json | 9 ++++--- .../Pin/Float.imageset/PinIcon.png | Bin 4403 -> 0 bytes .../Pin/Float.imageset/Pin_Light_1x.png | Bin 0 -> 5508 bytes .../Pin/Float.imageset/light-mode.png | Bin 0 -> 5996 bytes .../Pin/Pin.imageset/Contents.json | 25 +++++++++--------- .../Pin/Pin.imageset/PinIcon.png | Bin 4403 -> 0 bytes .../Pin/Pin.imageset/PinIconWhite.png | Bin 3162 -> 0 bytes .../Pin/Pin.imageset/Pin_1x.png | Bin 0 -> 852 bytes .../info panel detach button_Normal@2x.png | Bin 0 -> 1098 bytes .../Pin/Pin.imageset/light-mode.png | Bin 0 -> 5704 bytes 14 files changed, 23 insertions(+), 20 deletions(-) delete mode 100644 Clocker/Media.xcassets/Pin/Float-White.imageset/PinIconWhite.png create mode 100644 Clocker/Media.xcassets/Pin/Float-White.imageset/Pin_1x.png create mode 100644 Clocker/Media.xcassets/Pin/Float-White.imageset/info panel detach button_Normal@2x.png delete mode 100644 Clocker/Media.xcassets/Pin/Float.imageset/PinIcon.png create mode 100644 Clocker/Media.xcassets/Pin/Float.imageset/Pin_Light_1x.png create mode 100644 Clocker/Media.xcassets/Pin/Float.imageset/light-mode.png delete mode 100644 Clocker/Media.xcassets/Pin/Pin.imageset/PinIcon.png delete mode 100644 Clocker/Media.xcassets/Pin/Pin.imageset/PinIconWhite.png create mode 100644 Clocker/Media.xcassets/Pin/Pin.imageset/Pin_1x.png create mode 100644 Clocker/Media.xcassets/Pin/Pin.imageset/info panel detach button_Normal@2x.png create mode 100644 Clocker/Media.xcassets/Pin/Pin.imageset/light-mode.png diff --git a/Clocker/Media.xcassets/Pin/Float-White.imageset/Contents.json b/Clocker/Media.xcassets/Pin/Float-White.imageset/Contents.json index fff97e0..30c26a1 100644 --- a/Clocker/Media.xcassets/Pin/Float-White.imageset/Contents.json +++ b/Clocker/Media.xcassets/Pin/Float-White.imageset/Contents.json @@ -1,11 +1,12 @@ { "images" : [ { + "filename" : "Pin_1x.png", "idiom" : "universal", - "filename" : "PinIconWhite.png", "scale" : "1x" }, { + "filename" : "info panel detach button_Normal@2x.png", "idiom" : "universal", "scale" : "2x" }, @@ -15,7 +16,7 @@ } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/Clocker/Media.xcassets/Pin/Float-White.imageset/PinIconWhite.png b/Clocker/Media.xcassets/Pin/Float-White.imageset/PinIconWhite.png deleted file mode 100644 index 2e30f01ced81ce96cbe7a1cc5a4cba1367b0e374..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3162 zcmeAS@N?(olHy`uVBq!ia0y~yVA=!19Bd$wT{+G`iY>|8-33Sk!B6Mi^+1ZVz$3Dl zfq`2Xgc%uT&5-~KvX^-Jy0SlH=V9dJba7H%>Trz&-WrHb#)y!xXf0yC2XoGM>wHz^_qYq2P>TM+F%e6e<`Q z96m5HG(2EsU^vLlz|bVlz`&x9pgH0g7zBVZfvga#2ADz^jjRD~GO`Wm3bAScIR&H; zMx#3gWHN@^kxj;?Vbqhb7=+RA2tp2LSjbRfy!94n0vq?_6Hct3Qy1_U~!+2nYRgOZ^Hs+ zY`zlZt_8YJpbT6}qZth{VS|ZzIM87Z4;ZnO?+sn7c2Gkl`cJB1E6B@I3i*M?Ht}Oi zi6J^~7$MPc;D?VDBP@`SobiFRy9(sK25jzIkmLw58&tPFOa8=(&4K(8XP5={G$@F) zU=Q6BKv_@?)$ns>3lmbf!z$GWyxkQb?<-)FT#&@b5Ar_H;%mu9T-fZl7JCm0`vevw zKfx+IhogsNK|uyIA|VKy?u1OSw;eNW#F77d0C6)A0>*%BzNjA6v+Dt-{IcH_y^CZT6k}u?4>0au&v539GH-25^KoD+l)>uv0$}4`zd6u^ z$w65zv*FuDZfGtx=t>Wc?e1c@(2;#|LG2r;R|9^rz7dk!(5WH^c9Ey6pUXO@geCwd CT8|+B diff --git a/Clocker/Media.xcassets/Pin/Float-White.imageset/Pin_1x.png b/Clocker/Media.xcassets/Pin/Float-White.imageset/Pin_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..661ec7a3c901cec0faace1121c0f408dd363fdb9 GIT binary patch literal 852 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 mIq)|Z2Gw;QUSTeEakys3iv1mDl~K(A diff --git a/Clocker/Media.xcassets/Pin/Float.imageset/Pin_Light_1x.png b/Clocker/Media.xcassets/Pin/Float.imageset/Pin_Light_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..9fc4c657d8bf4b8e58df4f3043cdd7d115b92fc4 GIT binary patch literal 5508 zcmeHKdsq`!77u8tBI2V$sfxyE3tE#*UO=VJ@A-pQ_?mMjArnGJTej&(T-JLqcbr&s{k3CBlH;BmcepuaWE?u-b?FN2kW1gG zFTVXx_r$^5I=-88Q&H>u4q?y&jAP%XJu_^YVQoXQgflQB7ar; z`nm6%zb#+({_CNv2Yd2UQ*!rTe^)O0=KPY{6Q1nmnK@nxby?V!X|l2JX`5S>ZO2xu z+rLL!lDF`pi?Xa{n#^x%W4+Vvn?sHkFW+|f>(3KEKQz<5!P{qbNm>4llOxjZe%JO( zGo(qJRPGU3wrdsPg28z9FlU6EC_A9a0xrzG3Rvy`v@-xQBRb-8@rhSd6S6JTPhMoEGKzCzD8Dxyf=aZL_2>+Tie481 z+-zO{?t@P0@W$ldDh3gX~V@2S$^A_7%t24 zksTlU92`L$sbhZBH`>3~hd{PJV4r-Y>_O2FmXGe-*^;*Te3olm^R4jf}^q|yBv(||sj)#n| zU(l2)ndTlla^Xq&mg!?W&dPSnm%DC{O*wb$a^r~YQgLBhn{SQh_@4NG!ZiUM*IK6y z$(~4$Du~KuMYr`8hUUeOD0pzQ>!(Xy-t^{Kk$asvAx%2o##MPGow;6%BtG{?g}60w z_vR-^XO&;Sdtl|7D$Crh=XzVV?Fc`e;C5qm9q$yRYcscfDf^+dcFuUUB;m~!7@;sO_6N-`$2mLR+>nHwa{4HPcvd;U* z`dTgfVizwuHQTj*X~F9!?s>Un9}GEkE#Sh5f|y{Zo-;=`{&c%I?P#;l)pHe|Lg&nV zOY=G^DmtBt-#L18{iMy+Z{NdR?*-miJoCbaSMKYVcFn8W_phL+iA(tAjkQkh?n~D> zV^yDJSmM$QeOvL{-GdJ8B1PG=nLr)@BrrtD}qOfy>VJ4KojU;Z+ z(ic*be}(xeyev@+R% zwcga9MUYRn6*00oEQqbsJz-%YCFzg-J=4OZ0G9zf8Z#Np1d2)0F+Dli(Wy~uHaYq< zn=ndbi(9Kwvq4Zc&yF_XQki_fhDxIb*BNaV6xtD~LI-e0GoiI%R45zMVmc6r2{3b> zz*CpjfW;I0p)^kgLgMN_fK!^M;2^qZlRrwYEp*#4z+nc|OvNY-6EUdm!72lat6pjsK+eJe50?)?Dk#98 zDZtbilP^^9m`aY4%k<;%QN&-(Q$akw1H~Ky2aSVh9iyVCRDen;G&U9aU;ZA)LZb`wYs)V=@6Y^tnAqAHQ3j{Ea z%Y+0l1TpMKP7h>L*&;y`;>Ewm-`!ZcG)Ad3bcp>o1>Ux>37s|j3fnQeF|1DjvkKgYxJ^1ox z0dMcOdOmdqZ~iXI+2LU{Us@1tE}WJg3M4~~5eX(5ZP;tnpA&6UsTUBwN=jvtS1-GG z4ECqL(!Tl)AWD~p%~1HB+1a>fxHHEs=OTM$Wm$4z+6PN>i#)EL&z^KXy8|CtvEO<6 zhr_;H&q$ctTdZlQ-{(4itN=~C*|p^B?Osq@b-*WEveIkX6t`k>$KL4iNv+)BF(LD< zZ(NHf-0j`HMj#?Oc?BM=%M%Z`%wt6)-x_+@X?OTr9q*NGz6BznNhMKXm7&Sm{{`+A B4Hp0a literal 0 HcmV?d00001 diff --git a/Clocker/Media.xcassets/Pin/Float.imageset/light-mode.png b/Clocker/Media.xcassets/Pin/Float.imageset/light-mode.png new file mode 100644 index 0000000000000000000000000000000000000000..edf76f8841e84056eaa6741934a60a3076223104 GIT binary patch literal 5996 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 ICt!B=??j)iApigX literal 0 HcmV?d00001 diff --git a/Clocker/Media.xcassets/Pin/Pin.imageset/Contents.json b/Clocker/Media.xcassets/Pin/Pin.imageset/Contents.json index 4cb67ab..f6f839c 100644 --- a/Clocker/Media.xcassets/Pin/Pin.imageset/Contents.json +++ b/Clocker/Media.xcassets/Pin/Pin.imageset/Contents.json @@ -5,29 +5,30 @@ "scale" : "1x" }, { - "idiom" : "universal", - "scale" : "1x", "appearances" : [ { "appearance" : "luminosity", "value" : "dark" } - ] + ], + "filename" : "Pin_1x.png", + "idiom" : "universal", + "scale" : "1x" }, { + "filename" : "light-mode.png", "idiom" : "universal", - "filename" : "PinIcon.png", "scale" : "2x" }, { - "idiom" : "universal", - "filename" : "PinIconWhite.png", "appearances" : [ { "appearance" : "luminosity", "value" : "dark" } ], + "filename" : "info panel detach button_Normal@2x.png", + "idiom" : "universal", "scale" : "2x" }, { @@ -35,18 +36,18 @@ "scale" : "3x" }, { - "idiom" : "universal", - "scale" : "3x", "appearances" : [ { "appearance" : "luminosity", "value" : "dark" } - ] + ], + "idiom" : "universal", + "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/Clocker/Media.xcassets/Pin/Pin.imageset/PinIcon.png b/Clocker/Media.xcassets/Pin/Pin.imageset/PinIcon.png deleted file mode 100644 index 7e66bfecaef9218b7da1a7bb954f0671b6a9b525..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4403 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 mIq)|Z2Gw;QUSTeEakys3iv1mDl~K(A diff --git a/Clocker/Media.xcassets/Pin/Pin.imageset/PinIconWhite.png b/Clocker/Media.xcassets/Pin/Pin.imageset/PinIconWhite.png deleted file mode 100644 index 2e30f01ced81ce96cbe7a1cc5a4cba1367b0e374..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3162 zcmeAS@N?(olHy`uVBq!ia0y~yVA=!19Bd$wT{+G`iY>|8-33Sk!B6Mi^+1ZVz$3Dl zfq`2Xgc%uT&5-~KvX^-Jy0SlH=V9dJba7H%>Trz&-WrHb#)y!xXf0yC2XoGM>wHz^_qYq2P>TM+F%e6e<`Q z96m5HG(2EsU^vLlz|bVlz`&x9pgH0g7zBVZfvga#2ADz^jjRD~GO`Wm3bAScIR&H; zMx#3gWHN@^kxj;?Vbqhb7=+RA2tp2LSjbRfy!94n0vq?_6Hct3Qy1_U~!+2nYRgOZ^Hs+ zY`zlZt_8YJpbT6}qZth{VS|ZzIM87Z4;ZnO?+sn7c2Gkl`cJB1E6B@I3i*M?Ht}Oi zi6J^~7$MPc;D?VDBP@`SobiFRy9(sK25jzIkmLw58&tPFOa8=(&4K(8XP5={G$@F) zU=Q6BKv_@?)$ns>3lmbf!z$GWyxkQb?<-)FT#&@b5Ar_H;%mu9T-fZl7JCm0`vevw zKfx+IhogsNK|uyIA|VKy?u1OSw;eNW#F77d0C6)A0>*%BzNjA6v+Dt-{IcH_y^CZT6k}u?4>0au&v539GH-25^KoD+l)>uv0$}4`zd6u^ z$w65zv*FuDZfGtx=t>Wc?e1c@(2;#|LG2r;R|9^rz7dk!(5WH^c9Ey6pUXO@geCwd CT8|+B diff --git a/Clocker/Media.xcassets/Pin/Pin.imageset/Pin_1x.png b/Clocker/Media.xcassets/Pin/Pin.imageset/Pin_1x.png new file mode 100644 index 0000000000000000000000000000000000000000..661ec7a3c901cec0faace1121c0f408dd363fdb9 GIT binary patch literal 852 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 literal 0 HcmV?d00001 From 331b667797013e79166fb60fc623b1ed36801a2e Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sun, 21 Jun 2020 00:51:25 -0500 Subject: [PATCH 03/37] Imp fixes! --- .../CalendarHandler.swift | 28 +++++++++++++++++++ Clocker/Menu Bar/StatusContainerView.swift | 23 +++++++++++---- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Clocker/Events and Reminders/CalendarHandler.swift b/Clocker/Events and Reminders/CalendarHandler.swift index 85fa7a4..ab768f7 100644 --- a/Clocker/Events and Reminders/CalendarHandler.swift +++ b/Clocker/Events and Reminders/CalendarHandler.swift @@ -53,6 +53,34 @@ extension EventCenter { return sourcesAndCalendars } + func isThereAnUpcomingCalendarEvent() -> Bool { + if DataStore.shared().shouldDisplay(.showMeetingInMenubar) { + let filteredDates = EventCenter.sharedCenter().eventsForDate + let autoupdatingCal = EventCenter.sharedCenter().autoupdatingCalendar + guard let events = filteredDates[autoupdatingCal.startOfDay(for: Date())] else { + return false + } + + for event in events { + if event.event.startDate.timeIntervalSinceNow > 0, !event.isAllDay { + let timeForEventToStart = event.event.startDate.timeIntervalSinceNow / 60 + + if timeForEventToStart > 30 { + print("Our next event: \(event.event.title ?? "Error") starts in \(timeForEventToStart) mins") + continue + } + + return true + } + } + } + + return false + } + + /* Used for the compact menubar mode. + Returns a tuple with 0 as the header string and 1 as the subtitle string + */ func separateFormat(event: EKEvent) -> (String, String)? { guard let truncateLength = DataStore.shared().retrieve(key: CLTruncateTextLength) as? NSNumber, let eventTitle = event.title else { return nil diff --git a/Clocker/Menu Bar/StatusContainerView.swift b/Clocker/Menu Bar/StatusContainerView.swift index 63bbb27..f71925b 100644 --- a/Clocker/Menu Bar/StatusContainerView.swift +++ b/Clocker/Menu Bar/StatusContainerView.swift @@ -77,8 +77,9 @@ class StatusContainerView: NSView { if let timezoneObject = TimezoneData.customObject(from: timezone) { let precalculatedWidth = Double(compactWidth(for: timezoneObject)) let operationObject = TimezoneDataOperations(with: timezoneObject) - let calculatedSize = compactModeTimeFont.size(operationObject.compactMenuSubtitle(), precalculatedWidth, attributes: timeAttributes) - return result + calculatedSize.width + bufferWidth + let calculatedSubtitleSize = compactModeTimeFont.size(operationObject.compactMenuSubtitle(), precalculatedWidth, attributes: timeAttributes) + let calculatedTitleSize = compactModeTimeFont.size(operationObject.compactMenuTitle(), precalculatedWidth, attributes: timeAttributes) + return result + max(calculatedTitleSize.width, calculatedSubtitleSize.width) + bufferWidth } return result + CGFloat(bufferCalculatedWidth()) @@ -114,10 +115,11 @@ class StatusContainerView: NSView { private func bestWidth(for timezone: TimezoneData) -> Int { let operation = TimezoneDataOperations(with: timezone) + let bestSize = compactModeTimeFont.size(operation.compactMenuSubtitle(), + Double(compactWidth(for: timezone)), attributes: timeAttributes) + let bestTitleSize = compactModeTimeFont.size(operation.compactMenuTitle(), Double(compactWidth(for: timezone)), attributes: timeAttributes) - let bestSize = compactModeTimeFont.size(operation.compactMenuSubtitle(), Double(compactWidth(for: timezone)), attributes: timeAttributes) - - return Int(bestSize.width + bufferWidth) + return Int(max(bestSize.width, bestTitleSize.width) + bufferWidth) } func updateTime() { @@ -126,16 +128,25 @@ class StatusContainerView: NSView { } // See if frame's width needs any adjustment + adjustWidthIfNeccessary() + } + + private func adjustWidthIfNeccessary() { var newWidth: CGFloat = 0 subviews.forEach { - if let statusItem = $0 as? StatusItemView { + if let statusItem = $0 as? StatusItemView, statusItem.isHidden == false { // Determine what's the best width required to display the current string. let newBestWidth = CGFloat(bestWidth(for: statusItem.dataObject)) // Let's note if the current width is too small/correct newWidth += statusItem.frame.size.width != newBestWidth ? newBestWidth : statusItem.frame.size.width + statusItem.frame = CGRect(x: statusItem.frame.origin.x, + y: statusItem.frame.origin.y, + width: newBestWidth, + height: statusItem.frame.size.height) + statusItem.updateTimeInMenubar() } } From c41164b577f66892ecbedf8e5583da0eade895ad Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sun, 21 Jun 2020 01:10:45 -0500 Subject: [PATCH 04/37] Share icon updates! --- Clocker/Clocker/en.lproj/Panel.xib | 24 +++++++++--------- .../Sharing/Sharing.imageset/Contents.json | 9 ++++--- .../Sharing.imageset/noun_1020875_cc.png | Bin 4992 -> 0 bytes .../Sharing.imageset/share1x_light.png | Bin 0 -> 5582 bytes .../Sharing.imageset/share2x_light.png | Bin 0 -> 5846 bytes .../SharingDarkIcon.imageset/Contents.json | 9 ++++--- .../SharingDarkIcon.imageset/Sharing_Dark.png | Bin 3603 -> 0 bytes .../SharingDarkIcon.imageset/share1x.png | Bin 0 -> 1031 bytes .../SharingDarkIcon.imageset/share2x.png | Bin 0 -> 1244 bytes 9 files changed, 22 insertions(+), 20 deletions(-) delete mode 100644 Clocker/Media.xcassets/Sharing/Sharing.imageset/noun_1020875_cc.png create mode 100644 Clocker/Media.xcassets/Sharing/Sharing.imageset/share1x_light.png create mode 100644 Clocker/Media.xcassets/Sharing/Sharing.imageset/share2x_light.png delete mode 100644 Clocker/Media.xcassets/Sharing/SharingDarkIcon.imageset/Sharing_Dark.png create mode 100644 Clocker/Media.xcassets/Sharing/SharingDarkIcon.imageset/share1x.png create mode 100644 Clocker/Media.xcassets/Sharing/SharingDarkIcon.imageset/share2x.png diff --git a/Clocker/Clocker/en.lproj/Panel.xib b/Clocker/Clocker/en.lproj/Panel.xib index 8e150fc..120b6e8 100755 --- a/Clocker/Clocker/en.lproj/Panel.xib +++ b/Clocker/Clocker/en.lproj/Panel.xib @@ -1,8 +1,8 @@ - + - + @@ -465,12 +465,12 @@ - + - + - + @@ -1645,14 +1645,14 @@ DQ - + - + @@ -1690,14 +1690,14 @@ DQ - + - - + + - + - - - - - - - - - - - @@ -168,6 +158,36 @@ DQ + + + + + + + + + + + + + + + + + + + + @@ -175,22 +195,22 @@ DQ + + + - - + - - diff --git a/Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift b/Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift index 55fb716..6880ebb 100644 --- a/Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift +++ b/Clocker/Preferences/App Feedback/AppFeedbackWindowController.swift @@ -33,6 +33,7 @@ class AppFeedbackWindowController: NSWindowController { @IBOutlet var informativeText: NSTextField! @IBOutlet var progressIndicator: NSProgressIndicator! + @IBOutlet var quickCommentsLabel: UnderlinedButton! private var themeDidChangeNotification: NSObjectProtocol? private var serialNumber: String? { let platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")) @@ -72,6 +73,7 @@ class AppFeedbackWindowController: NSWindowController { nameField.setAccessibilityIdentifier("NameField") emailField.setAccessibilityIdentifier("EmailField") progressIndicator.setAccessibilityIdentifier("ProgressIndicator") + quickCommentsLabel.setAccessibility("QuickCommentLabel") setup() @@ -204,19 +206,54 @@ class AppFeedbackWindowController: NSWindowController { informativeText.stringValue = CLEmptyString } - @IBOutlet var headerLabel: NSTextField! @IBOutlet var contactBox: NSBox! @IBOutlet var accessoryInfo: NSTextField! private func setup() { - headerLabel.stringValue = "Tell us what you think!".localized() contactBox.title = "Contact Information (Optional)".localized() accessoryInfo.stringValue = "Contact fields are optional! Your contact information will let us contact you in case we need more information or can help!".localized() - [headerLabel, accessoryInfo].forEach { $0?.textColor = Themer.shared().mainTextColor() } + let range = NSRange(location: 9, length: 15) + quickCommentsLabel.title = "Tweet to @ClockerSupport if you have a quick comment!" + setUnderline(for: quickCommentsLabel, range: range) + + [accessoryInfo].forEach { $0?.textColor = Themer.shared().mainTextColor() } contactBox.borderColor = Themer.shared().mainTextColor() } + + private func setUnderline(for button: UnderlinedButton?, range: NSRange) { + guard let underlinedButton = button else { return } + + let mutableParaghStyle = NSMutableParagraphStyle() + mutableParaghStyle.alignment = .center + + let originalText = NSMutableAttributedString(string: underlinedButton.title) + originalText.addAttribute(NSAttributedString.Key.underlineStyle, + value: NSNumber(value: Int8(NSUnderlineStyle.single.rawValue)), + range: range) + originalText.addAttribute(NSAttributedString.Key.foregroundColor, + value: Themer.shared().mainTextColor(), + range: NSRange(location: 0, length: underlinedButton.attributedTitle.string.count)) + originalText.addAttribute(NSAttributedString.Key.font, + value: (button?.font)!, + range: NSRange(location: 0, length: underlinedButton.attributedTitle.string.count)) + originalText.addAttribute(NSAttributedString.Key.paragraphStyle, + value: mutableParaghStyle, + range: NSRange(location: 0, length: underlinedButton.attributedTitle.string.count)) + underlinedButton.attributedTitle = originalText + } + + @IBAction func navigateToSupportTwitter(_: Any) { + guard let twitterURL = URL(string: AboutUsConstants.TwitterLink), + let countryCode = Locale.autoupdatingCurrent.regionCode else { return } + + NSWorkspace.shared.open(twitterURL) + + // Log this + let custom: [String: Any] = ["Country": countryCode] + Logger.log(object: custom, for: "Opened Twitter") + } } extension AppFeedbackWindowController: NSWindowDelegate { From 029877a0b3f265c5dd6dc64e175052236324f4ba Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sun, 21 Jun 2020 03:01:14 -0500 Subject: [PATCH 10/37] Updating build! --- Clocker/Clocker.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Clocker/Clocker.xcodeproj/project.pbxproj b/Clocker/Clocker.xcodeproj/project.pbxproj index bd1c159..6d6e514 100755 --- a/Clocker/Clocker.xcodeproj/project.pbxproj +++ b/Clocker/Clocker.xcodeproj/project.pbxproj @@ -1454,7 +1454,7 @@ CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 77; + CURRENT_PROJECT_VERSION = 79; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( @@ -1939,7 +1939,7 @@ CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 77; + CURRENT_PROJECT_VERSION = 79; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; @@ -2002,7 +2002,7 @@ CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 77; + CURRENT_PROJECT_VERSION = 79; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = ( From b364388342883917ebce06f00e0a81f1a7a2ec1e Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 26 Jun 2020 21:19:12 -0500 Subject: [PATCH 11/37] Updates! --- .../Overall App/VersionUpdateHandler.swift | 257 ++++++++++++++++-- 1 file changed, 240 insertions(+), 17 deletions(-) diff --git a/Clocker/Overall App/VersionUpdateHandler.swift b/Clocker/Overall App/VersionUpdateHandler.swift index b3e982f..04d7cc5 100644 --- a/Clocker/Overall App/VersionUpdateHandler.swift +++ b/Clocker/Overall App/VersionUpdateHandler.swift @@ -15,6 +15,11 @@ class VersionUpdateHandler: NSObject { static let kMacRequestTimeout: Double = 60.0 static let kVersionCheckLastVersionKey = "VersionCheckLastVersionKey" static let kVersionIgnoreVersionKey = "VersionCheckIgnoreVersionKey" + static let kMacAppStoreIDKey = "VersionCheckAppStoreIDKey" + static let kVersionLastCheckedKey = "VersionLastCheckedKey" + static let kVersionLastRemindedKey = "VersionLastRemindedKey" + + static let sharedInstance = VersionUpdateHandler() private var appStoreCountry: String! private var applicationVersion: String! @@ -26,6 +31,10 @@ class VersionUpdateHandler: NSObject { private var checkPeriod: Float = 0.0 private var remindPeriod: Float = 1.0 private var verboseLogging: Bool = true + private var updateURL: URL! + private var checkingForNewVersion: Bool = false + private var remoteVersionsDict: [String: Any] = [:] + private var downloadError: Error? private var showOnFirstLaunch: Bool = false public var previewMode: Bool = false @@ -53,24 +62,98 @@ class VersionUpdateHandler: NSObject { super.init() } - private func shouldCheckForNewVersion() -> Bool { - return true + private func inThisVersionTitle() -> String { + return "New in this version" } - private func applicationLaunched() { - if checkAtLaunch { - checkIfNewVersion() - } else if verboseLogging { - print("iVersion will not check for updatess because checkAtLaunch option is disabled") + private func updateAvailableTitle() -> String { + return "New version available" + } + + private func versionLabelFormat() -> String { + return "Version %@" + } + + private func okayButtonLabel() -> String { + return "OK" + } + + private func ignoreButtonLabel() -> String { + return "Ignore" + } + + private func downloadButtonLabel() -> String { + return "Download" + } + + private func remindButtonLabel() -> String { + return "Remind Me Later" + } + + private func updatedURL() -> URL { + if updateURL.absoluteString.count > 0 { + return updateURL } + + guard let appStoreId = appStoreID() else { + print("No App Store ID was found for Clocker") + return URL(string: "")! + } + + return URL(string: "macappstore://itunes.apple.com/app/id\(appStoreId)")! + } + + private func appStoreID() -> Int? { + return UserDefaults.standard.integer(forKey: VersionUpdateHandler.kMacAppStoreIDKey) + } + + func setAppStoreID(_ appStoreID: Int) { + UserDefaults.standard.set(appStoreID, forKey: VersionUpdateHandler.kMacAppStoreIDKey) + } + + private func setLastChecked(_ date: Date) { + UserDefaults.standard.set(date, forKey: VersionUpdateHandler.kVersionLastCheckedKey) + } + + private func lastChecked() -> Date? { + return UserDefaults.standard.object(forKey: VersionUpdateHandler.kVersionLastCheckedKey) as? Date + } + + private func setLastReminded(_ date: Date?) { + UserDefaults.standard.set(date, forKey: VersionUpdateHandler.kVersionLastRemindedKey) + } + + private func lastReminded() -> Date? { + return UserDefaults.standard.object(forKey: VersionUpdateHandler.kVersionLastRemindedKey) as? Date + } + + private func ignoredVersion() -> String? { + return UserDefaults.standard.object(forKey: VersionUpdateHandler.kVersionIgnoreVersionKey) as? String + } + + private func setIgnoredVersion(_ version: String) { + UserDefaults.standard.set(version, forKey: VersionUpdateHandler.kVersionIgnoreVersionKey) + } + + private func setViewedVersionDetails(_ viewed: Bool) { + UserDefaults.standard.set(viewed ? applicationVersion : nil, forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) + } + + private func viewedVersionDetails() -> Bool { + let lastVersionKey = UserDefaults.standard.object(forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) as? String ?? "" + return lastVersionKey == applicationVersion } private func lastVersion() -> String { return UserDefaults.standard.object(forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) as? String ?? "" } - private func setLastReminded(_ date: Date?) { - UserDefaults.standard.set(date, forKey: VersionUpdateHandler.kVersionIgnoreVersionKey) + private func setLastVersion(_ version: String) { + UserDefaults.standard.set(version, forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) + } + + private func localVersionsDict() -> [String: Any] { + return [String: Any]() } private func versionDetails(_ version: String, _ dict: [String: Any]) -> String? { @@ -82,17 +165,40 @@ class VersionUpdateHandler: NSObject { return nil } - private func setViewedVersionDetails(_ viewed: Bool) { - UserDefaults.standard.set(viewed ? applicationVersion : nil, forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) + private func versionDetails(since lastVersion: String, in dict: [String: Any]) -> String? { + var lastVersionCopy = lastVersion + if previewMode { + lastVersionCopy = "0" + } + var newVersionFound = false + var details: String = "" + + let versions = dict.keys.sorted() + + for version in versions { + if version.compareVersion(lastVersionCopy) == .orderedDescending { + newVersionFound = true + } + details.append(versionDetails(version, dict) ?? "") + details.append("\n") + } + + if newVersionFound { + return details.trimmingCharacters(in: CharacterSet.newlines) + } + return nil } - private func viewedVersionDetails() -> Bool { - let lastVersionKey = UserDefaults.standard.object(forKey: VersionUpdateHandler.kVersionCheckLastVersionKey) as? String ?? "" - return lastVersionKey == applicationVersion + private func shouldCheckForNewVersion() -> Bool { + return true } - private func localVersionsDict() -> [String: Any] { - return [String: Any]() + private func applicationLaunched() { + if checkAtLaunch { + checkIfNewVersion() + } else if verboseLogging { + print("iVersion will not check for updatess because checkAtLaunch option is disabled") + } } private func versionDetailsString() -> String { @@ -101,12 +207,129 @@ class VersionUpdateHandler: NSObject { versionDetails = versionDetails(applicationVersion, localVersionsDict()) } } else { - versionDetails = versionDetails(lastVersion(), localVersionsDict()) + versionDetails = versionDetails(since: lastVersion(), in: localVersionsDict()) } return versionDetails! } + private func mostRecentVersionInDict(_ dict: [String: Any]) -> String { +// return [dictionary.allKeys sortedArrayUsingSelector:@selector(compareVersion:)].lastObject; + // TODO: Fix this sorting + return dict.keys.sorted().last ?? "" + } + + private func showAlertWithTitle(_ title: String, _ details: String, _ defaultButton: String, _ ignoreButton: String, _ remindButton: String) -> NSAlert { + let floatMax = CGFloat.greatestFiniteMagnitude + + let alert = NSAlert() + alert.messageText = title + alert.informativeText = inThisVersionTitle() + alert.addButton(withTitle: defaultButton) + + let scrollView = NSScrollView(frame: NSRect(x: 0.0, + y: 0.0, + width: 380.0, + height: 15.0)) + let contentSize = scrollView.contentSize + scrollView.borderType = .bezelBorder + scrollView.hasVerticalScroller = true + scrollView.hasHorizontalScroller = false + scrollView.autoresizingMask = [.width, .height] + + let textView = NSTextView(frame: NSRect(x: 0.0, + y: 0.0, + width: contentSize.width, + height: contentSize.height)) + textView.minSize = NSMakeSize(0.0, contentSize.height) + textView.maxSize = NSMakeSize(floatMax, floatMax) + textView.isVerticallyResizable = true + textView.isHorizontallyResizable = false + textView.isEditable = false + textView.autoresizingMask = .width + textView.textContainer?.containerSize = NSMakeSize(contentSize.width, floatMax) + textView.textContainer?.widthTracksTextView = true + textView.string = details + scrollView.documentView = textView + textView.sizeToFit() + + let height = min(200.0, scrollView.documentView?.frame.size.height ?? 200.0) + 3.0 + scrollView.frame = NSMakeRect(0.0, 0.0, scrollView.frame.size.width, height) + alert.accessoryView = scrollView + + if ignoreButton.count > 0 { + alert.addButton(withTitle: ignoreButton) + } + + if remindButton.count > 0 { + alert.addButton(withTitle: remindButton) + + let modalResponse = alert.runModal() + if modalResponse == .alertFirstButtonReturn { + // Right most button + didDismissAlert(alert, 0) + } else if modalResponse == .alertSecondButtonReturn { + didDismissAlert(alert, 1) + } else { + didDismissAlert(alert, 2) + } + } + + return alert + } + + private func showIgnoreButton() -> Bool { + return false + } + + private func showRemindButtton() -> Bool { + return false + } + + private func didDismissAlert(_: NSAlert, _: Int) { + // Get Button Indice + } + + private func downloadVersionsData() { + if onlyPromptIfMainWindowIsAvailable { + guard NSApplication.shared.mainWindow != nil else { + return + } + + _ = Repeater(interval: .seconds(0.5), mode: .infinite) { _ in + OperationQueue.main.addOperation { [weak self] in + guard let self = self else { + return + } + self.downloadVersionsData() + } + } + } + + if checkingForNewVersion { + checkingForNewVersion = false + + if remoteVersionsDict.count <= 0 { + if downloadError != nil { + print("Update Check Failed because of \(downloadError!.localizedDescription)") + } else { + print("Version Update Check because an unknown error occurred") + } + } + return + } + + let details = versionDetails(since: applicationVersion, in: remoteVersionsDict) + let mostRecentVersion = mostRecentVersionInDict(remoteVersionsDict) + + if details != nil { + // Check if ignored + let showDetails = ignoredVersion() == mostRecentVersion || previewMode + + if showDetails {} + } + } + private func checkIfNewVersion() { if onlyPromptIfMainWindowIsAvailable { guard NSApplication.shared.mainWindow != nil else { From 7379335c3198b6aed49ea7b96fe31ab9a4b17528 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 26 Jun 2020 21:19:27 -0500 Subject: [PATCH 12/37] Remove itunes link. --- Clocker/Dependencies/iVersion/iVersion.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Clocker/Dependencies/iVersion/iVersion.m b/Clocker/Dependencies/iVersion/iVersion.m index b9d5ea7..28814f7 100755 --- a/Clocker/Dependencies/iVersion/iVersion.m +++ b/Clocker/Dependencies/iVersion/iVersion.m @@ -69,7 +69,6 @@ static NSString *const iVersionLastRemindedKey = @"iVersionLastReminded"; static NSString *const iVersionMacAppStoreBundleID = @"com.apple.appstore"; static NSString *const iVersionAppLookupURLFormat = @"http://itunes.apple.com/%@/lookup"; -static NSString *const iVersioniOSAppStoreURLFormat = @"itms-apps://itunes.apple.com/app/id%@"; static NSString *const iVersionMacAppStoreURLFormat = @"macappstore://itunes.apple.com/app/id%@"; From 8513fc472e3f3ba6d2491c4bcb0cf9e2f4f60e8f Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 26 Jun 2020 21:21:18 -0500 Subject: [PATCH 13/37] Update colors for text in 11.0 --- Clocker/Menu Bar/StatusItemView.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Clocker/Menu Bar/StatusItemView.swift b/Clocker/Menu Bar/StatusItemView.swift index d3f14f4..a97ec4a 100644 --- a/Clocker/Menu Bar/StatusItemView.swift +++ b/Clocker/Menu Bar/StatusItemView.swift @@ -14,7 +14,11 @@ var compactModeTimeFont: NSFont { } var timeAttributes: [NSAttributedString.Key: AnyObject] { - let textColor = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark" ? NSColor.white : NSColor.black + var textColor = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark" ? NSColor.white : NSColor.black + + if #available(macOS 10.15, *) { + textColor = NSColor.white + } let attributes = [ NSAttributedString.Key.font: compactModeTimeFont, @@ -35,7 +39,11 @@ class StatusItemView: NSView { } private var textFontAttributes: [NSAttributedString.Key: Any] { - let textColor = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark" ? NSColor.white : NSColor.black + var textColor = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark" ? NSColor.white : NSColor.black + + if #available(macOS 10.15, *) { + textColor = NSColor.white + } let textFontAttributes = [ NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 10), From 68b152c669a13d1b23273adb15b25bfe85122823 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 26 Jun 2020 22:56:05 -0500 Subject: [PATCH 14/37] Update to SF Symbol image! --- Clocker/Overall App/Themer.swift | 14 ++++++++++++-- Clocker/Panel/UI/TimezoneDataSource.swift | 7 ++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Clocker/Overall App/Themer.swift b/Clocker/Overall App/Themer.swift index 8a0d030..e5957cc 100644 --- a/Clocker/Overall App/Themer.swift +++ b/Clocker/Overall App/Themer.swift @@ -166,6 +166,11 @@ extension Themer { } func preferenceImage() -> NSImage { + if #available(macOS 10.16, *) { + return NSImage(systemSymbolName: "gear", + accessibilityDescription: nil)! + } + if #available(macOS 10.14, *) { switch themeIndex { case .light: @@ -177,7 +182,10 @@ extension Themer { } } - return themeIndex == .light ? NSImage(named: NSImage.Name("Settings"))! : NSImage(named: NSImage.Name("Settings-White"))! + return + themeIndex == .light + ? NSImage(named: NSImage.Name("Settings"))! + : NSImage(named: NSImage.Name("Settings-White"))! } func pinImage() -> NSImage { @@ -192,7 +200,9 @@ extension Themer { } } - return themeIndex == .light ? NSImage(named: NSImage.Name("Float"))! : NSImage(named: NSImage.Name("Float-White"))! + return themeIndex == .light + ? NSImage(named: NSImage.Name("Float"))! + : NSImage(named: NSImage.Name("Float-White"))! } func sunriseImage() -> NSImage { diff --git a/Clocker/Panel/UI/TimezoneDataSource.swift b/Clocker/Panel/UI/TimezoneDataSource.swift index beaab76..18226e5 100644 --- a/Clocker/Panel/UI/TimezoneDataSource.swift +++ b/Clocker/Panel/UI/TimezoneDataSource.swift @@ -136,7 +136,12 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate { }) - swipeToDelete.image = NSImage(named: NSImage.Name("Trash")) + if #available(OSX 10.16, *) { + swipeToDelete.image = NSImage(systemSymbolName: "trash.fill", + accessibilityDescription: nil) + } else { + swipeToDelete.image = NSImage(named: NSImage.Name("Trash")) + } return [swipeToDelete] } From 093eafbe6b16cb69b5bda668499beebc1945571e Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 26 Jun 2020 23:12:22 -0500 Subject: [PATCH 15/37] Use of more SF symbols. --- Clocker/Overall App/Themer.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Clocker/Overall App/Themer.swift b/Clocker/Overall App/Themer.swift index e5957cc..1478d6f 100644 --- a/Clocker/Overall App/Themer.swift +++ b/Clocker/Overall App/Themer.swift @@ -151,6 +151,11 @@ extension Themer { } func shutdownImage() -> NSImage { + if #available(macOS 10.16, *) { + return NSImage(systemSymbolName: "ellipsis.circle", + accessibilityDescription: nil)! + } + if #available(macOS 10.14, *) { switch themeIndex { case .light: @@ -189,6 +194,11 @@ extension Themer { } func pinImage() -> NSImage { + if #available(macOS 10.16, *) { + return NSImage(systemSymbolName: "macwindow.on.rectangle", + accessibilityDescription: nil)! + } + if #available(macOS 10.14, *) { switch themeIndex { case .light: @@ -309,6 +319,11 @@ extension Themer { } func sharingImage() -> NSImage { + if #available(macOS 10.16, *) { + return NSImage(systemSymbolName: "square.and.arrow.up.on.square.fill", + accessibilityDescription: nil)! + } + if #available(macOS 10.14, *) { switch themeIndex { case .light: From 1d3d3b7831b1e363ea64f1147689433f6e012301 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Fri, 26 Jun 2020 23:16:37 -0500 Subject: [PATCH 16/37] Add button size. --- Clocker/Onboarding/OnboardingParentViewController.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Clocker/Onboarding/OnboardingParentViewController.swift b/Clocker/Onboarding/OnboardingParentViewController.swift index d299dfe..432f8bb 100644 --- a/Clocker/Onboarding/OnboardingParentViewController.swift +++ b/Clocker/Onboarding/OnboardingParentViewController.swift @@ -69,6 +69,12 @@ class OnboardingParentViewController: NSViewController { backButton.tag = OnboardingType.welcome.rawValue [negativeButton, backButton].forEach { $0?.isHidden = true } + + if #available(OSX 10.16, *) { + negativeButton.controlSize = .large + positiveButton.controlSize = .large + backButton.controlSize = .large + } } private func setIdentifiersForTests() { From 75a77bf89d5061b95e7bfa62936f5f16d1bf0ff4 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sat, 27 Jun 2020 00:31:02 -0500 Subject: [PATCH 17/37] Updating icons. --- Clocker/Clocker/en.lproj/Panel.xib | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Clocker/Clocker/en.lproj/Panel.xib b/Clocker/Clocker/en.lproj/Panel.xib index 2b1893f..7affbaf 100755 --- a/Clocker/Clocker/en.lproj/Panel.xib +++ b/Clocker/Clocker/en.lproj/Panel.xib @@ -1,8 +1,8 @@ - + - + @@ -38,7 +38,7 @@ - + @@ -47,19 +47,19 @@ - + - + - + - + @@ -72,7 +72,7 @@ - + @@ -208,7 +208,7 @@ - + - + @@ -421,7 +425,7 @@ DQ - + @@ -449,7 +453,7 @@ DQ - + @@ -461,19 +465,19 @@ DQ - + - + - + - + @@ -486,7 +490,7 @@ DQ - + @@ -509,7 +513,7 @@ DQ - + @@ -541,7 +545,7 @@ DQ + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -582,13 +601,9 @@ DQ - - - - @@ -603,7 +618,7 @@ DQ - + From 6aa871a68672ef73c01ec93032a9365eadbe21b4 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sat, 27 Jun 2020 18:51:53 -0500 Subject: [PATCH 29/37] Align clocker icon in Onboarding flow! --- Clocker/AppDelegate.swift | 2 +- Clocker/ClockerUITests/FloatingWindowTests.swift | 2 +- Clocker/Onboarding/Onboarding.storyboard | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Clocker/AppDelegate.swift b/Clocker/AppDelegate.swift index a79b6b9..6d0dcfb 100644 --- a/Clocker/AppDelegate.swift +++ b/Clocker/AppDelegate.swift @@ -113,7 +113,7 @@ open class AppDelegate: NSObject, NSApplicationDelegate { let shouldLaunchOnboarding = (DataStore.shared().retrieve(key: CLShowOnboardingFlow) == nil && DataStore.shared().timezones().isEmpty) || ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument) - shouldLaunchOnboarding ? controller?.launch() : continueUsually() + shouldLaunchOnboarding ? controller?.launch() : controller?.launch() } func continueUsually() { diff --git a/Clocker/ClockerUITests/FloatingWindowTests.swift b/Clocker/ClockerUITests/FloatingWindowTests.swift index 2d073a6..0548d6d 100644 --- a/Clocker/ClockerUITests/FloatingWindowTests.swift +++ b/Clocker/ClockerUITests/FloatingWindowTests.swift @@ -161,7 +161,7 @@ class FloatingWindowTests: XCTestCase { XCTAssertFalse(app.staticTexts["InformationLabel"].exists) } - /// Make sure to ensure supplementary/relative date label is turned on! + /// Make sure to ensure supplementary/relative date label is turned on! func testMovingSlider() { if app.buttons["Pin"].exists { app.buttons["Pin"].click() diff --git a/Clocker/Onboarding/Onboarding.storyboard b/Clocker/Onboarding/Onboarding.storyboard index 576766f..9b3a1b3 100644 --- a/Clocker/Onboarding/Onboarding.storyboard +++ b/Clocker/Onboarding/Onboarding.storyboard @@ -437,7 +437,7 @@ DQ - + @@ -445,7 +445,7 @@ DQ - + @@ -599,10 +599,10 @@ DQ + - From a0184e52d572a70c9149e298487aa63af57d555c Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sat, 27 Jun 2020 21:34:15 -0500 Subject: [PATCH 30/37] Older Xcode compatibility! --- .../OnboardingParentViewController.swift | 7 +++--- Clocker/Overall App/Themer.swift | 22 ++++++++++--------- Clocker/Panel/ParentPanelController.swift | 2 +- Clocker/Panel/UI/TimezoneDataSource.swift | 3 +-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Clocker/Onboarding/OnboardingParentViewController.swift b/Clocker/Onboarding/OnboardingParentViewController.swift index a2386dd..629b7f7 100644 --- a/Clocker/Onboarding/OnboardingParentViewController.swift +++ b/Clocker/Onboarding/OnboardingParentViewController.swift @@ -69,10 +69,9 @@ class OnboardingParentViewController: NSViewController { [negativeButton, backButton].forEach { $0?.isHidden = true } if #available(OSX 10.16, *) { - negativeButton.controlSize = .large - positiveButton.controlSize = .large - backButton.image = NSImage(systemSymbolName: "chevron.left.circle.fill", - accessibilityDescription: nil) +// negativeButton.controlSize = .large +// positiveButton.controlSize = .large + backButton.image = Themer.shared().symbolImage(for: "chevron.left.circle.fill", "back-button") } else { backButton.title = NSLocalizedString("Back", comment: "Button title for going back to the previous screen") diff --git a/Clocker/Overall App/Themer.swift b/Clocker/Overall App/Themer.swift index 1478d6f..d98197c 100644 --- a/Clocker/Overall App/Themer.swift +++ b/Clocker/Overall App/Themer.swift @@ -152,8 +152,7 @@ extension Themer { func shutdownImage() -> NSImage { if #available(macOS 10.16, *) { - return NSImage(systemSymbolName: "ellipsis.circle", - accessibilityDescription: nil)! + return symbolImage(for: "ellipsis.circle", nil) } if #available(macOS 10.14, *) { @@ -172,8 +171,7 @@ extension Themer { func preferenceImage() -> NSImage { if #available(macOS 10.16, *) { - return NSImage(systemSymbolName: "gear", - accessibilityDescription: nil)! + return symbolImage(for: "gear", nil) } if #available(macOS 10.14, *) { @@ -189,14 +187,13 @@ extension Themer { return themeIndex == .light - ? NSImage(named: NSImage.Name("Settings"))! - : NSImage(named: NSImage.Name("Settings-White"))! + ? NSImage(named: NSImage.Name("Settings"))! + : NSImage(named: NSImage.Name("Settings-White"))! } func pinImage() -> NSImage { if #available(macOS 10.16, *) { - return NSImage(systemSymbolName: "macwindow.on.rectangle", - accessibilityDescription: nil)! + return symbolImage(for: "macwindow.on.rectangle", nil) } if #available(macOS 10.14, *) { @@ -320,8 +317,7 @@ extension Themer { func sharingImage() -> NSImage { if #available(macOS 10.16, *) { - return NSImage(systemSymbolName: "square.and.arrow.up.on.square.fill", - accessibilityDescription: nil)! + return symbolImage(for: "square.and.arrow.up.on.square.fill", nil) } if #available(macOS 10.14, *) { @@ -448,4 +444,10 @@ extension Themer { NSColor(deviceRed: 241.0 / 255.0, green: 241.0 / 255.0, blue: 241.0 / 255.0, alpha: 1.0) : NSColor(deviceRed: 42.0 / 255.0, green: 55.0 / 255.0, blue: 62.0 / 255.0, alpha: 1.0) } + + func symbolImage(for _: String, _: String?) -> NSImage { + // Dummy image for older xcodes + return NSImage(named: NSImage.Name("Calendar Tab Icon"))! +// return NSImage(systemSymbolName: name, accessibilityDescription: accessibilityDescription)! + } } diff --git a/Clocker/Panel/ParentPanelController.swift b/Clocker/Panel/ParentPanelController.swift index d455664..79bc020 100644 --- a/Clocker/Panel/ParentPanelController.swift +++ b/Clocker/Panel/ParentPanelController.swift @@ -168,7 +168,7 @@ class ParentPanelController: NSWindowController { showDebugVersionViewIfNeccesary() if #available(macOS 10.16, *) { - mainTableView.style = .fullWidth +// mainTableView.style = .fullWidth } } diff --git a/Clocker/Panel/UI/TimezoneDataSource.swift b/Clocker/Panel/UI/TimezoneDataSource.swift index 38d9f66..c602dba 100644 --- a/Clocker/Panel/UI/TimezoneDataSource.swift +++ b/Clocker/Panel/UI/TimezoneDataSource.swift @@ -135,8 +135,7 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate { }) if #available(OSX 10.16, *) { - swipeToDelete.image = NSImage(systemSymbolName: "trash.fill", - accessibilityDescription: nil) + swipeToDelete.image = Themer.shared().symbolImage(for: "trash.fill", "Trash Button") } else { swipeToDelete.image = NSImage(named: NSImage.Name("Trash")) } From afb437020ac7d4bdc1e8a07f02a2a1cda65d63f9 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sat, 27 Jun 2020 22:54:47 -0500 Subject: [PATCH 31/37] Revert back to og back button! --- Clocker/Onboarding/Onboarding.storyboard | 308 ++--------------------- 1 file changed, 22 insertions(+), 286 deletions(-) diff --git a/Clocker/Onboarding/Onboarding.storyboard b/Clocker/Onboarding/Onboarding.storyboard index 5a0c3ec..1ce227f 100644 --- a/Clocker/Onboarding/Onboarding.storyboard +++ b/Clocker/Onboarding/Onboarding.storyboard @@ -1,8 +1,8 @@ - + - + @@ -46,7 +46,7 @@ - + @@ -425,7 +425,7 @@ DQ - + @@ -453,7 +453,7 @@ DQ - + @@ -465,13 +465,13 @@ DQ - + - + - + @@ -490,7 +490,7 @@ DQ - + @@ -513,11 +513,11 @@ DQ - + - + @@ -562,7 +562,7 @@ DQ