Browse Source

Merge branch 'master' of https://github.com/n0shake/Clocker

pull/92/head
Abhishek 4 years ago
parent
commit
67f50c08af
  1. 7
      Clocker/AppDelegate.swift
  2. 23
      Clocker/Clocker.xcodeproj/project.pbxproj
  3. 28
      Clocker/Clocker.xcodeproj/xcshareddata/xcschemes/Clocker.xcscheme
  4. 24
      Clocker/Clocker.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme
  5. 24
      Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcschemes/ClockerHelper.xcscheme
  6. 2
      Clocker/Clocker/Clocker.entitlements
  7. 6
      Clocker/Clocker/ShortcutRecorder-master/ShortcutRecorder.xcodeproj/xcshareddata/xcschemes/PTHotKey.framework.xcscheme
  8. 6
      Clocker/Clocker/ShortcutRecorder-master/ShortcutRecorder.xcodeproj/xcshareddata/xcschemes/ShortcutRecorder.framework.xcscheme
  9. 31
      Clocker/Clocker/en.lproj/Panel.xib
  10. 2
      Clocker/ClockerUITests/AboutUsTests.swift
  11. 105
      Clocker/ClockerUITests/OnboardingSearchTests.swift
  12. 2
      Clocker/ClockerUnitTests/ClockerUnitTests.swift
  13. 24
      Clocker/Events and Reminders/CalendarHandler.swift
  14. 2
      Clocker/Events and Reminders/EventCenter.swift
  15. 12
      Clocker/Events and Reminders/RemindersHandler.swift
  16. 14
      Clocker/Menu Bar/StatusContainerView.swift
  17. 3
      Clocker/Menu Bar/StatusItemHandler.swift
  18. 87
      Clocker/Onboarding/Onboarding.storyboard
  19. 72
      Clocker/Onboarding/OnboardingSearchController.swift
  20. 1
      Clocker/Overall App/Strings.swift
  21. 14
      Clocker/Panel/Data Layer/TimezoneDataOperations.swift
  22. 10
      Clocker/Panel/Notes Popover/NotesPopover.xib
  23. 4
      Clocker/Panel/PanelController.swift
  24. 26
      Clocker/Panel/ParentPanelController.swift
  25. 31
      Clocker/Panel/UI/FloatingWindow.xib
  26. 53
      Clocker/Panel/UI/TimezoneCellView.swift
  27. 9
      Clocker/Panel/UI/TimezoneDataSource.swift
  28. 90
      Clocker/Preferences/Appearance/AppearanceViewController.swift
  29. 16
      Clocker/Preferences/General/PreferencesViewController.swift
  30. 1556
      Clocker/Preferences/Preferences.storyboard

7
Clocker/AppDelegate.swift

@ -53,7 +53,6 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
RateController.applicationDidLaunch(UserDefaults.standard)
#if RELEASE
Crashlytics.sharedInstance().debugMode = true
Fabric.with([Crashlytics.self])
checkIfRunFromApplicationsFolder()
#endif
@ -161,7 +160,11 @@ open class AppDelegate: NSObject, NSApplicationDelegate {
let defaults = UserDefaults.standard
let currentActivationPolicy = NSRunningApplication.current.activationPolicy
let activationPolicy: NSApplication.ActivationPolicy = defaults.integer(forKey: CLAppDislayOptions) == 0 ? .accessory : .regular
var activationPolicy: NSApplication.ActivationPolicy = defaults.integer(forKey: CLAppDislayOptions) == 0 ? .accessory : .regular
#if DEBUG
activationPolicy = .regular
#endif
if currentActivationPolicy != activationPolicy {
NSApp.setActivationPolicy(activationPolicy)

23
Clocker/Clocker.xcodeproj/project.pbxproj

@ -81,6 +81,7 @@
35C36FA12259ED6D002FA5C6 /* EventCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F9E2259ED6D002FA5C6 /* EventCenter.swift */; };
35C36FA22259ED6D002FA5C6 /* RemindersHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36F9F2259ED6D002FA5C6 /* RemindersHandler.swift */; };
35C36FA42259EEC2002FA5C6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C36FA32259EEC2002FA5C6 /* AppDelegate.swift */; };
35E05E4424621A40008CA0A9 /* Keys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 35E05E4324621A40008CA0A9 /* Keys.plist */; };
9A0A1C8C20903DBD0012003B /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A9E87651C1FEDC500A7A2DF /* CoreLocation.framework */; };
9A13BAD61CA87F08007C6CBE /* Panel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A13BAD81CA87F08007C6CBE /* Panel.xib */; };
9A13BAE01CA882FA007C6CBE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9A13BAE21CA882FA007C6CBE /* InfoPlist.strings */; };
@ -107,6 +108,7 @@
9A7CDC1B22BEC2170035902D /* StartupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A7CDC1A22BEC2170035902D /* StartupManager.swift */; };
9A8605AE1BEC148400A810A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A8605AD1BEC148400A810A4 /* main.m */; };
9A8B256A232EFAD300204CAD /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9A13BAEC1CA88A76007C6CBE /* Localizable.strings */; };
9A97419B2455442100087B0D /* OnboardingSearchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A97419A2455442100087B0D /* OnboardingSearchTests.swift */; };
9A9E87621C1FEDB500A7A2DF /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A9E87611C1FEDB500A7A2DF /* CFNetwork.framework */; };
9A9E876A1C1FEDDB00A7A2DF /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A9E87691C1FEDDB00A7A2DF /* SystemConfiguration.framework */; };
9AA522C023415BDD00C9E005 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9AA522BE23415BDD00C9E005 /* InfoPlist.strings */; };
@ -298,6 +300,7 @@
35C36F9E2259ED6D002FA5C6 /* EventCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventCenter.swift; sourceTree = "<group>"; };
35C36F9F2259ED6D002FA5C6 /* RemindersHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemindersHandler.swift; sourceTree = "<group>"; };
35C36FA32259EEC2002FA5C6 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = SOURCE_ROOT; };
35E05E4324621A40008CA0A9 /* Keys.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Keys.plist; path = ../Internal/Keys.plist; sourceTree = "<group>"; };
9A13BAD71CA87F08007C6CBE /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Panel.xib; sourceTree = "<group>"; };
9A13BAE11CA882FA007C6CBE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
9A13BAEB1CA88A76007C6CBE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -337,6 +340,7 @@
9A8605C31BEC155B00A810A4 /* Clocker-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "Clocker-Info.plist"; path = "Clocker/Clocker-Info.plist"; sourceTree = "<group>"; };
9A8605CC1BEC155B00A810A4 /* Clocker-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Clocker-Prefix.pch"; path = "Clocker/Clocker-Prefix.pch"; sourceTree = "<group>"; };
9A86E2B51CE04F1600547EE7 /* ShortcutRecorder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ShortcutRecorder.xcodeproj; path = "Clocker/ShortcutRecorder-master/ShortcutRecorder.xcodeproj"; sourceTree = "<group>"; };
9A97419A2455442100087B0D /* OnboardingSearchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingSearchTests.swift; sourceTree = "<group>"; };
9A9E87611C1FEDB500A7A2DF /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
9A9E87631C1FEDBD00A7A2DF /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
9A9E87651C1FEDC500A7A2DF /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
@ -809,6 +813,7 @@
C2D30A8C21025106000BFAEE /* NetworkDisconnectionTests.swift */,
C22F3D7F2107778A0001D5E1 /* ShortcutTests.swift */,
C2AB022321AEED590014A401 /* OnboardingTests.swift */,
9A97419A2455442100087B0D /* OnboardingSearchTests.swift */,
);
path = ClockerUITests;
sourceTree = "<group>";
@ -816,6 +821,7 @@
DD4F7BF913C30F9F00825C6E = {
isa = PBXGroup;
children = (
35E05E4324621A40008CA0A9 /* Keys.plist */,
35C36F9B2259EC97002FA5C6 /* Events and Reminders */,
35C36F382259D80C002FA5C6 /* Overall App */,
35C36F242259D64D002FA5C6 /* Panel */,
@ -966,7 +972,7 @@
CLASSPREFIX = "";
DefaultBuildSystemTypeForWorkspace = Latest;
LastSwiftUpdateCheck = 1000;
LastUpgradeCheck = 1020;
LastUpgradeCheck = 1140;
TargetAttributes = {
9A7547CF1F184DC3004705EF = {
CreatedOnToolsVersion = 8.3.2;
@ -1109,6 +1115,7 @@
9A13BAD61CA87F08007C6CBE /* Panel.xib in Resources */,
35C36F6B2259E0E1002FA5C6 /* FloatingWindow.xib in Resources */,
35C36F17225961DA002FA5C6 /* DateTools.bundle in Resources */,
35E05E4424621A40008CA0A9 /* Keys.plist in Resources */,
35C36EF322595F14002FA5C6 /* WelcomeView.xib in Resources */,
35C36EF822595F14002FA5C6 /* Onboarding.storyboard in Resources */,
35C36F612259DE67002FA5C6 /* NotesPopover.xib in Resources */,
@ -1180,6 +1187,7 @@
C213713420B4FD920024D5A4 /* FloatingWindowTests.swift in Sources */,
C22F3D802107778A0001D5E1 /* ShortcutTests.swift in Sources */,
C2D30A8A210245C6000BFAEE /* ReviewTests.swift in Sources */,
9A97419B2455442100087B0D /* OnboardingSearchTests.swift in Sources */,
C2D30A8D21025106000BFAEE /* NetworkDisconnectionTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1446,7 +1454,7 @@
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 75;
CURRENT_PROJECT_VERSION = 77;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
@ -1471,7 +1479,7 @@
INFOPLIST_FILE = "Clocker/Clocker-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
MARKETING_VERSION = 1.6.20;
MARKETING_VERSION = 20.05.01;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.abhishek.Clocker;
PRODUCT_NAME = Clocker;
@ -1931,10 +1939,11 @@
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 75;
CURRENT_PROJECT_VERSION = 77;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
@ -1957,7 +1966,7 @@
INFOPLIST_FILE = "Clocker/Clocker-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
MARKETING_VERSION = 1.6.20;
MARKETING_VERSION = 20.05.01;
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = "";
"OTHER_SWIFT_FLAGS[arch=*]" = "-D DEBUG";
@ -1993,7 +2002,7 @@
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 75;
CURRENT_PROJECT_VERSION = 77;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
@ -2018,7 +2027,7 @@
INFOPLIST_FILE = "Clocker/Clocker-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
MARKETING_VERSION = 1.6.20;
MARKETING_VERSION = 20.05.01;
OTHER_LDFLAGS = "";
"OTHER_SWIFT_FLAGS[arch=*]" = "-D RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = com.abhishek.Clocker;

28
Clocker/Clocker.xcodeproj/xcshareddata/xcschemes/Clocker.xcscheme

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1140"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
@ -26,8 +26,17 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
codeCoverageEnabled = "YES"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
@ -50,17 +59,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -95,8 +93,6 @@
isEnabled = "NO">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">

24
Clocker/Clocker.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1140"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -27,6 +27,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
@ -39,17 +48,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -71,8 +69,6 @@
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

24
Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcschemes/ClockerHelper.xcscheme

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1140"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -27,6 +27,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
@ -39,17 +48,6 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -71,8 +69,6 @@
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

2
Clocker/Clocker/Clocker.entitlements

@ -4,6 +4,8 @@
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.personal-information.calendars</key>

6
Clocker/Clocker/ShortcutRecorder-master/ShortcutRecorder.xcodeproj/xcshareddata/xcschemes/PTHotKey.framework.xcscheme

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1140"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -51,8 +49,6 @@
ReferencedContainer = "container:ShortcutRecorder.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

6
Clocker/Clocker/ShortcutRecorder-master/ShortcutRecorder.xcodeproj/xcshareddata/xcschemes/ShortcutRecorder.framework.xcscheme

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1140"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -51,8 +49,6 @@
ReferencedContainer = "container:ShortcutRecorder.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

31
Clocker/Clocker/en.lproj/Panel.xib

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15504"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -38,7 +38,7 @@
<windowCollectionBehavior key="collectionBehavior" moveToActiveSpace="YES" ignoresCycle="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="1000" y="379" width="350" height="460"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" focusRingType="none" id="6" customClass="BackgroundPanelView" customModule="Clocker" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="350" height="460"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -54,14 +54,13 @@
<subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowHeight="95" viewBased="YES" id="dFw-ts-8OZ" customClass="PanelTableView" customModule="Clocker" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="350" height="265"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="1"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="347" minWidth="303" maxWidth="1000" id="LTt-db-Dwv">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -79,9 +78,9 @@
<textField verticalHuggingPriority="750" verticalCompressionResistancePriority="749" tag="102" preferredMaxLayoutWidth="72" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QUd-7D-q14">
<rect key="frame" x="28" y="50" width="189" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="JkG-8f-zhJ"/>
<constraint firstAttribute="height" constant="22" identifier="relative-day-height" id="JkG-8f-zhJ"/>
</constraints>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" state="on" placeholderString="Tomorrow" usesSingleLineMode="YES" id="74U-rv-5xj">
<textFieldCell key="cell" sendsActionOnEndEditing="YES" state="on" usesSingleLineMode="YES" id="74U-rv-5xj">
<font key="font" size="13" name="Avenir-Heavy"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -139,15 +138,15 @@
</textFieldCell>
</textField>
<stackView distribution="fill" orientation="vertical" alignment="centerX" spacing="-5" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Cbs-xa-uR7">
<rect key="frame" x="0.0" y="32" width="30" height="59"/>
<rect key="frame" x="0.0" y="35" width="30" height="56"/>
<subviews>
<imageView toolTip="Current Timezone" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="SVj-Xy-zG5">
<rect key="frame" x="3" y="34" width="25" height="25"/>
<rect key="frame" x="4" y="34" width="22" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="25" id="FqJ-7B-iG3"/>
<constraint firstAttribute="height" constant="25" id="N9m-Hj-a3D"/>
<constraint firstAttribute="width" constant="22" id="FqJ-7B-iG3"/>
<constraint firstAttribute="height" constant="22" id="N9m-Hj-a3D"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageAlignment="right" imageScaling="proportionallyDown" image="CurrentLocation" id="oBW-Gh-ZWI"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyDown" image="CurrentLocation" id="oBW-Gh-ZWI"/>
</imageView>
<button verticalHuggingPriority="750" alphaValue="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Y5g-Az-pAQ">
<rect key="frame" x="0.0" y="0.0" width="30" height="39"/>
@ -178,22 +177,22 @@
</stackView>
</subviews>
<constraints>
<constraint firstItem="etF-33-bCB" firstAttribute="top" secondItem="qbN-ba-fho" secondAttribute="top" constant="12" id="0yr-0x-Mrj"/>
<constraint firstItem="QUd-7D-q14" firstAttribute="top" secondItem="etF-33-bCB" secondAttribute="bottom" constant="7" id="BEN-9I-ixx"/>
<constraint firstItem="etF-33-bCB" firstAttribute="top" secondItem="qbN-ba-fho" secondAttribute="top" constant="12" identifier="custom-name-top-space" id="0yr-0x-Mrj"/>
<constraint firstItem="Cbs-xa-uR7" firstAttribute="top" secondItem="qbN-ba-fho" secondAttribute="top" constant="20" id="5tC-62-8VG"/>
<constraint firstItem="QUd-7D-q14" firstAttribute="top" secondItem="etF-33-bCB" secondAttribute="bottom" constant="7" identifier="location-bottom-constraint" id="BEN-9I-ixx"/>
<constraint firstItem="vnv-J2-7r1" firstAttribute="top" secondItem="etF-33-bCB" secondAttribute="top" constant="-3" identifier="time-top-space" id="Ddo-fy-t7b"/>
<constraint firstItem="uOg-ij-alO" firstAttribute="trailing" secondItem="vnv-J2-7r1" secondAttribute="trailing" id="ENb-Ol-gDA"/>
<constraint firstItem="etF-33-bCB" firstAttribute="leading" secondItem="Cbs-xa-uR7" secondAttribute="trailing" id="F6z-Ym-WBn"/>
<constraint firstAttribute="trailing" secondItem="6At-J8-gzZ" secondAttribute="trailing" constant="2" id="KOx-Xx-Lcj"/>
<constraint firstItem="vnv-J2-7r1" firstAttribute="leading" secondItem="etF-33-bCB" secondAttribute="trailing" constant="10" id="QNj-Ip-TrA"/>
<constraint firstAttribute="bottom" secondItem="6At-J8-gzZ" secondAttribute="bottom" id="ScN-F7-6DA"/>
<constraint firstItem="6At-J8-gzZ" firstAttribute="leading" secondItem="QUd-7D-q14" secondAttribute="leading" id="TxT-72-I4I"/>
<constraint firstItem="Cbs-xa-uR7" firstAttribute="top" secondItem="etF-33-bCB" secondAttribute="top" constant="8" id="Zbj-XR-eXs"/>
<constraint firstItem="sML-fJ-nbv" firstAttribute="top" secondItem="vnv-J2-7r1" secondAttribute="bottom" constant="-2" id="fDa-0N-dW8"/>
<constraint firstItem="sML-fJ-nbv" firstAttribute="leading" secondItem="QUd-7D-q14" secondAttribute="trailing" constant="10" id="hFC-6L-ahw"/>
<constraint firstItem="uOg-ij-alO" firstAttribute="top" secondItem="vnv-J2-7r1" secondAttribute="bottom" constant="-2" id="jnZ-S4-3aC"/>
<constraint firstItem="uOg-ij-alO" firstAttribute="leading" secondItem="sML-fJ-nbv" secondAttribute="trailing" constant="2" id="lOG-UM-1UX"/>
<constraint firstItem="Cbs-xa-uR7" firstAttribute="leading" secondItem="qbN-ba-fho" secondAttribute="leading" id="nZr-y8-mHE"/>
<constraint firstItem="QUd-7D-q14" firstAttribute="leading" secondItem="etF-33-bCB" secondAttribute="leading" id="qpc-l4-zYv"/>
<constraint firstItem="vnv-J2-7r1" firstAttribute="top" secondItem="qbN-ba-fho" secondAttribute="top" constant="9" id="vGp-XY-wiJ"/>
<constraint firstAttribute="trailing" secondItem="vnv-J2-7r1" secondAttribute="trailing" constant="20" id="zXo-eA-0bQ"/>
</constraints>
<connections>

2
Clocker/ClockerUITests/AboutUsTests.swift

@ -33,7 +33,7 @@ class AboutUsTests: XCTestCase {
tapAboutTab()
let appDisplayName = "CFBundleDisplayName".localizedString()
let expectedVersion = "\(appDisplayName) 1.6.19 (74)"
let expectedVersion = "\(appDisplayName) 20.05.01 (77)"
guard let presentVersion = app.windows["Clocker"].staticTexts["ClockerVersion"].value as? String else {
XCTFail("Present version not present")
return

105
Clocker/ClockerUITests/OnboardingSearchTests.swift

@ -0,0 +1,105 @@
// Copyright © 2015 Abhishek Banthia
import XCTest
class OnboardingSearchTests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
super.setUp()
continueAfterFailure = false
app = XCUIApplication()
app.launchArguments.append(CLOnboaringTestsLaunchArgument)
app.launch()
// Let's go to the Search View
moveForward()
moveForward()
moveForward()
}
func testRegularSearch() throws {
let searchField = app.searchFields["MainSearchField"]
searchField.reset(text: "Paris")
searchField.typeKey(XCUIKeyboardKey.return, modifierFlags: XCUIElement.KeyModifierFlags())
sleep(2) // Wait for the query to return
let results = app.tables["ResultsTableView"]
let firstResult = results.cells.firstMatch
XCTAssertTrue(results.cells.count > 0)
let resultsPredicate = NSPredicate(format: "value CONTAINS 'Paris'", "")
XCTAssertTrue(firstResult.staticTexts.matching(resultsPredicate).count > 0)
// Let's retrieve the tap and add it!
firstResult.doubleClick()
sleep(2) // Wait for the Undo button to appear
// Ensure Added Text is shown properly!
let predicate = NSPredicate(format: "value BEGINSWITH 'Added'", "")
let successTextShown = app.staticTexts.containing(predicate)
XCTAssertTrue(successTextShown.count > 0)
}
func testUndoSearch() throws {
let searchField = app.searchFields["MainSearchField"]
searchField.reset(text: "Seoul")
searchField.typeKey(XCUIKeyboardKey.return, modifierFlags: XCUIElement.KeyModifierFlags())
sleep(2) // Wait for the query to return
let results = app.tables["ResultsTableView"]
let firstResult = results.cells.firstMatch
XCTAssertTrue(results.cells.count > 0)
let resultsPredicate = NSPredicate(format: "value CONTAINS 'Seoul'", "")
XCTAssertTrue(firstResult.staticTexts.containing(resultsPredicate).count > 0)
// Let's retrieve the tap and add it!
firstResult.doubleClick()
sleep(2) // Wait for the Undo button to appear
// Ensure Added Text is shown properly!
let predicate = NSPredicate(format: "value BEGINSWITH 'Added'", "")
let successTextShown = app.staticTexts.containing(predicate)
XCTAssertTrue(successTextShown.count > 0)
let undoButton = app.buttons.matching(identifier: "UndoButton").firstMatch
undoButton.click()
// Ensure Removed Text is shown!
let removedPredicate = NSPredicate(format: "value BEGINSWITH 'Removed.'", "")
let removedText = app.staticTexts.containing(removedPredicate)
XCTAssertTrue(removedText.count > 0)
}
func testMispelledCityNameSearch() throws {
let searchField = app.searchFields["MainSearchField"]
searchField.reset(text: "ajsdkjasdkjhasdkashkjda")
searchField.typeKey(XCUIKeyboardKey.return, modifierFlags: XCUIElement.KeyModifierFlags())
sleep(2) // Wait for the query to return
let results = app.tables["ResultsTableView"]
let firstResult = results.cells.firstMatch
XCTAssertTrue(results.cells.count == 0)
XCTAssertFalse(firstResult.staticTexts["Paris, France"].exists)
sleep(2) // Wait for the Undo button to appear
// Ensure Added Text is shown properly!
let noErrorTextPredicate = NSPredicate(format: "value CONTAINS 'No results! 😔 Try entering the exact name.'", "")
let noErrorText = app.staticTexts.containing(noErrorTextPredicate)
XCTAssertTrue(noErrorText.count > 0)
}
private func moveForward() {
let onboardingWindow = app.windows["OnboardingWindow"]
onboardingWindow.buttons["Forward"].click()
sleep(1)
}
}

2
Clocker/ClockerUnitTests/ClockerUnitTests.swift

@ -157,7 +157,7 @@ class ClockerUnitTests: XCTestCase {
XCTAssertTrue(operations.timeDifference() == ", 12 hours 30 mins ahead", "Difference was unexpectedly: \(operations.timeDifference())")
XCTAssertTrue(californiaOperations.timeDifference() == "", "Difference was unexpectedly: \(californiaOperations.timeDifference())")
XCTAssertTrue(floridaOperations.timeDifference() == ", 3 hours ahead", "Difference was unexpectedly: \(floridaOperations.timeDifference())")
XCTAssertTrue(aucklandOperations.timeDifference() == ", 21 hours ahead", "Difference was unexpectedly: \(aucklandOperations.timeDifference())")
XCTAssertTrue(aucklandOperations.timeDifference() == ", 19 hours ahead", "Difference was unexpectedly: \(aucklandOperations.timeDifference())")
XCTAssertTrue(omahaOperations.timeDifference() == ", 2 hours ahead", "Difference was unexpectedly: \(omahaOperations.timeDifference())")
}

24
Clocker/Events and Reminders/CalendarHandler.swift

@ -20,7 +20,7 @@ extension EventCenter {
var sourcesAndCalendars: [Any] = []
// Fetch array of user's calendars sorted first by source title and then by calendar title
let calendars = store.calendars(for: .event).sorted { (cal1, cal2) -> Bool in
let calendars = eventStore.calendars(for: .event).sorted { (cal1, cal2) -> Bool in
if cal1.source.sourceIdentifier == cal2.source.sourceIdentifier {
return cal1.title < cal2.title
@ -109,8 +109,16 @@ extension EventCenter {
return filteredAllDayEvent?.event
}
private func initializeStoreIfNeccesary() {
if eventStore == nil {
eventStore = EKEventStore()
}
}
func requestAccess(to entity: EKEntityType, completionHandler: @escaping (_ granted: Bool) -> Void) {
store.requestAccess(to: entity) { [weak self] granted, _ in
initializeStoreIfNeccesary()
eventStore.requestAccess(to: entity) { [weak self] granted, _ in
// On successful granting of calendar permission, we default to showing events from all calendars
if let self = self, entity == .event, granted {
@ -161,7 +169,7 @@ extension EventCenter {
}
func retrieveAllCalendarIdentifiers() -> [String] {
return store.calendars(for: .event).map { (calendar) -> String in
return eventStore.calendars(for: .event).map { (calendar) -> String in
calendar.calendarIdentifier
}
}
@ -193,19 +201,21 @@ extension EventCenter {
return
}
initializeStoreIfNeccesary()
let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)
let startDate = createDateComponents(with: calendar, start)
let endDate = createDateComponents(with: calendar, end)
// Passing in nil for calendars to search all calendars
let predicate = store.predicateForEvents(withStart: startDate,
end: endDate,
calendars: nil)
let predicate = eventStore.predicateForEvents(withStart: startDate,
end: endDate,
calendars: nil)
var eventsForDateMapper: [Date: [EventInfo]] = [:]
let events = store.events(matching: predicate)
let events = eventStore.events(matching: predicate)
// Populate our cache with events that match our startDate and endDate.
// We map eachDate to array of events happening on that day

2
Clocker/Events and Reminders/EventCenter.swift

@ -6,7 +6,7 @@ import EventKit
class EventCenter: NSObject {
private static var shared = EventCenter()
let store = EKEventStore()
var eventStore: EKEventStore!
var calendar: EKCalendar?

12
Clocker/Events and Reminders/RemindersHandler.swift

@ -7,7 +7,7 @@ extension EventCenter {
private func retrieveCalendar() -> EKCalendar? {
if calendar == nil {
let calendars = store.calendars(for: .reminder)
let calendars = eventStore.calendars(for: .reminder)
let calendarTitle = "Clocker Reminders"
let predicate = NSPredicate(format: "title matches %@", calendarTitle)
let filtered = calendars.filter { predicate.evaluate(with: $0) }
@ -15,14 +15,14 @@ extension EventCenter {
if !filtered.isEmpty {
calendar = filtered.first
} else {
calendar = EKCalendar(for: .reminder, eventStore: store)
calendar = EKCalendar(for: .reminder, eventStore: eventStore)
calendar?.title = "Clocker Reminders"
calendar?.source = store.defaultCalendarForNewReminders()?.source
calendar?.source = eventStore.defaultCalendarForNewReminders()?.source
guard let calendar = calendar else { return nil }
do {
try store.saveCalendar(calendar, commit: true)
try eventStore.saveCalendar(calendar, commit: true)
} catch {
assertionFailure("Unable to store calendar")
}
@ -61,7 +61,7 @@ extension EventCenter {
from: reminderDate)) else { return false }
reminderComponents.timeZone = TimeZone(identifier: timezone)
let reminderEvent = EKReminder(eventStore: store)
let reminderEvent = EKReminder(eventStore: eventStore)
reminderEvent.calendar = retrieveCalendar()
reminderEvent.title = "\(title) - Clocker"
reminderEvent.startDateComponents = reminderComponents
@ -72,7 +72,7 @@ extension EventCenter {
// Commit the event
do {
try store.save(reminderEvent, commit: true)
try eventStore.save(reminderEvent, commit: true)
} catch {
Logger.log(object: ["Error": error.localizedDescription],
for: "Error saving reminder")

14
Clocker/Menu Bar/StatusContainerView.swift

@ -125,10 +125,24 @@ class StatusContainerView: NSView {
assertionFailure("Subviews count should > 0")
}
// See if frame's width needs any adjustment
var newWidth: CGFloat = 0
subviews.forEach {
if let statusItem = $0 as? StatusItemView {
// 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.updateTimeInMenubar()
}
}
if newWidth != frame.size.width {
print("Correcting our width to \(newWidth) and the previous width was \(frame.size.width)")
frame = CGRect(x: frame.origin.x, y: frame.origin.y, width: newWidth, height: frame.size.height)
}
}
}

3
Clocker/Menu Bar/StatusItemHandler.swift

@ -35,9 +35,6 @@ class StatusItemHandler: NSObject {
// TODO: Make sure it's set just once.
private var currentState: MenubarState = .standardText {
didSet {
if oldValue == currentState {
assert(oldValue == currentState, "We have the same status bar state")
}
// Do some cleanup
switch oldValue {
case .compactText:

87
Clocker/Onboarding/Onboarding.storyboard

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="fde-UX-327">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="fde-UX-327">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@ -119,7 +119,7 @@ DQ
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="ClockerIcon-512" id="R28-eL-ofd"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Dc6-Gx-aw1">
<rect key="frame" x="8" y="101" width="420" height="31"/>
<rect key="frame" x="8" y="116" width="420" height="25"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" placeholderString="Accessory Label" id="IZg-bl-Xko">
<font key="font" size="18" name="Avenir-Light"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -127,7 +127,7 @@ DQ
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3qt-6h-o21">
<rect key="frame" x="3" y="149" width="430" height="47"/>
<rect key="frame" x="3" y="158" width="430" height="38"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" placeholderString="App Name" id="vvz-nI-aO6">
<font key="font" size="28" name="Avenir-Light"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -164,7 +164,7 @@ DQ
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="N6Z-mh-pET">
<rect key="frame" x="18" y="-18" width="400" height="23"/>
<rect key="frame" x="18" y="1" width="400" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="lMj-6p-4uB">
<font key="font" size="13" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -172,10 +172,10 @@ DQ
</textFieldCell>
</textField>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="mF9-1w-sxR">
<rect key="frame" x="20" y="165" width="396" height="100"/>
<rect key="frame" x="20" y="179" width="396" height="100"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="Lef-GT-zuM">
<rect key="frame" x="8" y="67" width="157" height="23"/>
<rect key="frame" x="8" y="72" width="157" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" placeholderString="Reminders Access Header" id="QiB-Um-yjg">
<font key="font" size="13" name="Avenir-Roman"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -183,7 +183,7 @@ DQ
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="O0s-Bu-IPq">
<rect key="frame" x="303" y="59" width="79" height="32"/>
<rect key="frame" x="303" y="62" width="79" height="32"/>
<buttonCell key="cell" type="push" title="Action" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="BW3-qu-NiR">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -193,7 +193,7 @@ DQ
</connections>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="gHR-Pd-9pP">
<rect key="frame" x="8" y="5" width="370" height="47"/>
<rect key="frame" x="8" y="5" width="370" height="52"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" placeholderString="Reminder Access Detail" id="zbc-CH-UBI">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -201,7 +201,7 @@ DQ
</textFieldCell>
</textField>
<progressIndicator wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="Zhi-9z-C2u">
<rect key="frame" x="253" y="69" width="16" height="16"/>
<rect key="frame" x="253" y="71" width="16" height="16"/>
</progressIndicator>
</subviews>
<constraints>
@ -219,10 +219,10 @@ DQ
</constraints>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="4eB-eD-0jK">
<rect key="frame" x="20" y="25" width="396" height="100"/>
<rect key="frame" x="20" y="39" width="396" height="100"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="noJ-fx-c1b">
<rect key="frame" x="8" y="53" width="148" height="37"/>
<rect key="frame" x="8" y="48" width="148" height="42"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" placeholderString="Calendar Access Header" id="cXW-N9-WyD">
<font key="font" size="13" name="Avenir-Roman"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -230,7 +230,7 @@ DQ
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="749" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="wcB-cI-R4k">
<rect key="frame" x="8" y="20" width="370" height="23"/>
<rect key="frame" x="8" y="20" width="370" height="18"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="leO-6q-mRB">
<font key="font" size="13" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -238,7 +238,7 @@ DQ
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="DgE-EN-bNM">
<rect key="frame" x="8" y="10" width="380" height="33"/>
<rect key="frame" x="8" y="10" width="380" height="28"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" placeholderString="Calendar Access Detail" id="RpL-I6-iJq">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -246,7 +246,7 @@ DQ
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dI2-oA-MBA">
<rect key="frame" x="303" y="54" width="79" height="32"/>
<rect key="frame" x="303" y="52" width="79" height="32"/>
<buttonCell key="cell" type="push" title="Action" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="i5r-db-Pnw">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -256,7 +256,7 @@ DQ
</connections>
</button>
<progressIndicator wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="0GH-vY-2Du">
<rect key="frame" x="253" y="64" width="16" height="16"/>
<rect key="frame" x="253" y="61" width="16" height="16"/>
</progressIndicator>
</subviews>
<constraints>
@ -286,7 +286,7 @@ DQ
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="ClockerIcon-512" id="Ykz-ej-1Nf"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iMf-Uy-zAf">
<rect key="frame" x="120" y="310" width="308" height="20"/>
<rect key="frame" x="120" y="324" width="308" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" placeholderString="Onboarding Info" id="MOO-BA-qzM">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -294,7 +294,7 @@ DQ
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pC3-D3-DSa">
<rect key="frame" x="118" y="325" width="203" height="55"/>
<rect key="frame" x="118" y="335" width="203" height="45"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" placeholderString="Screen Name" id="o72-Yp-qjT">
<font key="font" size="33" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -358,7 +358,7 @@ DQ
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="ClockerIcon-512" id="p3m-Oi-4D1"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OpV-ID-Ygr">
<rect key="frame" x="120" y="310" width="94" height="20"/>
<rect key="frame" x="120" y="324" width="94" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" placeholderString="Onboarding Info" id="Y20-SO-sAO">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -366,7 +366,7 @@ DQ
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="70Q-lk-Lwh">
<rect key="frame" x="118" y="325" width="203" height="55"/>
<rect key="frame" x="118" y="335" width="203" height="45"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" placeholderString="Screen Name" id="L5w-Cd-KTt">
<font key="font" size="33" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -374,7 +374,7 @@ DQ
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hLN-Aq-g8b">
<rect key="frame" x="120" y="247" width="298" height="23"/>
<rect key="frame" x="120" y="266" width="298" height="18"/>
<textFieldCell key="cell" lineBreakMode="clipping" placeholderString="Accessory Label" id="N7I-qA-txi">
<font key="font" size="13" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -382,7 +382,7 @@ DQ
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mDt-zc-oSU">
<rect key="frame" x="120" y="34" width="298" height="20"/>
<rect key="frame" x="120" y="34" width="298" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" placeholderString="Alternate Way Description" id="TQL-aE-8L2">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -433,7 +433,7 @@ DQ
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="ClockerIcon-512" id="bjq-tD-CZ4"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2ra-RP-SYR">
<rect key="frame" x="120" y="297" width="94" height="20"/>
<rect key="frame" x="120" y="311" width="94" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" placeholderString="Onboarding Info" id="SIV-aM-Wjg">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -441,7 +441,7 @@ DQ
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hqW-RG-UOt">
<rect key="frame" x="118" y="312" width="203" height="55"/>
<rect key="frame" x="118" y="322" width="203" height="45"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" placeholderString="Screen Name" id="QDu-mo-gtb">
<font key="font" size="33" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -458,26 +458,23 @@ DQ
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
<connections>
<action selector="search:" target="bMm-q2-fpd" id="oHC-re-vql"/>
</connections>
<accessibility identifier="searchField"/>
</searchField>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="35" horizontalPageScroll="10" verticalLineScroll="35" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RGd-Ev-FdZ">
<rect key="frame" x="20" y="49" width="396" height="160"/>
<clipView key="contentView" id="XpR-1t-AQy">
<clipView key="contentView" ambiguous="YES" id="XpR-1t-AQy">
<rect key="frame" x="0.0" y="0.0" width="396" height="160"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowHeight="33" rowSizeStyle="automatic" viewBased="YES" id="30y-X6-i7I">
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowHeight="33" rowSizeStyle="automatic" viewBased="YES" id="30y-X6-i7I">
<rect key="frame" x="0.0" y="0.0" width="396" height="160"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="393" minWidth="40" maxWidth="1000" id="2gZ-a7-gsB">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -488,12 +485,12 @@ DQ
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="resultHeaderCellView" id="58e-cL-Nln" customClass="ResultSectionHeaderTableViewCell" customModule="Clocker" customModuleProvider="target">
<tableCellView identifier="resultHeaderCellView" misplaced="YES" id="58e-cL-Nln" customClass="ResultSectionHeaderTableViewCell" customModule="Clocker" customModuleProvider="target">
<rect key="frame" x="1" y="1" width="393" height="23"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="ceH-HF-rVw">
<rect key="frame" x="-2" y="0.0" width="87" height="23"/>
<rect key="frame" x="-2" y="0.0" width="87" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="left" title="Section Name" placeholderString="Section Name" id="zKt-LI-GWL">
<font key="font" size="13" name="Avenir-Medium"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -511,12 +508,12 @@ DQ
<outlet property="headerLabel" destination="ceH-HF-rVw" id="ngR-Ih-1lh"/>
</connections>
</tableCellView>
<tableCellView identifier="resultCellView" id="Et0-Ex-6mu" customClass="ResultTableViewCell" customModule="Clocker" customModuleProvider="target">
<tableCellView identifier="resultCellView" misplaced="YES" id="Et0-Ex-6mu" customClass="ResultTableViewCell" customModule="Clocker" customModuleProvider="target">
<rect key="frame" x="1" y="26" width="393" height="33"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="73t-th-Wh0">
<rect key="frame" x="-2" y="0.0" width="392" height="33"/>
<rect key="frame" x="-2" y="0.0" width="392" height="27"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="left" title="Search Result Name" placeholderString="Search Result Name" id="gDs-r6-Az3">
<font key="font" size="20" name="Avenir-Light"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -552,16 +549,16 @@ DQ
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wDx-nO-z0M">
<rect key="frame" x="20" y="24" width="4" height="23"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wDx-nO-z0M">
<rect key="frame" x="20" y="29" width="4" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" id="c1w-j2-JT6">
<font key="font" size="13" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="51r-DX-fZU">
<rect key="frame" x="22" y="26" width="394" height="20"/>
<button verticalHuggingPriority="750" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="51r-DX-fZU">
<rect key="frame" x="22" y="30" width="394" height="16"/>
<buttonCell key="cell" type="bevel" title="UNDO" bezelStyle="rounded" alignment="left" imageScaling="proportionallyDown" inset="2" id="h5W-mQ-yIP">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="12" name="Avenir-Medium"/>
@ -621,7 +618,7 @@ DQ
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="ClockerIcon-512" id="5ri-Dg-fqE"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fEE-QM-0Pi">
<rect key="frame" x="120" y="297" width="94" height="20"/>
<rect key="frame" x="120" y="311" width="94" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" placeholderString="Onboarding Info" id="2qy-EI-Vw9">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -629,7 +626,7 @@ DQ
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rQQ-Iw-KIs">
<rect key="frame" x="118" y="312" width="203" height="55"/>
<rect key="frame" x="118" y="322" width="203" height="45"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" placeholderString="Screen Name" id="Dg6-xM-fYe">
<font key="font" size="33" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -637,11 +634,11 @@ DQ
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="nbC-4o-Xjf">
<rect key="frame" x="122" y="232" width="294" height="23"/>
<rect key="frame" x="122" y="246" width="294" height="23"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageAlignment="left" imageScaling="proportionallyDown" image="Dark Menubar" id="cZ2-x0-bJ2"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="kMo-BE-OAn">
<rect key="frame" x="120" y="172" width="298" height="20"/>
<rect key="frame" x="120" y="190" width="298" height="16"/>
<textFieldCell key="cell" selectable="YES" title="Multiline Label" id="M4F-nv-Eyo">
<font key="font" size="12" name="Avenir-Book"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -649,7 +646,7 @@ DQ
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6WD-GP-iz1">
<rect key="frame" x="122" y="122" width="288" height="22"/>
<rect key="frame" x="122" y="140" width="288" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="OvB-hh-3zl"/>
</constraints>
@ -660,7 +657,7 @@ DQ
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qLP-tx-m41" customClass="UnderlinedButton" customModule="Clocker" customModuleProvider="target">
<rect key="frame" x="117" y="84" width="293" height="15"/>
<rect key="frame" x="117" y="103" width="293" height="14"/>
<buttonCell key="cell" type="bevel" bezelStyle="rounded" alignment="left" imageScaling="proportionallyDown" inset="2" id="o87-us-e82">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Avenir-Book"/>

72
Clocker/Onboarding/OnboardingSearchController.swift

@ -20,12 +20,23 @@ class OnboardingSearchController: NSViewController {
private var dataTask: URLSessionDataTask? = .none
private var themeDidChangeNotification: NSObjectProtocol?
private var geocodingKey: String = {
guard let path = Bundle.main.path(forResource: "Keys", ofType: "plist"),
let dictionary = NSDictionary(contentsOfFile: path),
let apiKey = dictionary["GeocodingKey"] as? String else {
assertionFailure("Unable to find the API key")
return ""
}
return apiKey
}()
override func viewDidLoad() {
super.viewDidLoad()
view.wantsLayer = true
resultsTableView.delegate = self
resultsTableView.setAccessibility("ResultsTableView")
resultsTableView.dataSource = self
resultsTableView.target = self
resultsTableView.doubleAction = #selector(doubleClickAction(_:))
@ -43,6 +54,7 @@ class OnboardingSearchController: NSViewController {
let attributes = [NSAttributedString.Key.foregroundColor: NSColor.linkColor,
NSAttributedString.Key.font: font]
undoButton.attributedTitle = NSAttributedString(string: "UNDO", attributes: attributes)
undoButton.setAccessibility("UndoButton")
}
setupUndoButton()
@ -144,7 +156,7 @@ class OnboardingSearchController: NSViewController {
let tuple = "\(latitude),\(longitude)"
let timeStamp = Date().timeIntervalSince1970
let urlString = "https://maps.googleapis.com/maps/api/timezone/json?location=\(tuple)&timestamp=\(timeStamp)&key=\(CLGeocodingKey)"
let urlString = "https://maps.googleapis.com/maps/api/timezone/json?location=\(tuple)&timestamp=\(timeStamp)&key=\(geocodingKey)"
NetworkManager.task(with: urlString) { [weak self] response, error in
@ -211,7 +223,9 @@ class OnboardingSearchController: NSViewController {
appName.stringValue = "Quick Add Locations".localized()
onboardingTypeLabel.stringValue = "More search options in Clocker Preferences.".localized()
setInfoLabel(CLEmptyString)
searchBar.placeholderString = "Enter 3 or more characters for locations you'll like to add".localized()
searchBar.placeholderString = "Press Enter to Search!"
searchBar.delegate = self
searchBar.setAccessibility("MainSearchField")
resultsTableView.backgroundColor = Themer.shared().mainBackgroundColor()
resultsTableView.enclosingScrollView?.backgroundColor = Themer.shared().mainBackgroundColor()
@ -243,7 +257,14 @@ class OnboardingSearchController: NSViewController {
}
NSObject.cancelPreviousPerformRequests(withTarget: self)
perform(#selector(OnboardingSearchController.actualSearch), with: nil, afterDelay: 0.5)
perform(#selector(OnboardingSearchController.actualSearch), with: nil, afterDelay: 0.2)
}
fileprivate func resetIfNeccesary(_ searchString: String) {
if searchString.isEmpty {
resetSearchView()
setInfoLabel(CLEmptyString)
}
}
@objc func actualSearch() {
@ -260,10 +281,11 @@ class OnboardingSearchController: NSViewController {
searchString = words.joined(separator: CLEmptyString)
if searchString.count < 3 {
resetIfNeccesary(searchString)
return
}
let urlString = "https://maps.googleapis.com/maps/api/geocode/json?address=\(searchString)&key=\(CLGeocodingKey)&language=\(userPreferredLanguage)"
let urlString = "https://maps.googleapis.com/maps/api/geocode/json?address=\(searchString)&key=\(geocodingKey)&language=\(userPreferredLanguage)"
dataTask = NetworkManager.task(with: urlString,
completionHandler: { [weak self] response, error in
@ -356,7 +378,7 @@ class OnboardingSearchController: NSViewController {
results = []
resultsTableView.reloadData()
searchBar.stringValue = CLEmptyString
searchBar.placeholderString = placeholders.randomElement()
searchBar.placeholderString = "Press Enter to Search"
}
@IBAction func undoAction(_: Any) {
@ -373,7 +395,7 @@ extension OnboardingSearchController: NSTableViewDataSource {
func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? {
if let result = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "resultCellView"), owner: self) as? ResultTableViewCell, row >= 0, row < results.count {
let currentTimezone = results[row]
result.result.stringValue = currentTimezone.formattedAddress ?? "Place Name"
result.result.stringValue = " \(currentTimezone.formattedAddress ?? "Place Name")"
result.result.textColor = Themer.shared().mainTextColor()
return result
}
@ -394,12 +416,50 @@ extension OnboardingSearchController: NSTableViewDelegate {
func tableView(_: NSTableView, shouldSelectRow row: Int) -> Bool {
return results.isEmpty ? row != 0 : true
}
func tableView(_: NSTableView, rowViewForRow _: Int) -> NSTableRowView? {
return OnboardingSelectionTableRowView()
}
}
class ResultSectionHeaderTableViewCell: NSTableCellView {
@IBOutlet var headerLabel: NSTextField!
}
class OnboardingSelectionTableRowView: NSTableRowView {
override func drawSelection(in _: NSRect) {
if selectionHighlightStyle != .none {
let selectionRect = NSInsetRect(bounds, 1, 1)
NSColor(calibratedWhite: 0.4, alpha: 1).setStroke()
NSColor(calibratedWhite: 0.4, alpha: 1).setFill()
let selectionPath = NSBezierPath(roundedRect: selectionRect, xRadius: 6, yRadius: 6)
selectionPath.fill()
selectionPath.stroke()
}
}
}
class ResultTableViewCell: NSTableCellView {
@IBOutlet var result: NSTextField!
}
extension OnboardingSearchController: NSSearchFieldDelegate {
func control(_ control: NSControl, textView _: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
guard let searchField = control as? NSSearchField else {
return false
}
if commandSelector == #selector(NSResponder.insertNewline(_:)) {
self.search(searchField)
return true
} else if commandSelector == #selector(NSResponder.deleteForward(_:)) || commandSelector == #selector(NSResponder.deleteBackward(_:)) {
// Handle DELETE key
self.search(searchField)
return false
}
print("Not Handled")
// return true if the action was handled; otherwise false
return false
}
}

1
Clocker/Overall App/Strings.swift

@ -37,4 +37,3 @@ let CLDefaultMenubarMode = "com.abhishek.shouldDefaultToCompactMode"
let CLInstallHomeIndicatorObject = "installHomeIndicatorObject"
let CLDefaultThemeOnMojave = "com.abhishek.defaultHasBeenSetOnMacOsMojave"
let CLSwitchToCompactModeAlert = "com.abhishek.switchToCompactMode"
let CLGeocodingKey = "AIzaSyCyf2knCi6KiKuDJLYDBD3Odq5dt4c-_KI"

14
Clocker/Panel/Data Layer/TimezoneDataOperations.swift

@ -138,16 +138,20 @@ extension TimezoneDataOperations {
}
func date(with sliderValue: Int, displayType: CLDateDisplayType) -> String {
var currentCalendar = Calendar(identifier: .gregorian)
currentCalendar.locale = Locale.autoupdatingCurrent
let convertedDate = timezoneDate(with: sliderValue, currentCalendar)
guard let relativeDayPreference = DataStore.shared().retrieve(key: CLRelativeDateKey) as? NSNumber else {
assertionFailure("Data was unexpectedly nil")
return CLEmptyString
}
if relativeDayPreference.intValue == 3 {
return CLEmptyString
}
var currentCalendar = Calendar(identifier: .gregorian)
currentCalendar.locale = Locale.autoupdatingCurrent
let convertedDate = timezoneDate(with: sliderValue, currentCalendar)
if displayType == CLDateDisplayType.panelDisplay {
// Yesterday, tomorrow, etc
if relativeDayPreference.intValue == 0 {

10
Clocker/Panel/Notes Popover/NotesPopover.xib

@ -87,7 +87,7 @@
<constraint firstAttribute="height" constant="22" id="wGh-4g-gQ3"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="CUSTOMIZE" id="AWQ-XX-6Ai">
<font key="font" metaFont="palette"/>
<font key="font" metaFont="toolTip"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -202,8 +202,8 @@
</segmentedControl>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Wqz-cF-lhm">
<rect key="frame" x="18" y="35" width="274" height="14"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" title="TIMEZONE FORMAT" id="JnF-g8-GLM">
<font key="font" metaFont="palette"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" title="Timezone Format" id="JnF-g8-GLM">
<font key="font" metaFont="toolTip"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -239,8 +239,8 @@
</segmentedControl>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WVk-sH-CqF">
<rect key="frame" x="18" y="35" width="274" height="14"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" title="DISPLAY SECONDS" id="lCg-ZI-gIk">
<font key="font" metaFont="palette"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" title="Display Seconds" id="lCg-ZI-gIk">
<font key="font" metaFont="toolTip"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>

4
Clocker/Panel/PanelController.swift

@ -313,6 +313,10 @@ class PanelController: ParentPanelController {
}
override func showNotesPopover(forRow row: Int, relativeTo positioningRect: NSRect, andButton target: NSButton!) -> Bool {
if morePopover == nil {
morePopover = NSPopover()
}
guard let popover = morePopover else {
return false
}

26
Clocker/Panel/ParentPanelController.swift

@ -36,7 +36,7 @@ class ParentPanelController: NSWindowController {
private lazy var feedbackWindow: AppFeedbackWindowController = AppFeedbackWindowController.shared()
private var note: NotesPopover?
private var notePopover: NotesPopover?
private lazy var oneWindow: OneWindowController? = {
let preferencesStoryboard = NSStoryboard(name: "Preferences", bundle: nil)
@ -125,6 +125,8 @@ class ParentPanelController: NSWindowController {
super.awakeFromNib()
mainTableView.backgroundColor = NSColor.clear
mainTableView.selectionHighlightStyle = .none
mainTableView.enclosingScrollView?.hasVerticalScroller = false
let sharedThemer = Themer.shared()
shutdownButton.image = sharedThemer.shutdownImage()
@ -136,9 +138,6 @@ class ParentPanelController: NSWindowController {
upcomingView.setAccessibility("UpcomingEventView")
}
mainTableView.selectionHighlightStyle = .none
mainTableView.enclosingScrollView?.hasVerticalScroller = false
setupObservers()
updateReviewViewFontColor()
@ -571,8 +570,8 @@ class ParentPanelController: NSWindowController {
popover.animates = true
if note == nil {
note = NotesPopover(nibName: NSNib.Name.notesPopover, bundle: nil)
if notePopover == nil {
notePopover = NotesPopover(nibName: NSNib.Name.notesPopover, bundle: nil)
popover.behavior = .applicationDefined
popover.delegate = self
}
@ -585,12 +584,12 @@ class ParentPanelController: NSWindowController {
let current = defaults[correctRow]
if let model = TimezoneData.customObject(from: current) {
note?.setDataSource(data: model)
note?.setRow(row: correctRow)
note?.set(timezones: defaults)
notePopover?.setDataSource(data: model)
notePopover?.setRow(row: correctRow)
notePopover?.set(timezones: defaults)
popover.contentViewController = note
note?.set(with: popover)
popover.contentViewController = notePopover
notePopover?.set(with: popover)
return true
}
@ -790,9 +789,10 @@ class ParentPanelController: NSWindowController {
// If the popover is displayed, close it
// Called when preferences are going to be displayed!
func updatePopoverDisplayState() {
if note != nil, let isShown = note?.popover?.isShown, isShown {
note?.popover?.close()
if notePopover != nil, let isShown = notePopover?.popover?.isShown, isShown {
notePopover?.popover?.close()
}
morePopover = nil
}
// MARK: Review

31
Clocker/Panel/UI/FloatingWindow.xib

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -37,7 +37,7 @@
<windowCollectionBehavior key="collectionBehavior" moveToActiveSpace="YES" ignoresCycle="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="1000" y="379" width="350" height="460"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<value key="minSize" type="size" width="150" height="50"/>
<value key="maxSize" type="size" width="350" height="800"/>
<view key="contentView" id="qEx-SC-5Qd">
@ -55,14 +55,13 @@
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowHeight="80" viewBased="YES" id="3js-Fl-DdU" customClass="PanelTableView" customModule="Clocker" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="350" height="265"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="1"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="347" minWidth="303" maxWidth="1000" id="009-6N-KRz">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -78,7 +77,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="751" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="751" tag="100" preferredMaxLayoutWidth="150" translatesAutoresizingMaskIntoConstraints="NO" id="Nov-Lq-MHq">
<rect key="frame" x="33" y="45" width="178" height="25"/>
<rect key="frame" x="33" y="50" width="178" height="20"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" placeholderString="Timezone Name" id="NN9-pF-Axo">
<font key="font" size="15" name="Avenir-Light"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -86,19 +85,19 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="749" tag="102" preferredMaxLayoutWidth="72" translatesAutoresizingMaskIntoConstraints="NO" id="KEf-HK-1oi">
<rect key="frame" x="33" y="19" width="76" height="20"/>
<rect key="frame" x="33" y="24" width="76" height="20"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="72" identifier="width" id="4Qb-vu-Upf"/>
<constraint firstAttribute="height" constant="20" id="zbG-5a-kZz"/>
</constraints>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" state="on" placeholderString="Tomorrow" usesSingleLineMode="YES" id="MAt-8Z-HKJ">
<textFieldCell key="cell" sendsActionOnEndEditing="YES" state="on" usesSingleLineMode="YES" id="MAt-8Z-HKJ">
<font key="font" size="13" name="Avenir-Heavy"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="751" tag="101" preferredMaxLayoutWidth="110" translatesAutoresizingMaskIntoConstraints="NO" id="vG5-PS-a35">
<rect key="frame" x="215" y="33" width="114" height="37"/>
<rect key="frame" x="215" y="43" width="114" height="30"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="110" id="DyD-zQ-QUy"/>
</constraints>
@ -109,7 +108,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NYh-Nx-Z7X">
<rect key="frame" x="33" y="-3" width="296" height="22"/>
<rect key="frame" x="33" y="2" width="296" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="S78-bF-ZaL"/>
</constraints>
@ -120,7 +119,7 @@
</textFieldCell>
</textField>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fsY-Co-wno">
<rect key="frame" x="279" y="22" width="50" height="17"/>
<rect key="frame" x="279" y="27" width="50" height="17"/>
<constraints>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="59" id="UUh-5p-Mx2"/>
<constraint firstAttribute="height" constant="17" id="qB5-wj-dAu"/>
@ -132,7 +131,7 @@
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="WfK-L4-OKG">
<rect key="frame" x="259" y="21" width="20" height="20"/>
<rect key="frame" x="259" y="26" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="gDq-Uj-NYZ"/>
<constraint firstAttribute="height" constant="20" id="rIi-uA-qtx"/>
@ -180,21 +179,21 @@
</subviews>
<constraints>
<constraint firstItem="NYh-Nx-Z7X" firstAttribute="leading" secondItem="KEf-HK-1oi" secondAttribute="leading" id="1Of-Y1-aUQ"/>
<constraint firstItem="xGh-3b-9zf" firstAttribute="top" secondItem="Nov-Lq-MHq" secondAttribute="top" constant="5" id="7tt-Ds-vwo"/>
<constraint firstItem="NYh-Nx-Z7X" firstAttribute="top" secondItem="KEf-HK-1oi" secondAttribute="bottom" id="Ape-pV-pDJ"/>
<constraint firstItem="vG5-PS-a35" firstAttribute="leading" secondItem="Nov-Lq-MHq" secondAttribute="trailing" constant="8" id="CHc-la-Uaw"/>
<constraint firstItem="KEf-HK-1oi" firstAttribute="top" secondItem="Nov-Lq-MHq" secondAttribute="bottom" constant="6" id="EK0-Kr-ytA"/>
<constraint firstAttribute="trailing" secondItem="NYh-Nx-Z7X" secondAttribute="trailing" constant="20" id="HP8-8w-hBH"/>
<constraint firstItem="KEf-HK-1oi" firstAttribute="leading" secondItem="Nov-Lq-MHq" secondAttribute="leading" id="HmM-3n-rqp"/>
<constraint firstItem="xGh-3b-9zf" firstAttribute="top" secondItem="UES-Eo-BEf" secondAttribute="top" constant="15" id="Ktt-a9-Ez4"/>
<constraint firstAttribute="trailing" secondItem="vG5-PS-a35" secondAttribute="trailing" constant="20" id="Rcj-BS-Maj"/>
<constraint firstItem="Nov-Lq-MHq" firstAttribute="leading" secondItem="xGh-3b-9zf" secondAttribute="trailing" id="b1e-BW-AO3"/>
<constraint firstItem="WfK-L4-OKG" firstAttribute="centerY" secondItem="fsY-Co-wno" secondAttribute="centerY" id="bHQ-7c-DFh"/>
<constraint firstItem="fsY-Co-wno" firstAttribute="leading" secondItem="WfK-L4-OKG" secondAttribute="trailing" constant="2" id="biy-8h-kX4"/>
<constraint firstItem="vG5-PS-a35" firstAttribute="top" secondItem="Nov-Lq-MHq" secondAttribute="top" constant="-3" identifier="time-top-space" id="n2c-ZY-PFy"/>
<constraint firstItem="fsY-Co-wno" firstAttribute="top" secondItem="KEf-HK-1oi" secondAttribute="top" id="ndt-Tg-jLK"/>
<constraint firstItem="fsY-Co-wno" firstAttribute="trailing" secondItem="vG5-PS-a35" secondAttribute="trailing" id="sQc-aG-7Mo"/>
<constraint firstItem="Nov-Lq-MHq" firstAttribute="top" secondItem="UES-Eo-BEf" secondAttribute="top" constant="10" id="si0-gL-b4j"/>
<constraint firstItem="Nov-Lq-MHq" firstAttribute="top" secondItem="UES-Eo-BEf" secondAttribute="top" constant="10" identifier="custom-name-top-space" id="si0-gL-b4j"/>
<constraint firstItem="xGh-3b-9zf" firstAttribute="leading" secondItem="UES-Eo-BEf" secondAttribute="leading" constant="5" id="w6E-p7-9te"/>
<constraint firstItem="vG5-PS-a35" firstAttribute="top" secondItem="UES-Eo-BEf" secondAttribute="top" constant="10" id="zlT-zp-59t"/>
</constraints>
<connections>
<outlet property="currentLocationIndicator" destination="k4t-Nn-Fzn" id="cUu-XI-fvJ"/>
@ -259,7 +258,6 @@
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" fixedFrame="YES" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Y83-Ew-CDw">
<rect key="frame" x="80" y="30" width="185" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" preferredMaxLayoutWidth="185" translatesAutoresizingMaskIntoConstraints="NO" id="DHg-ca-UOi">
<rect key="frame" x="-2" y="0.0" width="189" height="20"/>
@ -283,7 +281,6 @@
</stackView>
<stackView distribution="fillEqually" orientation="horizontal" alignment="top" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" fixedFrame="YES" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xts-eA-jvq">
<rect key="frame" x="75" y="4" width="200" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8oB-ID-Dka">
<rect key="frame" x="-6" y="-7" width="108" height="32"/>

53
Clocker/Panel/UI/TimezoneCellView.swift

@ -50,8 +50,55 @@ class TimezoneCellView: NSTableCellView {
let width = relativeDateString.size(withAttributes: [NSAttributedString.Key.font: relativeFont]).width
let sunriseWidth = sunriseString.size(withAttributes: [NSAttributedString.Key.font: sunriseFont]).width
for constraint in relativeDate.constraints where constraint.identifier == "width" {
constraint.constant = width + 8
if relativeDateString.length > 0 {
if relativeDate.isHidden {
relativeDate.isHidden.toggle()
}
for constraint in relativeDate.constraints where constraint.identifier == "width" {
constraint.constant = width + 8
}
for constraint in constraints where constraint.identifier == "custom-name-top-space" {
if constraint.constant != 12 {
constraint.constant = 12
}
}
// If sunrise/sunset times are shown, adjust the time's top space to be closer to cell's top
if !sunriseSetTime.isHidden, relativeDate.isHidden {
for constraint in constraints where constraint.identifier == "time-top-space" {
if constraint.constant == -5.0 {
constraint.constant -= 10.0
}
}
} else {
for constraint in constraints where constraint.identifier == "time-top-space" {
if constraint.constant != -5.0 {
constraint.constant = -3.0
}
}
}
} else {
relativeDate.isHidden = true
for constraint in constraints where constraint.identifier == "custom-name-top-space" {
if constraint.constant == 12 {
constraint.constant += 15
}
}
if !sunriseSetTime.isHidden {
for constraint in constraints where constraint.identifier == "time-top-space" {
if constraint.constant == -5.0 {
constraint.constant -= 10.0
}
}
} else {
for constraint in constraints where constraint.identifier == "time-top-space" {
if constraint.constant != -5.0 {
constraint.constant = -5.0
}
}
}
}
for constraint in sunriseSetTime.constraints where constraint.identifier == "width" {
@ -123,7 +170,7 @@ class TimezoneCellView: NSTableCellView {
guard let panelTableView = searchView as? PanelTableView,
let enclosingScroller = panelTableView.enclosingScrollView
else {
assertionFailure("Unable to find panel table view in hierarchy")
// We might be coming from the preview tableview!
return
}

9
Clocker/Panel/UI/TimezoneDataSource.swift

@ -75,10 +75,15 @@ extension TimezoneDataSource: NSTableViewDataSource, NSTableViewDelegate {
return 100
}
if let userFontSize = DataStore.shared().retrieve(key: CLUserFontSizePreference) as? NSNumber, timezones.count > row {
if let userFontSize = DataStore.shared().retrieve(key: CLUserFontSizePreference) as? NSNumber, timezones.count > row, let relativeDisplay = DataStore.shared().retrieve(key: CLRelativeDateKey) as? NSNumber {
let model = timezones[row]
let rowHeight: Int = userFontSize == 4 ? 60 : 65
var rowHeight: Int = userFontSize == 4 ? 60 : 65
if relativeDisplay.intValue == 3 {
rowHeight -= 5
}
if let note = model.note, !note.isEmpty {
return CGFloat(rowHeight + userFontSize.intValue + 25)
}

90
Clocker/Preferences/Appearance/AppearanceViewController.swift

@ -15,6 +15,8 @@ class AppearanceViewController: ParentViewController {
private var themeDidChangeNotification: NSObjectProtocol?
private var previewTimezones: [TimezoneData] = []
override func viewDidLoad() {
super.viewDidLoad()
@ -40,7 +42,24 @@ class AppearanceViewController: ParentViewController {
self.setup()
self.animateBackgroundColorChange()
self.view.needsDisplay = true // Let's make the color change permanent.
self.previewPanelTableView.reloadData()
}
previewTimezones = [TimezoneData(with: ["customLabel": "San Francisco",
"formattedAddress": "San Francisco",
"place_id": "TestIdentifier",
"timezoneID": "America/Los_Angeles",
"nextUpdate": "",
"note": "Remember to finish setting up Clocker!",
"latitude": "37.7749295",
"longitude": "-122.4194155"])]
// Setup Preview Pane
previewPanelTableView.dataSource = self
previewPanelTableView.delegate = self
previewPanelTableView.reloadData()
previewPanelTableView.selectionHighlightStyle = .none
previewPanelTableView.enclosingScrollView?.hasVerticalScroller = false
}
deinit {
@ -80,7 +99,6 @@ class AppearanceViewController: ParentViewController {
updateMenubarControls(!shouldDisplayCompact)
}
@IBOutlet var headerLabel: NSTextField!
@IBOutlet var timeFormatLabel: NSTextField!
@IBOutlet var panelTheme: NSTextField!
@IBOutlet var dayDisplayOptionsLabel: NSTextField!
@ -96,8 +114,11 @@ class AppearanceViewController: ParentViewController {
@IBOutlet var appDisplayLabel: NSTextField!
@IBOutlet var menubarModeLabel: NSTextField!
// Panel Preview
@IBOutlet var previewPanelTableView: NSTableView!
private func setup() {
headerLabel.stringValue = "Main Panel Options".localized()
timeFormatLabel.stringValue = "Time Format".localized()
panelTheme.stringValue = "Panel Theme".localized()
dayDisplayOptionsLabel.stringValue = "Day Display Options".localized()
@ -109,10 +130,9 @@ class AppearanceViewController: ParentViewController {
includeDateLabel.stringValue = "Include Date".localized()
includeDayLabel.stringValue = "Include Day".localized()
includePlaceLabel.stringValue = "Include Place Name".localized()
menubarDisplayOptionsLabel.stringValue = "Menubar Display Options".localized()
menubarModeLabel.stringValue = "Menubar Mode".localized()
[headerLabel, timeFormatLabel, panelTheme,
[timeFormatLabel, panelTheme,
dayDisplayOptionsLabel, showSliderLabel, showSecondsLabel,
showSunriseLabel, largerTextLabel, futureSliderRangeLabel,
includeDayLabel, includeDateLabel, includePlaceLabel,
@ -131,6 +151,8 @@ class AppearanceViewController: ParentViewController {
refresh(panel: true, floating: true)
updateStatusItem()
previewPanelTableView.reloadData()
}
private var previousBackgroundColor: NSColor = NSColor.white
@ -185,6 +207,8 @@ class AppearanceViewController: ParentViewController {
Logger.log(object: ["dayPreference": selection], for: "RelativeDate")
refresh(panel: true, floating: true)
previewPanelTableView.reloadData()
}
@IBAction func showFutureSlider(_: Any) {
@ -193,6 +217,7 @@ class AppearanceViewController: ParentViewController {
@IBAction func showSunriseSunset(_ sender: NSSegmentedControl) {
Logger.log(object: ["Is It Displayed": sender.selectedSegment == 0 ? "YES" : "NO"], for: "Sunrise Sunset")
previewPanelTableView.reloadData()
}
@IBAction func displayTimeWithSeconds(_ sender: NSSegmentedControl) {
@ -204,6 +229,7 @@ class AppearanceViewController: ParentViewController {
}
updateStatusItem()
previewPanelTableView.reloadData()
}
@IBAction func changeAppDisplayOptions(_ sender: NSSegmentedControl) {
@ -291,4 +317,60 @@ class AppearanceViewController: ParentViewController {
private func updateMenubarControls(_ isEnabled: Bool) {
[includePlaceNameControl].forEach { $0?.isEnabled = isEnabled }
}
@IBAction func fontSliderChanged(_: Any) {
previewPanelTableView.reloadData()
}
}
extension AppearanceViewController: NSTableViewDataSource, NSTableViewDelegate {
func numberOfRows(in _: NSTableView) -> Int {
return 1
}
func tableView(_ tableView: NSTableView, viewFor _: NSTableColumn?, row: Int) -> NSView? {
guard !previewTimezones.isEmpty else {
return nil
}
guard let cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "previewTimezoneCell"), owner: self) as? TimezoneCellView else {
assertionFailure("Unable to create tableviewcell")
return NSView()
}
let currentModel = previewTimezones[row]
let operation = TimezoneDataOperations(with: currentModel)
cellView.sunriseSetTime.stringValue = operation.formattedSunriseTime(with: 0)
cellView.sunriseImage.image = currentModel.isSunriseOrSunset ? Themer.shared().sunriseImage() : Themer.shared().sunsetImage()
cellView.relativeDate.stringValue = operation.date(with: 0, displayType: .panelDisplay)
cellView.rowNumber = row
cellView.customName.stringValue = currentModel.formattedTimezoneLabel()
cellView.time.stringValue = operation.time(with: 0)
cellView.noteLabel.stringValue = currentModel.note ?? CLEmptyString
cellView.noteLabel.toolTip = currentModel.note ?? CLEmptyString
cellView.currentLocationIndicator.isHidden = !currentModel.isSystemTimezone
cellView.time.setAccessibilityIdentifier("ActualTime")
cellView.layout(with: currentModel)
cellView.setAccessibilityIdentifier(currentModel.formattedTimezoneLabel())
cellView.setAccessibilityLabel(currentModel.formattedTimezoneLabel())
return cellView
}
func tableView(_: NSTableView, heightOfRow row: Int) -> CGFloat {
if let userFontSize = DataStore.shared().retrieve(key: CLUserFontSizePreference) as? NSNumber, previewTimezones.count > row {
let model = previewTimezones[row]
let rowHeight: Int = userFontSize == 4 ? 60 : 65
if let note = model.note, !note.isEmpty {
return CGFloat(rowHeight + userFontSize.intValue + 25)
}
return CGFloat(rowHeight + (userFontSize.intValue * 2))
}
return 0
}
}

16
Clocker/Preferences/General/PreferencesViewController.swift

@ -37,6 +37,16 @@ class PreferencesViewController: ParentViewController {
NoTimezoneView(frame: tableview.frame)
}()
private var geocodingKey: String = {
guard let path = Bundle.main.path(forResource: "Keys", ofType: "plist"),
let dictionary = NSDictionary(contentsOfFile: path),
let apiKey = dictionary["GeocodingKey"] as? String else {
assertionFailure("Unable to find the API key")
return ""
}
return apiKey
}()
// Sorting
private var arePlacesSortedInAscendingOrder = false
private var arePlacesSortedInAscendingTimezoneOrder = false
@ -471,7 +481,7 @@ extension PreferencesViewController {
let words = searchString.components(separatedBy: CharacterSet.whitespacesAndNewlines)
searchString = words.joined(separator: CLEmptyString)
let url = "https://maps.googleapis.com/maps/api/geocode/json?address=\(searchString)&key=\(CLGeocodingKey)&language=\(userPreferredLanguage)"
let url = "https://maps.googleapis.com/maps/api/geocode/json?address=\(searchString)&key=\(geocodingKey)&language=\(userPreferredLanguage)"
return url
}
@ -564,7 +574,7 @@ extension PreferencesViewController {
let tuple = "\(latitude),\(longitude)"
let timeStamp = Date().timeIntervalSince1970
let urlString = "https://maps.googleapis.com/maps/api/timezone/json?location=\(tuple)&timestamp=\(timeStamp)&key=\(CLGeocodingKey)"
let urlString = "https://maps.googleapis.com/maps/api/timezone/json?location=\(tuple)&timestamp=\(timeStamp)&key=\(geocodingKey)"
NetworkManager.task(with: urlString) { [weak self] response, error in
@ -597,7 +607,7 @@ extension PreferencesViewController {
}
private func installTimezone(_ timezone: Timezone) {
guard let dataObject = self.searchResultsDataSource.filteredArray[self.availableTimezoneTableView.selectedRow % searchResultsDataSource.filteredArray.count] as? TimezoneData else {
guard let dataObject = searchResultsDataSource.filteredArray[availableTimezoneTableView.selectedRow % searchResultsDataSource.filteredArray.count] as? TimezoneData else {
assertionFailure("Data was unexpectedly nil")
return
}

1556
Clocker/Preferences/Preferences.storyboard

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save