├── .gitignore ├── CalendarQuickView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ │ └── Package.resolved │ └── xcuserdata │ │ └── michaelellis.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcshareddata │ └── xcschemes │ └── CalendarQuickView.xcscheme ├── CalendarQuickView ├── AppDelegate.swift ├── Base.lproj │ └── Main.storyboard ├── CalendarQuickView.entitlements ├── Info.plist ├── Managers │ ├── EventKitManager.swift │ └── LaunchAtLoginMonitor.swift ├── Models │ ├── CalendarViewModel.swift │ └── ColorStore.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── Views │ ├── .DS_Store │ ├── CalendarBody.swift │ ├── CalendarButton.swift │ ├── CalendarDay.swift │ ├── CalendarFooter.swift │ ├── CalendarHeader.swift │ ├── EventListView.swift │ ├── Settings │ │ ├── Colors │ │ │ ├── AppColors.swift │ │ │ └── ColorSettings.swift │ │ ├── EventSettings.swift │ │ ├── GeneralSettings.swift │ │ └── SettingsTabView.swift │ └── StatusBarCalendar.swift ├── Widget │ ├── CalendarWidget.swift │ └── CalendarWidgetProvider.swift └── en-US.lproj │ └── Main.strings ├── CalendarWidget ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ └── WidgetBackground.colorset │ │ └── Contents.json ├── CalendarWidget.entitlements ├── CalendarWidget.intentdefinition ├── CalendarWidget.swift ├── Info.plist └── WidgetCalendarView.swift ├── Gemfile ├── Gemfile.lock ├── README.md └── Shared ├── Assets.xcassets ├── AccentColor.colorset │ └── Contents.json ├── AppIcon.appiconset │ ├── 1024.png │ ├── 128.png │ ├── 16.png │ ├── 256.png │ ├── 32.png │ ├── 512.png │ ├── 64.png │ └── Contents.json └── Contents.json ├── Colors.xcassets ├── Contents.json ├── contrast.colorset │ └── Contents.json ├── coral.colorset │ └── Contents.json ├── jet.colorset │ └── Contents.json ├── jonquil.colorset │ └── Contents.json ├── lavendar.colorset │ └── Contents.json ├── mustard.colorset │ └── Contents.json ├── onyx.colorset │ └── Contents.json ├── pink.colorset │ └── Contents.json ├── rose.colorset │ └── Contents.json ├── sky.colorset │ └── Contents.json ├── stone.colorset │ └── Contents.json ├── tart.colorset │ └── Contents.json ├── vermillion.colorset │ └── Contents.json └── wood.colorset │ └── Contents.json ├── Extensions ├── Array-Extension.swift ├── Calendar-Extension.swift ├── Date-Extention.swift ├── DateFormatter-Extension.swift └── View-Extension.swift └── Utilities.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .xcuserstate 2 | .DS_Store 3 | .Trashes 4 | Thumbs.db 5 | *.xcuserstate 6 | CalendarQuickView.xcodeproj/xcuserdata/michaelellis.xcuserdatad/xcschemes/xcschememanagement.plist 7 | CalendarQuickView.xcodeproj/project.xcworkspace/xcuserdata/michaelellis.xcuserdatad/UserInterfaceState.xcuserstate 8 | CalendarQuickView.xcodeproj/project.xcworkspace/xcuserdata/michaelellis.xcuserdatad/UserInterfaceState.xcuserstate 9 | CalendarQuickView.xcodeproj/xcuserdata/michaelellis.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist 10 | CalendarQuickView.xcodeproj/project.xcworkspace/xcuserdata/michaelellis.xcuserdatad/UserInterfaceState.xcuserstate 11 | *.xcuserstate 12 | *.cer 13 | *.p12 14 | *.certSigningRequest 15 | *.mobileprovision 16 | *.provisionprofile 17 | *.zip 18 | fastlane_match_repo/ 19 | *.xcuserstate 20 | -------------------------------------------------------------------------------- /CalendarQuickView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2F0B26E12748B28B00F9D54E /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FDFB0872730241B00BE49CC /* WidgetKit.framework */; platformFilter = maccatalyst; }; 11 | 2F0B26E22748B28B00F9D54E /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FDFB0892730241C00BE49CC /* SwiftUI.framework */; platformFilter = maccatalyst; }; 12 | 2F0B26E52748B28B00F9D54E /* CalendarWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B26E42748B28B00F9D54E /* CalendarWidget.swift */; }; 13 | 2F0B26EB2748B28D00F9D54E /* CalendarWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B26E62748B28B00F9D54E /* CalendarWidget.intentdefinition */; }; 14 | 2F0B26EC2748B28D00F9D54E /* CalendarWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B26E62748B28B00F9D54E /* CalendarWidget.intentdefinition */; }; 15 | 2F0B26EF2748B28D00F9D54E /* CalendarWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2F0B26E02748B28B00F9D54E /* CalendarWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 16 | 2F0B26F32748B87A00F9D54E /* CalendarHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEE6DAB2736B8DD0081C4B8 /* CalendarHeader.swift */; }; 17 | 2F0B26F42748B87A00F9D54E /* CalendarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEE6DAF2736B9840081C4B8 /* CalendarButton.swift */; }; 18 | 2F0B26F52748B87A00F9D54E /* CalendarDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F1BAC00273E94B900C4708B /* CalendarDay.swift */; }; 19 | 2F0B26F62748B87A00F9D54E /* CalendarBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB94627322C7700DD0ACC /* CalendarBody.swift */; }; 20 | 2F0B26F82748B8D000F9D54E /* CalendarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB96A2736A5DD00DD0ACC /* CalendarViewModel.swift */; }; 21 | 2F0B26F92748B8D300F9D54E /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB95427347B0300DD0ACC /* Utilities.swift */; }; 22 | 2F0B26FA2748B8E400F9D54E /* Calendar-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FCC6CFD272C4801006D5C7D /* Calendar-Extension.swift */; }; 23 | 2F0B26FB2748B8E400F9D54E /* Array-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB94927342E4F00DD0ACC /* Array-Extension.swift */; }; 24 | 2F0B26FC2748B8E400F9D54E /* DateFormatter-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FCC6CFB272C47EB006D5C7D /* DateFormatter-Extension.swift */; }; 25 | 2F0B26FD2748B8E400F9D54E /* View-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F2D8A702738B658002C8EF0 /* View-Extension.swift */; }; 26 | 2F0B26FE2748B8E400F9D54E /* Date-Extention.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FCC6D05272C80C5006D5C7D /* Date-Extention.swift */; }; 27 | 2F0B27002748BA7100F9D54E /* WidgetCalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B26FF2748BA0400F9D54E /* WidgetCalendarView.swift */; }; 28 | 2F0B270327497B7300F9D54E /* ColorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B270227497B7300F9D54E /* ColorStore.swift */; }; 29 | 2F0B270427497BD400F9D54E /* ColorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F0B270227497B7300F9D54E /* ColorStore.swift */; }; 30 | 2F0B27052749899600F9D54E /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2F2D8A6E2738AF09002C8EF0 /* Colors.xcassets */; }; 31 | 2F0B27062749899900F9D54E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2FCC6CE6272C3A09006D5C7D /* Assets.xcassets */; }; 32 | 2F1765842793AA2A001D305E /* EventKitManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41EA3BBF27336B77001070CF /* EventKitManager.swift */; }; 33 | 2F1BAC01273E94BA00C4708B /* CalendarDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F1BAC00273E94B900C4708B /* CalendarDay.swift */; }; 34 | 2F2D8A6F2738AF09002C8EF0 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2F2D8A6E2738AF09002C8EF0 /* Colors.xcassets */; }; 35 | 2F2D8A712738B658002C8EF0 /* View-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F2D8A702738B658002C8EF0 /* View-Extension.swift */; }; 36 | 2F2D8A732738B8AA002C8EF0 /* AppColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F2D8A722738B8AA002C8EF0 /* AppColors.swift */; }; 37 | 2F42D4882748887300D77239 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F42D4872748887300D77239 /* ServiceManagement.framework */; }; 38 | 2F42D49227488BF900D77239 /* LaunchAtLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 2F42D49127488BF900D77239 /* LaunchAtLogin */; }; 39 | 2F6FB94727322C7700DD0ACC /* CalendarBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB94627322C7700DD0ACC /* CalendarBody.swift */; }; 40 | 2F6FB94A27342E4F00DD0ACC /* Array-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB94927342E4F00DD0ACC /* Array-Extension.swift */; }; 41 | 2F6FB95527347B0300DD0ACC /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB95427347B0300DD0ACC /* Utilities.swift */; }; 42 | 2F6FB95B27357DF800DD0ACC /* LaunchAtLoginMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB95A27357DF800DD0ACC /* LaunchAtLoginMonitor.swift */; }; 43 | 2F6FB95D27358A1900DD0ACC /* ColorSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB95C27358A1900DD0ACC /* ColorSettings.swift */; }; 44 | 2F6FB95F27358A7B00DD0ACC /* GeneralSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB95E27358A7B00DD0ACC /* GeneralSettings.swift */; }; 45 | 2F6FB96127358AAF00DD0ACC /* EventSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB96027358AAF00DD0ACC /* EventSettings.swift */; }; 46 | 2F6FB96B2736A5DD00DD0ACC /* CalendarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6FB96A2736A5DD00DD0ACC /* CalendarViewModel.swift */; }; 47 | 2FCC6CE3272C3A08006D5C7D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FCC6CE2272C3A08006D5C7D /* AppDelegate.swift */; }; 48 | 2FCC6CE7272C3A09006D5C7D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2FCC6CE6272C3A09006D5C7D /* Assets.xcassets */; }; 49 | 2FCC6CEA272C3A09006D5C7D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2FCC6CE9272C3A09006D5C7D /* Preview Assets.xcassets */; }; 50 | 2FCC6CFC272C47EB006D5C7D /* DateFormatter-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FCC6CFB272C47EB006D5C7D /* DateFormatter-Extension.swift */; }; 51 | 2FCC6CFE272C4801006D5C7D /* Calendar-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FCC6CFD272C4801006D5C7D /* Calendar-Extension.swift */; }; 52 | 2FCC6D06272C80C5006D5C7D /* Date-Extention.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FCC6D05272C80C5006D5C7D /* Date-Extention.swift */; }; 53 | 2FDFB09D2730B09800BE49CC /* SettingsTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FDFB09C2730B09800BE49CC /* SettingsTabView.swift */; }; 54 | 2FEE6DAD2736B8DD0081C4B8 /* CalendarHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEE6DAB2736B8DD0081C4B8 /* CalendarHeader.swift */; }; 55 | 2FEE6DAE2736B8DD0081C4B8 /* CalendarFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEE6DAC2736B8DD0081C4B8 /* CalendarFooter.swift */; }; 56 | 2FEE6DB02736B9840081C4B8 /* CalendarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEE6DAF2736B9840081C4B8 /* CalendarButton.swift */; }; 57 | 2FEF62902737510300F0A9DF /* StatusBarCalendar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEF628F2737510300F0A9DF /* StatusBarCalendar.swift */; }; 58 | 2FEF62942738024700F0A9DF /* EventListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEF62932738024700F0A9DF /* EventListView.swift */; }; 59 | 2FF55752273F641C000FD5C5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2FF55750273F641C000FD5C5 /* Main.storyboard */; }; 60 | 41EA3BC027336B77001070CF /* EventKitManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41EA3BBF27336B77001070CF /* EventKitManager.swift */; }; 61 | /* End PBXBuildFile section */ 62 | 63 | /* Begin PBXContainerItemProxy section */ 64 | 2F0B26ED2748B28D00F9D54E /* PBXContainerItemProxy */ = { 65 | isa = PBXContainerItemProxy; 66 | containerPortal = 2FCC6CD7272C3A08006D5C7D /* Project object */; 67 | proxyType = 1; 68 | remoteGlobalIDString = 2F0B26DF2748B28B00F9D54E; 69 | remoteInfo = CalendarWidgetExtension; 70 | }; 71 | 2F42D48C274888B500D77239 /* PBXContainerItemProxy */ = { 72 | isa = PBXContainerItemProxy; 73 | containerPortal = 2FCC6CD7272C3A08006D5C7D /* Project object */; 74 | proxyType = 1; 75 | remoteGlobalIDString = 2F42D4742748873600D77239; 76 | remoteInfo = LoginLauncher; 77 | }; 78 | 2F42D48E274888B800D77239 /* PBXContainerItemProxy */ = { 79 | isa = PBXContainerItemProxy; 80 | containerPortal = 2FCC6CD7272C3A08006D5C7D /* Project object */; 81 | proxyType = 1; 82 | remoteGlobalIDString = 2F42D4742748873600D77239; 83 | remoteInfo = LoginLauncher; 84 | }; 85 | /* End PBXContainerItemProxy section */ 86 | 87 | /* Begin PBXCopyFilesBuildPhase section */ 88 | 2FDFB0982730241F00BE49CC /* Embed App Extensions */ = { 89 | isa = PBXCopyFilesBuildPhase; 90 | buildActionMask = 2147483647; 91 | dstPath = ""; 92 | dstSubfolderSpec = 13; 93 | files = ( 94 | 2F0B26EF2748B28D00F9D54E /* CalendarWidgetExtension.appex in Embed App Extensions */, 95 | ); 96 | name = "Embed App Extensions"; 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | /* End PBXCopyFilesBuildPhase section */ 100 | 101 | /* Begin PBXFileReference section */ 102 | 2F07D87E274B28C900C5BBB0 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 103 | 2F0B26E02748B28B00F9D54E /* CalendarWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = CalendarWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 104 | 2F0B26E42748B28B00F9D54E /* CalendarWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarWidget.swift; sourceTree = ""; }; 105 | 2F0B26E62748B28B00F9D54E /* CalendarWidget.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = CalendarWidget.intentdefinition; sourceTree = ""; }; 106 | 2F0B26E92748B28D00F9D54E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 107 | 2F0B26EA2748B28D00F9D54E /* CalendarWidget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CalendarWidget.entitlements; sourceTree = ""; }; 108 | 2F0B26FF2748BA0400F9D54E /* WidgetCalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetCalendarView.swift; sourceTree = ""; }; 109 | 2F0B270227497B7300F9D54E /* ColorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorStore.swift; sourceTree = ""; }; 110 | 2F1BAC00273E94B900C4708B /* CalendarDay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarDay.swift; sourceTree = ""; }; 111 | 2F2D8A6E2738AF09002C8EF0 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; }; 112 | 2F2D8A702738B658002C8EF0 /* View-Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View-Extension.swift"; sourceTree = ""; }; 113 | 2F2D8A722738B8AA002C8EF0 /* AppColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppColors.swift; sourceTree = ""; }; 114 | 2F42D4872748887300D77239 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; }; 115 | 2F6FB94627322C7700DD0ACC /* CalendarBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarBody.swift; sourceTree = ""; }; 116 | 2F6FB94927342E4F00DD0ACC /* Array-Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array-Extension.swift"; sourceTree = ""; }; 117 | 2F6FB95427347B0300DD0ACC /* Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utilities.swift; sourceTree = ""; }; 118 | 2F6FB95A27357DF800DD0ACC /* LaunchAtLoginMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchAtLoginMonitor.swift; sourceTree = ""; }; 119 | 2F6FB95C27358A1900DD0ACC /* ColorSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorSettings.swift; sourceTree = ""; }; 120 | 2F6FB95E27358A7B00DD0ACC /* GeneralSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettings.swift; sourceTree = ""; }; 121 | 2F6FB96027358AAF00DD0ACC /* EventSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventSettings.swift; sourceTree = ""; }; 122 | 2F6FB96A2736A5DD00DD0ACC /* CalendarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarViewModel.swift; sourceTree = ""; }; 123 | 2FCC6CDF272C3A08006D5C7D /* CalendarQuickView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CalendarQuickView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 124 | 2FCC6CE2272C3A08006D5C7D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 125 | 2FCC6CE6272C3A09006D5C7D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 126 | 2FCC6CE9272C3A09006D5C7D /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 127 | 2FCC6CEE272C3A09006D5C7D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 128 | 2FCC6CEF272C3A09006D5C7D /* CalendarQuickView.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CalendarQuickView.entitlements; sourceTree = ""; }; 129 | 2FCC6CFB272C47EB006D5C7D /* DateFormatter-Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter-Extension.swift"; sourceTree = ""; }; 130 | 2FCC6CFD272C4801006D5C7D /* Calendar-Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Calendar-Extension.swift"; sourceTree = ""; }; 131 | 2FCC6D05272C80C5006D5C7D /* Date-Extention.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date-Extention.swift"; sourceTree = ""; }; 132 | 2FDFB0872730241B00BE49CC /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 133 | 2FDFB0892730241C00BE49CC /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; 134 | 2FDFB09C2730B09800BE49CC /* SettingsTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTabView.swift; sourceTree = ""; }; 135 | 2FEE6DAB2736B8DD0081C4B8 /* CalendarHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarHeader.swift; sourceTree = ""; }; 136 | 2FEE6DAC2736B8DD0081C4B8 /* CalendarFooter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarFooter.swift; sourceTree = ""; }; 137 | 2FEE6DAF2736B9840081C4B8 /* CalendarButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarButton.swift; sourceTree = ""; }; 138 | 2FEF628F2737510300F0A9DF /* StatusBarCalendar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusBarCalendar.swift; sourceTree = ""; }; 139 | 2FEF62932738024700F0A9DF /* EventListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventListView.swift; sourceTree = ""; }; 140 | 2FF55751273F641C000FD5C5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 141 | 2FF55753273F6562000FD5C5 /* en-US */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-US"; path = "en-US.lproj/Main.strings"; sourceTree = ""; }; 142 | 41EA3BBF27336B77001070CF /* EventKitManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventKitManager.swift; sourceTree = ""; }; 143 | /* End PBXFileReference section */ 144 | 145 | /* Begin PBXFrameworksBuildPhase section */ 146 | 2F0B26DD2748B28B00F9D54E /* Frameworks */ = { 147 | isa = PBXFrameworksBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | 2F0B26E22748B28B00F9D54E /* SwiftUI.framework in Frameworks */, 151 | 2F0B26E12748B28B00F9D54E /* WidgetKit.framework in Frameworks */, 152 | ); 153 | runOnlyForDeploymentPostprocessing = 0; 154 | }; 155 | 2FCC6CDC272C3A08006D5C7D /* Frameworks */ = { 156 | isa = PBXFrameworksBuildPhase; 157 | buildActionMask = 2147483647; 158 | files = ( 159 | 2F42D49227488BF900D77239 /* LaunchAtLogin in Frameworks */, 160 | 2F42D4882748887300D77239 /* ServiceManagement.framework in Frameworks */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | /* End PBXFrameworksBuildPhase section */ 165 | 166 | /* Begin PBXGroup section */ 167 | 2F0B26E32748B28B00F9D54E /* CalendarWidget */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 2F0B26E42748B28B00F9D54E /* CalendarWidget.swift */, 171 | 2F0B26FF2748BA0400F9D54E /* WidgetCalendarView.swift */, 172 | 2F0B26E62748B28B00F9D54E /* CalendarWidget.intentdefinition */, 173 | 2F0B26E92748B28D00F9D54E /* Info.plist */, 174 | 2F0B26EA2748B28D00F9D54E /* CalendarWidget.entitlements */, 175 | ); 176 | path = CalendarWidget; 177 | sourceTree = ""; 178 | }; 179 | 2F0B2701274934A200F9D54E /* Shared */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 2FCC6CE6272C3A09006D5C7D /* Assets.xcassets */, 183 | 2F2D8A6E2738AF09002C8EF0 /* Colors.xcassets */, 184 | 2F6FB95427347B0300DD0ACC /* Utilities.swift */, 185 | 2F6FB93527320EDC00DD0ACC /* Extensions */, 186 | ); 187 | path = Shared; 188 | sourceTree = ""; 189 | }; 190 | 2F1BABFE273E8C8300C4708B /* Models */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 2F6FB96A2736A5DD00DD0ACC /* CalendarViewModel.swift */, 194 | 2F0B270227497B7300F9D54E /* ColorStore.swift */, 195 | ); 196 | path = Models; 197 | sourceTree = ""; 198 | }; 199 | 2F1BABFF273E8C9000C4708B /* Managers */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 41EA3BBF27336B77001070CF /* EventKitManager.swift */, 203 | 2F6FB95A27357DF800DD0ACC /* LaunchAtLoginMonitor.swift */, 204 | ); 205 | path = Managers; 206 | sourceTree = ""; 207 | }; 208 | 2F6FB93527320EDC00DD0ACC /* Extensions */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | 2FCC6CFD272C4801006D5C7D /* Calendar-Extension.swift */, 212 | 2F6FB94927342E4F00DD0ACC /* Array-Extension.swift */, 213 | 2FCC6CFB272C47EB006D5C7D /* DateFormatter-Extension.swift */, 214 | 2F2D8A702738B658002C8EF0 /* View-Extension.swift */, 215 | 2FCC6D05272C80C5006D5C7D /* Date-Extention.swift */, 216 | ); 217 | path = Extensions; 218 | sourceTree = ""; 219 | }; 220 | 2F6FB93627320EEE00DD0ACC /* Views */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 2FEF628F2737510300F0A9DF /* StatusBarCalendar.swift */, 224 | 2FEE6DAB2736B8DD0081C4B8 /* CalendarHeader.swift */, 225 | 2FEE6DAF2736B9840081C4B8 /* CalendarButton.swift */, 226 | 2F6FB94627322C7700DD0ACC /* CalendarBody.swift */, 227 | 2F1BAC00273E94B900C4708B /* CalendarDay.swift */, 228 | 2FEF62932738024700F0A9DF /* EventListView.swift */, 229 | 2FEE6DAC2736B8DD0081C4B8 /* CalendarFooter.swift */, 230 | 2F6FB9622735953F00DD0ACC /* Settings */, 231 | ); 232 | path = Views; 233 | sourceTree = ""; 234 | }; 235 | 2F6FB9622735953F00DD0ACC /* Settings */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | 2FDFB09C2730B09800BE49CC /* SettingsTabView.swift */, 239 | 2F6FB95E27358A7B00DD0ACC /* GeneralSettings.swift */, 240 | 2FF5575627401753000FD5C5 /* Colors */, 241 | 2F6FB96027358AAF00DD0ACC /* EventSettings.swift */, 242 | ); 243 | path = Settings; 244 | sourceTree = ""; 245 | }; 246 | 2FCC6CD6272C3A08006D5C7D = { 247 | isa = PBXGroup; 248 | children = ( 249 | 2F07D87E274B28C900C5BBB0 /* README.md */, 250 | 2F0B2701274934A200F9D54E /* Shared */, 251 | 2FCC6CE1272C3A08006D5C7D /* CalendarQuickView */, 252 | 2F0B26E32748B28B00F9D54E /* CalendarWidget */, 253 | 2FDFB0862730241B00BE49CC /* Frameworks */, 254 | 2FCC6CE0272C3A08006D5C7D /* Products */, 255 | ); 256 | sourceTree = ""; 257 | }; 258 | 2FCC6CE0272C3A08006D5C7D /* Products */ = { 259 | isa = PBXGroup; 260 | children = ( 261 | 2FCC6CDF272C3A08006D5C7D /* CalendarQuickView.app */, 262 | 2F0B26E02748B28B00F9D54E /* CalendarWidgetExtension.appex */, 263 | ); 264 | name = Products; 265 | sourceTree = ""; 266 | }; 267 | 2FCC6CE1272C3A08006D5C7D /* CalendarQuickView */ = { 268 | isa = PBXGroup; 269 | children = ( 270 | 2FCC6CE2272C3A08006D5C7D /* AppDelegate.swift */, 271 | 2F1BABFF273E8C9000C4708B /* Managers */, 272 | 2F1BABFE273E8C8300C4708B /* Models */, 273 | 2F6FB93627320EEE00DD0ACC /* Views */, 274 | 2FF55750273F641C000FD5C5 /* Main.storyboard */, 275 | 2FCC6CEE272C3A09006D5C7D /* Info.plist */, 276 | 2FCC6CEF272C3A09006D5C7D /* CalendarQuickView.entitlements */, 277 | 2FCC6CE8272C3A09006D5C7D /* Preview Content */, 278 | ); 279 | path = CalendarQuickView; 280 | sourceTree = ""; 281 | }; 282 | 2FCC6CE8272C3A09006D5C7D /* Preview Content */ = { 283 | isa = PBXGroup; 284 | children = ( 285 | 2FCC6CE9272C3A09006D5C7D /* Preview Assets.xcassets */, 286 | ); 287 | path = "Preview Content"; 288 | sourceTree = ""; 289 | }; 290 | 2FDFB0862730241B00BE49CC /* Frameworks */ = { 291 | isa = PBXGroup; 292 | children = ( 293 | 2F42D4872748887300D77239 /* ServiceManagement.framework */, 294 | 2FDFB0872730241B00BE49CC /* WidgetKit.framework */, 295 | 2FDFB0892730241C00BE49CC /* SwiftUI.framework */, 296 | ); 297 | name = Frameworks; 298 | sourceTree = ""; 299 | }; 300 | 2FF5575627401753000FD5C5 /* Colors */ = { 301 | isa = PBXGroup; 302 | children = ( 303 | 2F6FB95C27358A1900DD0ACC /* ColorSettings.swift */, 304 | 2F2D8A722738B8AA002C8EF0 /* AppColors.swift */, 305 | ); 306 | path = Colors; 307 | sourceTree = ""; 308 | }; 309 | /* End PBXGroup section */ 310 | 311 | /* Begin PBXNativeTarget section */ 312 | 2F0B26DF2748B28B00F9D54E /* CalendarWidgetExtension */ = { 313 | isa = PBXNativeTarget; 314 | buildConfigurationList = 2F0B26F02748B28D00F9D54E /* Build configuration list for PBXNativeTarget "CalendarWidgetExtension" */; 315 | buildPhases = ( 316 | 2F0B26DC2748B28B00F9D54E /* Sources */, 317 | 2F0B26DD2748B28B00F9D54E /* Frameworks */, 318 | 2F0B26DE2748B28B00F9D54E /* Resources */, 319 | ); 320 | buildRules = ( 321 | ); 322 | dependencies = ( 323 | ); 324 | name = CalendarWidgetExtension; 325 | productName = CalendarWidgetExtension; 326 | productReference = 2F0B26E02748B28B00F9D54E /* CalendarWidgetExtension.appex */; 327 | productType = "com.apple.product-type.app-extension"; 328 | }; 329 | 2FCC6CDE272C3A08006D5C7D /* CalendarQuickView */ = { 330 | isa = PBXNativeTarget; 331 | buildConfigurationList = 2FCC6CF2272C3A09006D5C7D /* Build configuration list for PBXNativeTarget "CalendarQuickView" */; 332 | buildPhases = ( 333 | 2FCC6CDB272C3A08006D5C7D /* Sources */, 334 | 2FCC6CDC272C3A08006D5C7D /* Frameworks */, 335 | 2FCC6CDD272C3A08006D5C7D /* Resources */, 336 | 2FDFB0982730241F00BE49CC /* Embed App Extensions */, 337 | 2F42D49327488C4700D77239 /* Copy “Launch at Login Helper” */, 338 | ); 339 | buildRules = ( 340 | ); 341 | dependencies = ( 342 | 2F42D48D274888B500D77239 /* PBXTargetDependency */, 343 | 2F42D48F274888B800D77239 /* PBXTargetDependency */, 344 | 2F0B26EE2748B28D00F9D54E /* PBXTargetDependency */, 345 | ); 346 | name = CalendarQuickView; 347 | packageProductDependencies = ( 348 | 2F42D49127488BF900D77239 /* LaunchAtLogin */, 349 | ); 350 | productName = CalendarQuickView; 351 | productReference = 2FCC6CDF272C3A08006D5C7D /* CalendarQuickView.app */; 352 | productType = "com.apple.product-type.application"; 353 | }; 354 | /* End PBXNativeTarget section */ 355 | 356 | /* Begin PBXProject section */ 357 | 2FCC6CD7272C3A08006D5C7D /* Project object */ = { 358 | isa = PBXProject; 359 | attributes = { 360 | LastSwiftUpdateCheck = 1310; 361 | LastUpgradeCheck = 1310; 362 | TargetAttributes = { 363 | 2F0B26DF2748B28B00F9D54E = { 364 | CreatedOnToolsVersion = 13.1; 365 | }; 366 | 2FCC6CDE272C3A08006D5C7D = { 367 | CreatedOnToolsVersion = 12.5.1; 368 | }; 369 | }; 370 | }; 371 | buildConfigurationList = 2FCC6CDA272C3A08006D5C7D /* Build configuration list for PBXProject "CalendarQuickView" */; 372 | compatibilityVersion = "Xcode 9.3"; 373 | developmentRegion = en; 374 | hasScannedForEncodings = 0; 375 | knownRegions = ( 376 | en, 377 | Base, 378 | "en-US", 379 | ); 380 | mainGroup = 2FCC6CD6272C3A08006D5C7D; 381 | packageReferences = ( 382 | 2F42D49027488BF900D77239 /* XCRemoteSwiftPackageReference "LaunchAtLogin" */, 383 | ); 384 | productRefGroup = 2FCC6CE0272C3A08006D5C7D /* Products */; 385 | projectDirPath = ""; 386 | projectRoot = ""; 387 | targets = ( 388 | 2FCC6CDE272C3A08006D5C7D /* CalendarQuickView */, 389 | 2F0B26DF2748B28B00F9D54E /* CalendarWidgetExtension */, 390 | ); 391 | }; 392 | /* End PBXProject section */ 393 | 394 | /* Begin PBXResourcesBuildPhase section */ 395 | 2F0B26DE2748B28B00F9D54E /* Resources */ = { 396 | isa = PBXResourcesBuildPhase; 397 | buildActionMask = 2147483647; 398 | files = ( 399 | 2F0B27062749899900F9D54E /* Assets.xcassets in Resources */, 400 | 2F0B27052749899600F9D54E /* Colors.xcassets in Resources */, 401 | ); 402 | runOnlyForDeploymentPostprocessing = 0; 403 | }; 404 | 2FCC6CDD272C3A08006D5C7D /* Resources */ = { 405 | isa = PBXResourcesBuildPhase; 406 | buildActionMask = 2147483647; 407 | files = ( 408 | 2F2D8A6F2738AF09002C8EF0 /* Colors.xcassets in Resources */, 409 | 2FF55752273F641C000FD5C5 /* Main.storyboard in Resources */, 410 | 2FCC6CEA272C3A09006D5C7D /* Preview Assets.xcassets in Resources */, 411 | 2FCC6CE7272C3A09006D5C7D /* Assets.xcassets in Resources */, 412 | ); 413 | runOnlyForDeploymentPostprocessing = 0; 414 | }; 415 | /* End PBXResourcesBuildPhase section */ 416 | 417 | /* Begin PBXShellScriptBuildPhase section */ 418 | 2F42D49327488C4700D77239 /* Copy “Launch at Login Helper” */ = { 419 | isa = PBXShellScriptBuildPhase; 420 | buildActionMask = 2147483647; 421 | files = ( 422 | ); 423 | inputFileListPaths = ( 424 | ); 425 | inputPaths = ( 426 | ); 427 | name = "Copy “Launch at Login Helper”"; 428 | outputFileListPaths = ( 429 | ); 430 | outputPaths = ( 431 | ); 432 | runOnlyForDeploymentPostprocessing = 0; 433 | shellPath = /bin/sh; 434 | shellScript = "\"${BUILT_PRODUCTS_DIR}/LaunchAtLogin_LaunchAtLogin.bundle/Contents/Resources/copy-helper-swiftpm.sh\"\n"; 435 | }; 436 | /* End PBXShellScriptBuildPhase section */ 437 | 438 | /* Begin PBXSourcesBuildPhase section */ 439 | 2F0B26DC2748B28B00F9D54E /* Sources */ = { 440 | isa = PBXSourcesBuildPhase; 441 | buildActionMask = 2147483647; 442 | files = ( 443 | 2F0B26FE2748B8E400F9D54E /* Date-Extention.swift in Sources */, 444 | 2F0B27002748BA7100F9D54E /* WidgetCalendarView.swift in Sources */, 445 | 2F0B26FC2748B8E400F9D54E /* DateFormatter-Extension.swift in Sources */, 446 | 2F0B26EB2748B28D00F9D54E /* CalendarWidget.intentdefinition in Sources */, 447 | 2F0B26F42748B87A00F9D54E /* CalendarButton.swift in Sources */, 448 | 2F1765842793AA2A001D305E /* EventKitManager.swift in Sources */, 449 | 2F0B26E52748B28B00F9D54E /* CalendarWidget.swift in Sources */, 450 | 2F0B270427497BD400F9D54E /* ColorStore.swift in Sources */, 451 | 2F0B26FB2748B8E400F9D54E /* Array-Extension.swift in Sources */, 452 | 2F0B26F62748B87A00F9D54E /* CalendarBody.swift in Sources */, 453 | 2F0B26F52748B87A00F9D54E /* CalendarDay.swift in Sources */, 454 | 2F0B26F32748B87A00F9D54E /* CalendarHeader.swift in Sources */, 455 | 2F0B26FD2748B8E400F9D54E /* View-Extension.swift in Sources */, 456 | 2F0B26FA2748B8E400F9D54E /* Calendar-Extension.swift in Sources */, 457 | 2F0B26F92748B8D300F9D54E /* Utilities.swift in Sources */, 458 | 2F0B26F82748B8D000F9D54E /* CalendarViewModel.swift in Sources */, 459 | ); 460 | runOnlyForDeploymentPostprocessing = 0; 461 | }; 462 | 2FCC6CDB272C3A08006D5C7D /* Sources */ = { 463 | isa = PBXSourcesBuildPhase; 464 | buildActionMask = 2147483647; 465 | files = ( 466 | 2FCC6D06272C80C5006D5C7D /* Date-Extention.swift in Sources */, 467 | 2FCC6CFC272C47EB006D5C7D /* DateFormatter-Extension.swift in Sources */, 468 | 2FEE6DAE2736B8DD0081C4B8 /* CalendarFooter.swift in Sources */, 469 | 2F0B26EC2748B28D00F9D54E /* CalendarWidget.intentdefinition in Sources */, 470 | 2FDFB09D2730B09800BE49CC /* SettingsTabView.swift in Sources */, 471 | 2F1BAC01273E94BA00C4708B /* CalendarDay.swift in Sources */, 472 | 2F2D8A712738B658002C8EF0 /* View-Extension.swift in Sources */, 473 | 2FEE6DB02736B9840081C4B8 /* CalendarButton.swift in Sources */, 474 | 2F6FB94727322C7700DD0ACC /* CalendarBody.swift in Sources */, 475 | 2FEE6DAD2736B8DD0081C4B8 /* CalendarHeader.swift in Sources */, 476 | 2F6FB95527347B0300DD0ACC /* Utilities.swift in Sources */, 477 | 2F2D8A732738B8AA002C8EF0 /* AppColors.swift in Sources */, 478 | 2FCC6CFE272C4801006D5C7D /* Calendar-Extension.swift in Sources */, 479 | 2FEF62902737510300F0A9DF /* StatusBarCalendar.swift in Sources */, 480 | 2FEF62942738024700F0A9DF /* EventListView.swift in Sources */, 481 | 2F0B270327497B7300F9D54E /* ColorStore.swift in Sources */, 482 | 2F6FB96B2736A5DD00DD0ACC /* CalendarViewModel.swift in Sources */, 483 | 2F6FB96127358AAF00DD0ACC /* EventSettings.swift in Sources */, 484 | 41EA3BC027336B77001070CF /* EventKitManager.swift in Sources */, 485 | 2F6FB94A27342E4F00DD0ACC /* Array-Extension.swift in Sources */, 486 | 2F6FB95B27357DF800DD0ACC /* LaunchAtLoginMonitor.swift in Sources */, 487 | 2FCC6CE3272C3A08006D5C7D /* AppDelegate.swift in Sources */, 488 | 2F6FB95D27358A1900DD0ACC /* ColorSettings.swift in Sources */, 489 | 2F6FB95F27358A7B00DD0ACC /* GeneralSettings.swift in Sources */, 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | /* End PBXSourcesBuildPhase section */ 494 | 495 | /* Begin PBXTargetDependency section */ 496 | 2F0B26EE2748B28D00F9D54E /* PBXTargetDependency */ = { 497 | isa = PBXTargetDependency; 498 | target = 2F0B26DF2748B28B00F9D54E /* CalendarWidgetExtension */; 499 | targetProxy = 2F0B26ED2748B28D00F9D54E /* PBXContainerItemProxy */; 500 | }; 501 | 2F42D48D274888B500D77239 /* PBXTargetDependency */ = { 502 | isa = PBXTargetDependency; 503 | targetProxy = 2F42D48C274888B500D77239 /* PBXContainerItemProxy */; 504 | }; 505 | 2F42D48F274888B800D77239 /* PBXTargetDependency */ = { 506 | isa = PBXTargetDependency; 507 | targetProxy = 2F42D48E274888B800D77239 /* PBXContainerItemProxy */; 508 | }; 509 | /* End PBXTargetDependency section */ 510 | 511 | /* Begin PBXVariantGroup section */ 512 | 2FF55750273F641C000FD5C5 /* Main.storyboard */ = { 513 | isa = PBXVariantGroup; 514 | children = ( 515 | 2FF55751273F641C000FD5C5 /* Base */, 516 | 2FF55753273F6562000FD5C5 /* en-US */, 517 | ); 518 | name = Main.storyboard; 519 | sourceTree = ""; 520 | }; 521 | /* End PBXVariantGroup section */ 522 | 523 | /* Begin XCBuildConfiguration section */ 524 | 2F0B26F12748B28D00F9D54E /* Debug */ = { 525 | isa = XCBuildConfiguration; 526 | buildSettings = { 527 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 528 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 529 | ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; 530 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 531 | CODE_SIGN_ENTITLEMENTS = CalendarWidget/CalendarWidget.entitlements; 532 | CODE_SIGN_IDENTITY = "Apple Development"; 533 | CODE_SIGN_STYLE = Automatic; 534 | CURRENT_PROJECT_VERSION = 104; 535 | DEVELOPMENT_TEAM = KLQC884752; 536 | ENABLE_HARDENED_RUNTIME = YES; 537 | GENERATE_INFOPLIST_FILE = YES; 538 | INFOPLIST_FILE = CalendarWidget/Info.plist; 539 | INFOPLIST_KEY_CFBundleDisplayName = CalendarWidget; 540 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 541 | LD_RUNPATH_SEARCH_PATHS = ( 542 | "$(inherited)", 543 | "@executable_path/../Frameworks", 544 | "@executable_path/../../../../Frameworks", 545 | ); 546 | MACOSX_DEPLOYMENT_TARGET = 12.0; 547 | MARKETING_VERSION = 1.2; 548 | PRODUCT_BUNDLE_IDENTIFIER = com.michaellis.CalendarQuickView.CalendarWidget; 549 | PRODUCT_NAME = "$(TARGET_NAME)"; 550 | SKIP_INSTALL = YES; 551 | SWIFT_EMIT_LOC_STRINGS = YES; 552 | SWIFT_VERSION = 5.0; 553 | }; 554 | name = Debug; 555 | }; 556 | 2F0B26F22748B28D00F9D54E /* Release */ = { 557 | isa = XCBuildConfiguration; 558 | buildSettings = { 559 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 560 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 561 | ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; 562 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 563 | CODE_SIGN_ENTITLEMENTS = CalendarWidget/CalendarWidget.entitlements; 564 | CODE_SIGN_IDENTITY = "Apple Development"; 565 | CODE_SIGN_STYLE = Automatic; 566 | CURRENT_PROJECT_VERSION = 104; 567 | DEVELOPMENT_TEAM = KLQC884752; 568 | ENABLE_HARDENED_RUNTIME = YES; 569 | GENERATE_INFOPLIST_FILE = YES; 570 | INFOPLIST_FILE = CalendarWidget/Info.plist; 571 | INFOPLIST_KEY_CFBundleDisplayName = CalendarWidget; 572 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 573 | LD_RUNPATH_SEARCH_PATHS = ( 574 | "$(inherited)", 575 | "@executable_path/../Frameworks", 576 | "@executable_path/../../../../Frameworks", 577 | ); 578 | MACOSX_DEPLOYMENT_TARGET = 12.0; 579 | MARKETING_VERSION = 1.2; 580 | PRODUCT_BUNDLE_IDENTIFIER = com.michaellis.CalendarQuickView.CalendarWidget; 581 | PRODUCT_NAME = "$(TARGET_NAME)"; 582 | SKIP_INSTALL = YES; 583 | SWIFT_EMIT_LOC_STRINGS = YES; 584 | SWIFT_VERSION = 5.0; 585 | }; 586 | name = Release; 587 | }; 588 | 2FCC6CF0272C3A09006D5C7D /* Debug */ = { 589 | isa = XCBuildConfiguration; 590 | buildSettings = { 591 | ALWAYS_SEARCH_USER_PATHS = NO; 592 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 593 | CLANG_ANALYZER_NONNULL = YES; 594 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 595 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 596 | CLANG_CXX_LIBRARY = "libc++"; 597 | CLANG_ENABLE_MODULES = YES; 598 | CLANG_ENABLE_OBJC_ARC = YES; 599 | CLANG_ENABLE_OBJC_WEAK = YES; 600 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 601 | CLANG_WARN_BOOL_CONVERSION = YES; 602 | CLANG_WARN_COMMA = YES; 603 | CLANG_WARN_CONSTANT_CONVERSION = YES; 604 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 605 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 606 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 607 | CLANG_WARN_EMPTY_BODY = YES; 608 | CLANG_WARN_ENUM_CONVERSION = YES; 609 | CLANG_WARN_INFINITE_RECURSION = YES; 610 | CLANG_WARN_INT_CONVERSION = YES; 611 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 612 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 613 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 614 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 615 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 616 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 617 | CLANG_WARN_STRICT_PROTOTYPES = YES; 618 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 619 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 620 | CLANG_WARN_UNREACHABLE_CODE = YES; 621 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 622 | COPY_PHASE_STRIP = NO; 623 | DEBUG_INFORMATION_FORMAT = dwarf; 624 | DEVELOPMENT_TEAM = KLQC884752; 625 | ENABLE_STRICT_OBJC_MSGSEND = YES; 626 | ENABLE_TESTABILITY = YES; 627 | GCC_C_LANGUAGE_STANDARD = gnu11; 628 | GCC_DYNAMIC_NO_PIC = NO; 629 | GCC_NO_COMMON_BLOCKS = YES; 630 | GCC_OPTIMIZATION_LEVEL = 0; 631 | GCC_PREPROCESSOR_DEFINITIONS = ( 632 | "DEBUG=1", 633 | "$(inherited)", 634 | ); 635 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 636 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 637 | GCC_WARN_UNDECLARED_SELECTOR = YES; 638 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 639 | GCC_WARN_UNUSED_FUNCTION = YES; 640 | GCC_WARN_UNUSED_VARIABLE = YES; 641 | MACOSX_DEPLOYMENT_TARGET = 11.0; 642 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 643 | MTL_FAST_MATH = YES; 644 | ONLY_ACTIVE_ARCH = YES; 645 | SDKROOT = macosx; 646 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 647 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 648 | }; 649 | name = Debug; 650 | }; 651 | 2FCC6CF1272C3A09006D5C7D /* Release */ = { 652 | isa = XCBuildConfiguration; 653 | buildSettings = { 654 | ALWAYS_SEARCH_USER_PATHS = NO; 655 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 656 | CLANG_ANALYZER_NONNULL = YES; 657 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 658 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 659 | CLANG_CXX_LIBRARY = "libc++"; 660 | CLANG_ENABLE_MODULES = YES; 661 | CLANG_ENABLE_OBJC_ARC = YES; 662 | CLANG_ENABLE_OBJC_WEAK = YES; 663 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 664 | CLANG_WARN_BOOL_CONVERSION = YES; 665 | CLANG_WARN_COMMA = YES; 666 | CLANG_WARN_CONSTANT_CONVERSION = YES; 667 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 668 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 669 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 670 | CLANG_WARN_EMPTY_BODY = YES; 671 | CLANG_WARN_ENUM_CONVERSION = YES; 672 | CLANG_WARN_INFINITE_RECURSION = YES; 673 | CLANG_WARN_INT_CONVERSION = YES; 674 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 675 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 676 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 677 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 678 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 679 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 680 | CLANG_WARN_STRICT_PROTOTYPES = YES; 681 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 682 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 683 | CLANG_WARN_UNREACHABLE_CODE = YES; 684 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 685 | COPY_PHASE_STRIP = NO; 686 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 687 | DEVELOPMENT_TEAM = KLQC884752; 688 | ENABLE_NS_ASSERTIONS = NO; 689 | ENABLE_STRICT_OBJC_MSGSEND = YES; 690 | GCC_C_LANGUAGE_STANDARD = gnu11; 691 | GCC_NO_COMMON_BLOCKS = YES; 692 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 693 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 694 | GCC_WARN_UNDECLARED_SELECTOR = YES; 695 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 696 | GCC_WARN_UNUSED_FUNCTION = YES; 697 | GCC_WARN_UNUSED_VARIABLE = YES; 698 | MACOSX_DEPLOYMENT_TARGET = 11.0; 699 | MTL_ENABLE_DEBUG_INFO = NO; 700 | MTL_FAST_MATH = YES; 701 | SDKROOT = macosx; 702 | SWIFT_COMPILATION_MODE = wholemodule; 703 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 704 | }; 705 | name = Release; 706 | }; 707 | 2FCC6CF3272C3A09006D5C7D /* Debug */ = { 708 | isa = XCBuildConfiguration; 709 | buildSettings = { 710 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 711 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 712 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 713 | ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; 714 | CODE_SIGN_ENTITLEMENTS = CalendarQuickView/CalendarQuickView.entitlements; 715 | CODE_SIGN_IDENTITY = "Apple Development"; 716 | CODE_SIGN_STYLE = Automatic; 717 | COMBINE_HIDPI_IMAGES = YES; 718 | CURRENT_PROJECT_VERSION = 1; 719 | DEVELOPMENT_ASSET_PATHS = "\"CalendarQuickView/Preview Content\""; 720 | DEVELOPMENT_TEAM = KLQC884752; 721 | ENABLE_HARDENED_RUNTIME = YES; 722 | ENABLE_PREVIEWS = YES; 723 | GCC_NO_COMMON_BLOCKS = NO; 724 | INFOPLIST_FILE = CalendarQuickView/Info.plist; 725 | LD_RUNPATH_SEARCH_PATHS = ( 726 | "$(inherited)", 727 | "@executable_path/../Frameworks", 728 | ); 729 | MACOSX_DEPLOYMENT_TARGET = 11.0; 730 | MARKETING_VERSION = 1.3.0; 731 | PRODUCT_BUNDLE_IDENTIFIER = com.michaellis.CalendarQuickView; 732 | PRODUCT_NAME = "$(TARGET_NAME)"; 733 | PROVISIONING_PROFILE_SPECIFIER = ""; 734 | SWIFT_VERSION = 5.0; 735 | VERSIONING_SYSTEM = "apple-generic"; 736 | }; 737 | name = Debug; 738 | }; 739 | 2FCC6CF4272C3A09006D5C7D /* Release */ = { 740 | isa = XCBuildConfiguration; 741 | buildSettings = { 742 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 743 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 744 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 745 | ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; 746 | CODE_SIGN_ENTITLEMENTS = CalendarQuickView/CalendarQuickView.entitlements; 747 | CODE_SIGN_IDENTITY = "Apple Development"; 748 | CODE_SIGN_STYLE = Automatic; 749 | COMBINE_HIDPI_IMAGES = YES; 750 | CURRENT_PROJECT_VERSION = 1; 751 | DEVELOPMENT_ASSET_PATHS = "\"CalendarQuickView/Preview Content\""; 752 | DEVELOPMENT_TEAM = KLQC884752; 753 | ENABLE_HARDENED_RUNTIME = YES; 754 | ENABLE_PREVIEWS = YES; 755 | GCC_NO_COMMON_BLOCKS = NO; 756 | INFOPLIST_FILE = CalendarQuickView/Info.plist; 757 | LD_RUNPATH_SEARCH_PATHS = ( 758 | "$(inherited)", 759 | "@executable_path/../Frameworks", 760 | ); 761 | MACOSX_DEPLOYMENT_TARGET = 11.0; 762 | MARKETING_VERSION = 1.3.0; 763 | PRODUCT_BUNDLE_IDENTIFIER = com.michaellis.CalendarQuickView; 764 | PRODUCT_NAME = "$(TARGET_NAME)"; 765 | PROVISIONING_PROFILE_SPECIFIER = ""; 766 | SWIFT_VERSION = 5.0; 767 | VERSIONING_SYSTEM = "apple-generic"; 768 | }; 769 | name = Release; 770 | }; 771 | /* End XCBuildConfiguration section */ 772 | 773 | /* Begin XCConfigurationList section */ 774 | 2F0B26F02748B28D00F9D54E /* Build configuration list for PBXNativeTarget "CalendarWidgetExtension" */ = { 775 | isa = XCConfigurationList; 776 | buildConfigurations = ( 777 | 2F0B26F12748B28D00F9D54E /* Debug */, 778 | 2F0B26F22748B28D00F9D54E /* Release */, 779 | ); 780 | defaultConfigurationIsVisible = 0; 781 | defaultConfigurationName = Release; 782 | }; 783 | 2FCC6CDA272C3A08006D5C7D /* Build configuration list for PBXProject "CalendarQuickView" */ = { 784 | isa = XCConfigurationList; 785 | buildConfigurations = ( 786 | 2FCC6CF0272C3A09006D5C7D /* Debug */, 787 | 2FCC6CF1272C3A09006D5C7D /* Release */, 788 | ); 789 | defaultConfigurationIsVisible = 0; 790 | defaultConfigurationName = Release; 791 | }; 792 | 2FCC6CF2272C3A09006D5C7D /* Build configuration list for PBXNativeTarget "CalendarQuickView" */ = { 793 | isa = XCConfigurationList; 794 | buildConfigurations = ( 795 | 2FCC6CF3272C3A09006D5C7D /* Debug */, 796 | 2FCC6CF4272C3A09006D5C7D /* Release */, 797 | ); 798 | defaultConfigurationIsVisible = 0; 799 | defaultConfigurationName = Release; 800 | }; 801 | /* End XCConfigurationList section */ 802 | 803 | /* Begin XCRemoteSwiftPackageReference section */ 804 | 2F42D49027488BF900D77239 /* XCRemoteSwiftPackageReference "LaunchAtLogin" */ = { 805 | isa = XCRemoteSwiftPackageReference; 806 | repositoryURL = "https://github.com/sindresorhus/LaunchAtLogin"; 807 | requirement = { 808 | branch = main; 809 | kind = branch; 810 | }; 811 | }; 812 | /* End XCRemoteSwiftPackageReference section */ 813 | 814 | /* Begin XCSwiftPackageProductDependency section */ 815 | 2F42D49127488BF900D77239 /* LaunchAtLogin */ = { 816 | isa = XCSwiftPackageProductDependency; 817 | package = 2F42D49027488BF900D77239 /* XCRemoteSwiftPackageReference "LaunchAtLogin" */; 818 | productName = LaunchAtLogin; 819 | }; 820 | /* End XCSwiftPackageProductDependency section */ 821 | }; 822 | rootObject = 2FCC6CD7272C3A08006D5C7D /* Project object */; 823 | } 824 | -------------------------------------------------------------------------------- /CalendarQuickView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CalendarQuickView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CalendarQuickView.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "LaunchAtLogin", 6 | "repositoryURL": "https://github.com/sindresorhus/LaunchAtLogin", 7 | "state": { 8 | "branch": "main", 9 | "revision": "e8171b3e38a2816f579f58f3dac1522aa39efe41", 10 | "version": null 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /CalendarQuickView.xcodeproj/project.xcworkspace/xcuserdata/michaelellis.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/CalendarQuickView.xcodeproj/project.xcworkspace/xcuserdata/michaelellis.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CalendarQuickView.xcodeproj/xcshareddata/xcschemes/CalendarQuickView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /CalendarQuickView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 10/29/21. 6 | // 7 | 8 | import Cocoa 9 | import SwiftUI 10 | import LaunchAtLogin 11 | 12 | @main 13 | class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate { 14 | 15 | /// Required window that is immediately closed and hidden 16 | var window: NSWindow! 17 | /// This is the Status Bar Item that is clicked to show the Calendar Quick View 18 | var statusBarItem: NSStatusItem? 19 | /// This NSMenu will show when the NSStatusItem is clicked, an alternative to NSPopover 20 | let menu = NSMenu() 21 | /// Holds the Calendar View, belongs to the NSMenu 22 | let menuItem = NSMenuItem() 23 | /// Displayed as the content of the NSMenuItem 24 | var hostingView: NSHostingView? 25 | @AppStorage(AppStorageKeys.calendarSize) var calendarSize: CalendarSize = .small 26 | @AppStorage(AppStorageKeys.showWeekDayHeader) var showWeekDayHeader: Bool = true 27 | let eventKitManager = EventKitManager.shared 28 | /// This calculated var will provide a new CalendarView when the Calendar view is opened by user 29 | /// Making a new one will make sure the current date is set correctly on the calendar if the user doesn't restart their computer 30 | var newHostingView: NSHostingView { 31 | let newView = NSHostingView(rootView: StatusBarCalendar()) 32 | // Set the frame or it won't be shown 33 | var size: CGSize 34 | switch(self.calendarSize) { 35 | case .small: 36 | size = CGSize(width: 250, height: 295) 37 | size.height += showWeekDayHeader ? 25 : 10 38 | case .medium: 39 | size = CGSize(width: 300, height: 330) 40 | size.height += showWeekDayHeader ? 30 : 10 41 | case .large: 42 | size = CGSize(width: 400, height: 408) 43 | size.height += showWeekDayHeader ? 42 : 10 44 | } 45 | 46 | // Alter size of window to accomodate displaying EKEvent info 47 | if eventKitManager.isEventFeatureEnabled { 48 | eventKitManager.checkCalendarAuthStatus() { hasAccess in 49 | if hasAccess { 50 | self.eventKitManager.fetchEvents() 51 | let displayEventCount = min(Int(self.eventKitManager.numOfEventsToDisplay), self.eventKitManager.futureEvents.count) 52 | size.height += CGFloat(displayEventCount * 30) 53 | } 54 | } 55 | } 56 | newView.frame = NSRect(x: 0, y: 0, width: size.width, height: size.height) 57 | return newView 58 | } 59 | 60 | func applicationDidFinishLaunching(_ aNotification: Notification) { 61 | // Set the view and status menu bar item 62 | self.hostingView = newHostingView 63 | menuItem.view = newHostingView 64 | menu.addItem(menuItem) 65 | // Allow this AppDelegate, conforming to NSMenuDelegate, to know when the Calendar Quick View button is clicked 66 | menu.delegate = self 67 | // Configure the status bar menu item 68 | self.statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) 69 | self.statusBarItem?.menu = menu 70 | self.statusBarItem?.button?.image = NSImage(systemSymbolName: "calendar", accessibilityDescription: "Quick View Calendar") 71 | } 72 | 73 | func menuWillOpen(_ menu: NSMenu) { 74 | // Every time the menu bar view is opened it should show the current date 75 | // Example: User opens at 11:59PM, then re-opens at 12:01AM, two different dates 76 | menuItem.view = newHostingView 77 | if EventKitManager.shared.isAbleToAccessUserCalendar { 78 | 79 | } 80 | } 81 | 82 | } 83 | 84 | -------------------------------------------------------------------------------- /CalendarQuickView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | Default 529 | 530 | 531 | 532 | 533 | 534 | 535 | Left to Right 536 | 537 | 538 | 539 | 540 | 541 | 542 | Right to Left 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | Default 554 | 555 | 556 | 557 | 558 | 559 | 560 | Left to Right 561 | 562 | 563 | 564 | 565 | 566 | 567 | Right to Left 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | -------------------------------------------------------------------------------- /CalendarQuickView/CalendarQuickView.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | com.apple.security.personal-information.calendars 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /CalendarQuickView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSApplicationCategoryType 24 | public.app-category.utilities 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | LSUIElement 28 | 29 | NSCalendarsUsageDescription 30 | Add, edit, and view reminders with Calendar Quick View 31 | NSContactsUsageDescription 32 | CalendarQuickView would like access to your contacts for use with events and reminders 33 | NSRemindersUsageDescription 34 | Add, edit, and view reminders with Calendar Quick View 35 | CFBundleDisplayName 36 | 37 | NSMainStoryboardFile 38 | Main 39 | NSPrincipalClass 40 | NSApplication 41 | 42 | 43 | -------------------------------------------------------------------------------- /CalendarQuickView/Managers/EventKitManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventKitManager.swift 3 | // CalendarQuickView 4 | // 5 | // Created by David Malicke on 11/1/21. 6 | // 7 | 8 | import Foundation 9 | import EventKit 10 | import AppKit 11 | import SwiftUI 12 | 13 | class EventKitManager: ObservableObject { 14 | 15 | @AppStorage(AppStorageKeys.calendarAccessGranted) var isAbleToAccessUserCalendar: Bool = false 16 | @AppStorage(AppStorageKeys.isEventFeatureEnabled) var isEventFeatureEnabled: Bool = false 17 | @AppStorage(AppStorageKeys.numOfEventsToDisplay) var numOfEventsToDisplay: Double = 4 18 | 19 | private(set) var titles: [String] = [] 20 | private(set) var startDates: [Date] = [] 21 | private(set) var endDates: [Date] = [] 22 | private(set) var events: [EKEvent] = [] 23 | private(set) var futureEvents: [EKEvent] = [] 24 | 25 | let eventStore = EKEventStore() 26 | static let shared = EventKitManager() 27 | private init() { } 28 | 29 | func accessGranted() { 30 | isAbleToAccessUserCalendar = true 31 | } 32 | 33 | func checkCalendarAuthStatus(completion: @escaping (Bool) -> ()) { 34 | switch(EKEventStore.authorizationStatus(for: EKEntityType.event)) { 35 | case EKAuthorizationStatus.notDetermined: 36 | isAbleToAccessUserCalendar = false 37 | requestAccessToCalendar(completion: completion) 38 | case EKAuthorizationStatus.authorized: 39 | accessGranted() 40 | completion(isAbleToAccessUserCalendar) 41 | case EKAuthorizationStatus.restricted, EKAuthorizationStatus.denied: 42 | isAbleToAccessUserCalendar = false 43 | completion(isAbleToAccessUserCalendar) 44 | @unknown default: 45 | isAbleToAccessUserCalendar = false 46 | completion(isAbleToAccessUserCalendar) 47 | } 48 | } 49 | 50 | func requestAccessToCalendar(completion: @escaping (Bool) -> ()) { 51 | eventStore.requestAccess(to: .event) { accessGranted, error in 52 | if accessGranted == true { 53 | DispatchQueue.main.async { 54 | self.accessGranted() 55 | completion(true) 56 | } 57 | } else { 58 | DispatchQueue.main.async { 59 | self.isAbleToAccessUserCalendar = false 60 | completion(false) 61 | } 62 | } 63 | } 64 | } 65 | 66 | func fetchEvents() { 67 | defer { print(events) } 68 | self.events = [] 69 | self.titles = [] 70 | self.startDates = [] 71 | self.endDates = [] 72 | for calendar in self.eventStore.calendars(for: EKEntityType.event) { 73 | 74 | let oneMonthAgo = Date(timeIntervalSinceNow: -30 * 24 * 3600) 75 | let oneMonthAfterToday = Date(timeIntervalSinceNow: +30 * 24 * 3600) 76 | 77 | let predicate = eventStore.predicateForEvents(withStart: oneMonthAgo, end: oneMonthAfterToday, calendars: [calendar]) 78 | for event in eventStore.events(matching: predicate) { 79 | titles.append(event.title) 80 | startDates.append(event.startDate) 81 | endDates.append(event.endDate) 82 | events.append(event) 83 | if events.count >= Int(self.numOfEventsToDisplay) { 84 | return 85 | } 86 | } 87 | } 88 | self.futureEvents = self.getFutureEvents() 89 | } 90 | 91 | func getFutureEvents() -> [EKEvent] { 92 | guard let midnight = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: Date()) else { 93 | print("Error: No Midnight Date can be made") 94 | return [] 95 | } 96 | let futureEvents = self.events.filter { $0.startDate > midnight } 97 | return futureEvents 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /CalendarQuickView/Managers/LaunchAtLoginMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchAtLoginMonitor.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/5/21. 6 | // 7 | 8 | import Combine 9 | import SwiftUI 10 | import LaunchAtLogin 11 | 12 | /// A simple object to listen for changes in the user's preference to enable the LaunchAtLogin third party Library feature 13 | final class LaunchAtLoginMonitor: ObservableObject { 14 | /// This is what we are accessing and listening to 15 | @Published public private(set) var isLaunchAtLoginEnabled = LaunchAtLogin.isEnabled 16 | private var cancellables = Set() 17 | /// Only one of this object will ever be needed at a time 18 | public static let shared = LaunchAtLoginMonitor() 19 | 20 | // Binding Management 21 | private init() { bind() } 22 | deinit { cancellables.forEach { $0.cancel() } } 23 | /// Creates a listener to the isEnabled property of the external dependency 24 | private func bind() { 25 | LaunchAtLogin 26 | .publisher 27 | .assign(to: \.isLaunchAtLoginEnabled, on: self) 28 | .store(in: &cancellables) 29 | } 30 | } 31 | /// An empty LaunchAtLogin Toggle Button 32 | public struct LaunchAtLoginMonitorToggle: View { 33 | public var body: some View { 34 | LaunchAtLogin.Toggle("") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /CalendarQuickView/Models/CalendarViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StorageManager.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/6/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | final class CalendarViewModel: ObservableObject { 11 | 12 | // MARK: - Date Formats 13 | 14 | /// Stored property to determine date format for the Title of the calendar view 15 | @AppStorage(AppStorageKeys.titleDateFormat) var titleDateFormat: TitleDateFormat = .shortMonthAndYear 16 | /// Stored property to determine date format for displayed events 17 | @AppStorage(AppStorageKeys.eventDateFormat) var eventDateFormat: EventDateFormat = .shortDayAndMonth 18 | var titleDateFormatter: DateFormatter { DateFormatter(dateFormat: self.titleDateFormat.rawValue, calendar: .current) } 19 | var eventDateFormatter: DateFormatter { DateFormatter(dateFormat: self.eventDateFormat.rawValue, calendar: .current) } 20 | 21 | // MARK: - Sizing 22 | 23 | /// This is the storage variable for calendar size, do not use 24 | @AppStorage(AppStorageKeys.calendarSize) private var storedCalendarSize: CalendarSize = .small 25 | /// This is for getting and setting the calendar size, will update buttonSize 26 | var calendarSize: CalendarSize { 27 | get { 28 | return self.storedCalendarSize 29 | } 30 | set { 31 | self.storedCalendarSize = newValue 32 | } 33 | } 34 | 35 | var buttonSize: CGFloat { 36 | self.calendarSize == .small ? 20 : self.calendarSize == .medium ? 30 : 40 37 | } 38 | var calendarTitleSize: Font { self.calendarSize == .small ? .title2 : self.calendarSize == .medium ? .title : .largeTitle } 39 | 40 | 41 | // MARK: - Calendar Data 42 | /// Stored property to determine if the S M T W T F S row should be shown 43 | @AppStorage(AppStorageKeys.showWeekDayHeader) var showWeekDayHeader: Bool = true 44 | 45 | @AppStorage(AppStorageKeys.selectedDay) var selectedDate: Date = Date() 46 | @Published public var displayDate: Date 47 | public var calendar: Calendar 48 | @AppStorage(AppStorageKeys.dayDisplayShape) var dayDisplayShape: DayDisplayShape = .roundedSquare 49 | 50 | /// Stored property to determine if Dock Icon should be displayed 51 | @AppStorage(AppStorageKeys.showDockIcon) var showDockIcon: Bool = false 52 | 53 | init() { 54 | self.displayDate = Date() 55 | self.calendar = .current 56 | } 57 | 58 | public func resetDate() { 59 | self.displayDate = Date() 60 | } 61 | 62 | var getDayCellSize: CGFloat { 63 | switch(self.calendarSize) { 64 | case .small: 65 | return 24 66 | case .medium: 67 | return 30 68 | case .large: 69 | return 42 70 | } 71 | } 72 | 73 | /// Generates 6 weeks worth of days in an array 74 | public func getGetCalendarDays() -> [Date] { 75 | guard let monthInterval = calendar.dateInterval(of: .month, for: displayDate), 76 | let monthFirstWeek = calendar.dateInterval(of: .weekOfMonth, for: monthInterval.start), 77 | let sixWeeksFromStart = Calendar.current.date(byAdding: .day, value: 7 * 6, to: monthFirstWeek.start) else { 78 | return [] 79 | } 80 | // get 6 weeks of days 81 | let dateInterval = DateInterval(start: monthFirstWeek.start, end: sixWeeksFromStart) 82 | return calendar.generateDays(for: dateInterval) 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /CalendarQuickView/Models/ColorStore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorStore.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/20/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | class ColorStore: ObservableObject { 11 | 12 | static let shared = ColorStore() 13 | private init() { } 14 | 15 | // MARK: - Colors 16 | 17 | @AppStorage("titleText") public var _titleTextColor: String = "contrast" 18 | var titleTextColor: Color { Color("\(self._titleTextColor)") } 19 | @AppStorage("eventTextColor") public var _eventTextColor: String = "contrast" 20 | var eventTextColor: Color { Color("\(self._eventTextColor)") } 21 | @AppStorage("buttonColor") public var _buttonColor: String = "contrast" 22 | var buttonColor: Color { Color("\(self._buttonColor)") } 23 | @AppStorage("currentMonthText") public var _currentMonthText: String = "contrast" 24 | var currentMonthText: Color { Color("\(self._currentMonthText)") } 25 | @AppStorage("currentMonthColor") public var _currentMonthColor: String = "stone" 26 | var currentMonthColor: Color { Color("\(self._currentMonthColor)") } 27 | @AppStorage("otherMonthText") public var _otherMonthText: String = "contrast" 28 | var otherMonthText: Color { Color("\(self._otherMonthText)") } 29 | @AppStorage("otherMonthColor") public var _otherMonthColor: String = "stone" 30 | var otherMonthColor: Color { Color("\(self._otherMonthColor)") } 31 | } 32 | -------------------------------------------------------------------------------- /CalendarQuickView/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/CalendarQuickView/Views/.DS_Store -------------------------------------------------------------------------------- /CalendarQuickView/Views/CalendarBody.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarBody.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/2/21. 6 | // 7 | 8 | import SwiftUI 9 | import WidgetKit 10 | 11 | struct CalendarBody: View { 12 | // TODO: Remove this - make it more reusable 13 | // Constants 14 | private let daysInWeek: Int = 7 15 | private let weekDayCellSpacing: CGFloat = 10 16 | private let verticalPadding: CGFloat = 8 17 | private let days: [[Date]] 18 | private let fontSize: Font 19 | private let dayCellSize: CGFloat 20 | private let titleTextColor: Color 21 | private let showWeekdayHeaderRow: Bool 22 | private let displayMonth: Date 23 | private let dayShape: DayDisplayShape 24 | 25 | init(viewModel: CalendarViewModel) { 26 | self.dayCellSize = viewModel.getDayCellSize 27 | self.fontSize = viewModel.calendarSize == .small ? .body : viewModel.calendarSize == .medium ? .title3 : .title2 28 | self.titleTextColor = ColorStore.shared.titleTextColor 29 | self.days = viewModel.getGetCalendarDays().chunked(into: 7) 30 | self.showWeekdayHeaderRow = viewModel.showWeekDayHeader 31 | self.displayMonth = viewModel.displayDate.startOfMonth(using: viewModel.calendar) 32 | self.dayShape = viewModel.dayDisplayShape 33 | } 34 | 35 | private func weekDayHeaders(for weekDays: [Date]) -> some View { 36 | let weekDayFormatter = DateFormatter.weekDayFormatter 37 | return HStack(spacing: weekDayCellSpacing) { 38 | ForEach(weekDays, id: \.self) { date in 39 | Text(weekDayFormatter.string(from: date)) 40 | .font(self.fontSize) 41 | .frame(width: self.dayCellSize, height: self.dayCellSize) 42 | } 43 | } 44 | .foregroundColor(self.titleTextColor) 45 | } 46 | 47 | var body: some View { 48 | // TODO: Make week able to start on any day of week(customizable) 49 | return VStack(spacing: 0) { 50 | if self.showWeekdayHeaderRow { 51 | // M T W T F S S 52 | weekDayHeaders(for: days.first ?? []) 53 | .padding(.vertical, verticalPadding) 54 | } 55 | // Iterating over the days of the month 56 | ForEach(days, id: \.self) { weekDays in 57 | HStack(spacing: weekDayCellSpacing) { 58 | ForEach(weekDays, id:\.self) { date in 59 | // Each individual day 60 | CalendarDay(date: date, 61 | fontSize: self.fontSize, 62 | cellSize: self.dayCellSize, 63 | dayShape: self.dayShape, 64 | month: self.displayMonth) 65 | .padding(.vertical, 4) 66 | } 67 | } 68 | } 69 | } 70 | .padding(.top, verticalPadding) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/CalendarButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarButton.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/6/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CalendarButton: View { 11 | 12 | let imageName: String 13 | let animation: Animation 14 | let color: Color 15 | let size: CGFloat 16 | let action: () -> () 17 | 18 | var body: some View { 19 | Button(action: { 20 | withAnimation(animation) { 21 | action() 22 | } 23 | }, label: { 24 | Image(systemName: imageName) 25 | .frame(width: size, height: size) 26 | .foregroundColor(color) 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/CalendarDay.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarDay.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/12/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CalendarDay: View { 11 | 12 | private let date: Date 13 | private let fontSize: Font 14 | private let cellSize: CGFloat 15 | private let dayShape: DayDisplayShape 16 | private let dayColors: (text: Color, bgColor: Color) 17 | private var showEventOverlay: Bool = false 18 | 19 | init(date: Date, fontSize: Font, cellSize: CGFloat, dayShape: DayDisplayShape, month: Date) { 20 | self.date = date 21 | self.fontSize = fontSize 22 | self.cellSize = cellSize 23 | self.dayShape = dayShape 24 | if Calendar.current.isDateInToday(self.date) { 25 | // Current Day 26 | self.dayColors = (ColorStore.shared.currentMonthText, ColorStore.shared.currentMonthColor) 27 | } else if Calendar.current.isDate(self.date, equalTo: month, toGranularity: .month) { 28 | // Day in Current Displayed Month 29 | self.dayColors = (ColorStore.shared.currentMonthText, ColorStore.shared.currentMonthColor) 30 | } else { 31 | // Day is not in Current Displayed Month 32 | self.dayColors = (ColorStore.shared.otherMonthText, ColorStore.shared.otherMonthColor) 33 | } 34 | self.showEventOverlay = !EventKitManager.shared.startDates.compactMap { 35 | Calendar.current.isDate($0, inSameDayAs: self.date) 36 | }.allSatisfy { $0 == false } 37 | } 38 | 39 | var body: some View { 40 | Text(String(Calendar.current.component(.day, from: date))) 41 | .frame(width: cellSize, height: cellSize) 42 | .font(fontSize) 43 | .foregroundColor(self.dayColors.text) 44 | .if(dayShape != .none) { textView in 45 | textView.background(self.dayColors.bgColor) 46 | .clipShape(dayShape.shape) 47 | } 48 | .if(self.showEventOverlay) { view in 49 | view.overlay(Circle().fill(ColorStore.shared.eventTextColor).frame(width: cellSize / 8, height: cellSize / 8).position(x: cellSize / 2, y: cellSize - (cellSize / 8))) 50 | // 24 30 42 51 | } 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/CalendarFooter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarFooter.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/5/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CalendarFooter: View { 11 | 12 | @EnvironmentObject var viewModel: CalendarViewModel 13 | 14 | var settingWindowCallback: () -> () = { } 15 | 16 | init(openSettings settingWindowCallback: @escaping () -> ()) { 17 | self.settingWindowCallback = settingWindowCallback 18 | } 19 | 20 | var body: some View { 21 | HStack(spacing: 0) { 22 | Spacer() 23 | CalendarButton(imageName: "gear", animation: .linear, color: ColorStore.shared.buttonColor, size: viewModel.buttonSize, action: self.settingWindowCallback) 24 | .foregroundColor(ColorStore.shared.buttonColor) 25 | } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/CalendarHeader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarHeader.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/2/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | /// Displays the displayed Month Name and Year as well as buttons to view next/prev/current month 11 | struct CalendarHeader: View { 12 | 13 | /// Because this view allows the user to change the display it must have a reference to the view model(tightly coupled) 14 | @EnvironmentObject var viewModel: CalendarViewModel 15 | 16 | var body: some View { 17 | VStack(alignment: .leading) { 18 | HStack(spacing: 0) { 19 | 20 | // MARK: - Title (Month/Year) 21 | Text(self.viewModel.titleDateFormatter.string(from: self.viewModel.displayDate)) 22 | .foregroundColor(ColorStore.shared.titleTextColor) 23 | .font(self.viewModel.calendarTitleSize) 24 | Spacer() 25 | 26 | // MARK: - Previous Month Button 27 | 28 | CalendarButton(imageName: "chevron.left", animation: .easeOut, color: ColorStore.shared.buttonColor, size: self.viewModel.buttonSize) { 29 | self.viewModel.displayDate.incrementMonths(by: -1) 30 | } 31 | .padding(.horizontal, 5) 32 | .foregroundColor(ColorStore.shared.buttonColor) 33 | 34 | // MARK: - GoTo Current Date Button 35 | 36 | CalendarButton(imageName: "calendar", animation: .spring(), color: ColorStore.shared.buttonColor, size: self.viewModel.buttonSize) { 37 | self.viewModel.displayDate = Date() 38 | } 39 | .padding(.trailing, 5) 40 | .foregroundColor(ColorStore.shared.buttonColor) 41 | 42 | // MARK: - Next Month Button 43 | 44 | CalendarButton(imageName: "chevron.right", animation: .easeIn, color: ColorStore.shared.buttonColor, size: self.viewModel.buttonSize) { 45 | self.viewModel.displayDate.incrementMonths(by: 1) 46 | } 47 | .foregroundColor(ColorStore.shared.buttonColor) 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/EventListView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventListView.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/7/21. 6 | // 7 | 8 | import SwiftUI 9 | import EventKit 10 | 11 | struct EventListView: View { 12 | 13 | @EnvironmentObject var viewModel: CalendarViewModel 14 | @ObservedObject var eventManager = EventKitManager.shared 15 | var eventsToDisplay: [EKEvent] = [] 16 | 17 | init() { 18 | self.eventManager.fetchEvents() 19 | self.eventsToDisplay = self.eventManager.getFutureEvents() 20 | } 21 | 22 | var body: some View { 23 | // Events List 24 | let fontSize: Font = self.viewModel.calendarSize == .small ? .callout : self.viewModel.calendarSize == .medium ? .body : .title3 25 | if EventKitManager.shared.isEventFeatureEnabled, 26 | EventKitManager.shared.isAbleToAccessUserCalendar { 27 | VStack(alignment: .leading, spacing: 0) { 28 | ForEach(self.eventsToDisplay.prefix(Int(eventManager.numOfEventsToDisplay)), id: \.self) { event in 29 | HStack { 30 | Text(event.title) 31 | .font(fontSize) 32 | Spacer() 33 | Text(viewModel.eventDateFormatter.string(from: event.startDate)) 34 | .font(fontSize) 35 | } 36 | .foregroundColor((ColorStore.shared.eventTextColor)) 37 | .frame(height: 29) 38 | Divider() 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/Settings/Colors/AppColors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppColors.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/7/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | /// Rose App Color Them 11 | enum AppColors: String, CaseIterable { 12 | case contrast 13 | case coral 14 | case jet 15 | case jonquil 16 | case lavendar 17 | case mustard 18 | case onyx 19 | case pink 20 | case rose 21 | case sky 22 | case stone 23 | case tart 24 | case vermillion 25 | case wood 26 | 27 | var color: Color { Color(self.rawValue) } 28 | } 29 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/Settings/Colors/ColorSettings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorSettings.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/5/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ColorSettings: View { 11 | 12 | @EnvironmentObject var viewModel: CalendarViewModel 13 | @ObservedObject var colorStore: ColorStore = ColorStore.shared 14 | @State var isShowingPopover: [Bool] = [Bool](repeating: false, count: 7) 15 | 16 | func ColorLabel(index: Int, _ color: Color, _ text: String, value: Binding) -> some View { 17 | HStack { 18 | Text(text).frame(height: 25).foregroundColor(AppColors.contrast.color) 19 | Spacer() 20 | Button(action: { 21 | isShowingPopover[index] = true 22 | }) { 23 | color.frame(width: 25, height: 25) 24 | .cornerRadius(4) 25 | } 26 | .buttonStyle(PlainButtonStyle()) 27 | .popover(isPresented: $isShowingPopover[index], attachmentAnchor: PopoverAttachmentAnchor.point(.bottom), arrowEdge: .bottom) { 28 | ScrollView(.vertical) { 29 | VStack(alignment: .leading, spacing: 4) { 30 | ForEach(AppColors.allCases, id:\.self) { color in 31 | HStack(spacing: 0) { 32 | Text(color.rawValue.capitalized) 33 | .padding(.horizontal, 8) 34 | .padding(.vertical, 4) 35 | .foregroundColor(AppColors.contrast.color) 36 | Spacer() 37 | Color(color.rawValue) 38 | .frame(width: 40) 39 | .cornerRadius(4) 40 | .padding(.trailing, 6) 41 | } 42 | .frame(width: 130, height: 30) 43 | .contentShape(Rectangle()) 44 | .onTapGesture { 45 | isShowingPopover[index] = false 46 | value.wrappedValue = color.rawValue 47 | } 48 | Divider() 49 | } 50 | } 51 | .padding(.vertical, 5) 52 | } 53 | } 54 | } 55 | } 56 | 57 | var body: some View { 58 | VStack(spacing: 10) { 59 | HStack { 60 | Spacer() 61 | Text("Reset All") 62 | .font(.title3) 63 | CalendarButton(imageName: "arrow.triangle.2.circlepath", animation: .linear, color: ColorStore.shared.buttonColor, size: viewModel.buttonSize) { 64 | ColorStore.shared._titleTextColor = "contrast" 65 | ColorStore.shared._eventTextColor = "contrast" 66 | ColorStore.shared._buttonColor = "contrast" 67 | 68 | ColorStore.shared._currentMonthText = "contrast" 69 | ColorStore.shared._currentMonthColor = "stone" 70 | 71 | ColorStore.shared._otherMonthText = "contrast" 72 | ColorStore.shared._otherMonthColor = "stone" 73 | } 74 | Spacer() 75 | } 76 | VStack(alignment: .leading) { 77 | Divider() 78 | HStack { 79 | Text("General Colors") 80 | .font(.title3) 81 | Spacer() 82 | } 83 | ColorLabel(index: 0, ColorStore.shared.titleTextColor, "Calendar Title Text", value: ColorStore.shared.$_titleTextColor) 84 | ColorLabel(index: 1, ColorStore.shared.eventTextColor, "Event Text", value: ColorStore.shared.$_eventTextColor) 85 | ColorLabel(index: 2, ColorStore.shared.buttonColor, "Button Highlight", value: ColorStore.shared.$_buttonColor) 86 | } 87 | VStack(alignment: .leading) { 88 | Divider() 89 | HStack { 90 | Text("Current Month's Days") 91 | .font(.title3) 92 | Spacer() 93 | } 94 | ColorLabel(index: 4, ColorStore.shared.currentMonthText, "Text", value: ColorStore.shared.$_currentMonthText) 95 | ColorLabel(index: 3, ColorStore.shared.currentMonthColor, "Background", value: ColorStore.shared.$_currentMonthColor) 96 | } 97 | VStack(alignment: .leading) { 98 | Divider() 99 | HStack { 100 | Text("Other Month's Days") 101 | .font(.title3) 102 | Spacer() 103 | } 104 | ColorLabel(index: 5, ColorStore.shared.otherMonthText, "Text", value: ColorStore.shared.$_otherMonthText) 105 | ColorLabel(index: 6, ColorStore.shared.otherMonthColor, "Background", value: ColorStore.shared.$_otherMonthColor) 106 | } 107 | Spacer() 108 | } 109 | .frame(width: 250) 110 | .padding(.vertical, 20) 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/Settings/EventSettings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventSettings.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/5/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct EventSettings: View { 11 | 12 | @ObservedObject var eventManager = EventKitManager.shared 13 | @EnvironmentObject var viewModel: CalendarViewModel 14 | 15 | func TextWithFrame(_ text: String) -> some View { 16 | Text(text).frame(height: 25) 17 | } 18 | 19 | var body: some View { 20 | VStack { 21 | HStack { 22 | VStack(alignment: .leading) { 23 | TextWithFrame("Calendar Access") 24 | TextWithFrame("Display Event Info") 25 | TextWithFrame("Event List Date Format") 26 | TextWithFrame("Events to display: \(Int(eventManager.numOfEventsToDisplay))") 27 | } 28 | VStack(alignment: .trailing) { 29 | HStack { 30 | CalendarButton(imageName: eventManager.isAbleToAccessUserCalendar ? "checkmark.circle" : "xmark.circle", animation: .linear, color: ColorStore.shared.buttonColor, size: viewModel.buttonSize) { 31 | self.eventManager.requestAccessToCalendar { success in 32 | print("Event access - \(success)") 33 | } 34 | } 35 | .foregroundColor(eventManager.isAbleToAccessUserCalendar ? .green : .white) 36 | Spacer() 37 | } 38 | .frame(height: 25) 39 | .padding(.leading, 10) 40 | HStack { 41 | CalendarButton(imageName: eventManager.isEventFeatureEnabled ? "checkmark.circle" : "xmark.circle", animation: .linear, color: ColorStore.shared.buttonColor, size: viewModel.buttonSize) { 42 | self.eventManager.isEventFeatureEnabled.toggle() 43 | } 44 | .foregroundColor(eventManager.isEventFeatureEnabled ? .green : .white) 45 | Spacer() 46 | } 47 | .frame(height: 25) 48 | .padding(.leading, 10) 49 | Picker("", selection: $viewModel.eventDateFormat) { 50 | ForEach(EventDateFormat.allCases, id: \.self) { dateFormatOption in 51 | Text(dateFormatOption.displayName) 52 | } 53 | } 54 | .frame(height: 25) 55 | Slider(value: $eventManager.numOfEventsToDisplay, in: 1...10, step: 1.0) 56 | .frame(height: 25) 57 | .padding(.trailing, 3) 58 | .padding(.leading, 10) 59 | } 60 | .frame(width: 215) 61 | } 62 | Spacer() 63 | } 64 | .padding(.vertical, 20) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/Settings/GeneralSettings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GeneralSettings.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/5/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct GeneralSettings: View { 11 | 12 | @EnvironmentObject var viewModel: CalendarViewModel 13 | @ObservedObject var launchAtLoginMonitor = LaunchAtLoginMonitor.shared 14 | 15 | func TextWithFrame(_ text: String) -> some View { 16 | Text(text) 17 | .frame(width: 200, height: 25, alignment: .leading) 18 | } 19 | 20 | var body: some View { 21 | VStack { 22 | HStack { 23 | VStack(alignment: .leading) { 24 | // Calendar Month/Year Title Date Format 25 | TextWithFrame("Title Date Format") 26 | // Day Shape 27 | TextWithFrame("Day Display Shape") 28 | // Calendar Size 29 | TextWithFrame("Calendar Size") 30 | // SMTWTFS Calendar Header Row 31 | TextWithFrame("Show Weekday Header Row") 32 | // Show app icon in dock 33 | TextWithFrame(viewModel.showDockIcon ? "App Icon Shown In Dock" : "App Icon Not In Dock") 34 | // Launch app at login 35 | TextWithFrame("\(self.launchAtLoginMonitor.isLaunchAtLoginEnabled ? "App is currently in" : "Click to add to") Login Items") 36 | } 37 | .frame(width: 200) 38 | VStack(alignment: .trailing) { 39 | // Calendar Month/Year Title Date Format 40 | Picker("", selection: $viewModel.titleDateFormat) { 41 | ForEach(TitleDateFormat.allCases, id: \.self) { dateFormatOption in 42 | Text(dateFormatOption.displayName) 43 | } 44 | } 45 | .frame(height: 25) 46 | // Day Shape 47 | Picker("", selection: $viewModel.dayDisplayShape) { 48 | ForEach(DayDisplayShape.allCases, id: \.self) { option in 49 | Text(option.displayName) 50 | } 51 | } 52 | .frame(height: 25) 53 | // Calendar Size 54 | Picker("", selection: $viewModel.calendarSize) { 55 | ForEach(CalendarSize.allCases, id: \.self) { calendarSize in 56 | Text(calendarSize.rawValue) 57 | } 58 | } 59 | .pickerStyle(.segmented) 60 | // SMTWTFS Calendar Header Row 61 | .frame(height: 25) 62 | HStack { 63 | Toggle("", isOn: viewModel.$showWeekDayHeader) 64 | Spacer() 65 | } 66 | .padding(.leading, 10) 67 | .frame(height: 25) 68 | // Show app icon in dock 69 | HStack { 70 | Toggle("", isOn: $viewModel.showDockIcon) 71 | .onChange(of: viewModel.showDockIcon) { newValue in 72 | NSApp.setActivationPolicy(newValue ? .regular : .accessory) 73 | } 74 | Spacer() 75 | } 76 | .padding(.leading, 10) 77 | .frame(height: 25) 78 | // Launch app at login 79 | HStack { 80 | LaunchAtLoginMonitorToggle() 81 | Spacer() 82 | } 83 | .padding(.leading, 10) 84 | .frame(height: 25) 85 | } 86 | .frame(width: 200) 87 | } 88 | Spacer() 89 | } 90 | .padding(.vertical, 20) 91 | } 92 | } 93 | 94 | struct mything: View { 95 | @State private var isOn = false 96 | 97 | var body: some View { 98 | Toggle("Title", isOn: $isOn) 99 | .onChange(of: isOn) { _isOn in 100 | /// use _isOn here.. 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/Settings/SettingsTabView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsTabView.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/1/21. 6 | // 7 | 8 | import SwiftUI 9 | import Combine 10 | 11 | struct SettingsTabView: View { 12 | 13 | @State var showMenuButton: Bool = true 14 | @StateObject var viewModel = CalendarViewModel() 15 | 16 | private enum Tabs: Hashable { 17 | case general 18 | case colors 19 | case events 20 | } 21 | 22 | var body: some View { 23 | VStack(alignment: .leading, spacing: 10) { 24 | HStack { 25 | Text("Calendar Quick View Settings") 26 | .font(.title) 27 | .padding() 28 | Spacer() 29 | Button(action: { 30 | NSApp.terminate(self) 31 | }, label: { Text("Quit App") }) 32 | .padding() 33 | } 34 | TabView { 35 | GeneralSettings() 36 | .tabItem { 37 | Label("General", systemImage: "gear") 38 | } 39 | .tag(Tabs.colors) 40 | .environmentObject(viewModel) 41 | ColorSettings() 42 | .tabItem { 43 | Label("Colors", systemImage: "star") 44 | } 45 | .tag(Tabs.colors) 46 | .environmentObject(viewModel) 47 | EventSettings() 48 | .tabItem { 49 | Label("Events", systemImage: "star") 50 | } 51 | .tag(Tabs.events) 52 | .environmentObject(viewModel) 53 | } 54 | Spacer() 55 | } 56 | .frame(width: 480) 57 | Spacer() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /CalendarQuickView/Views/StatusBarCalendar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StatusBarCalendar.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 10/29/21. 6 | // 7 | 8 | import SwiftUI 9 | import AppKit 10 | import Combine 11 | 12 | struct StatusBarCalendar: View { 13 | 14 | @ObservedObject var viewModel = CalendarViewModel() 15 | static var windowRef: NSWindow? 16 | private var horizontalPadding: CGFloat = 10 17 | 18 | init() { 19 | self.horizontalPadding = self.viewModel.calendarSize == .small ? 10 : viewModel.calendarSize == .medium ? 15 : 23 20 | } 21 | 22 | var body: some View { 23 | VStack(alignment: .center, spacing: 0) { 24 | CalendarHeader() 25 | .padding(.bottom, 4) 26 | .environmentObject(viewModel) 27 | CalendarBody(viewModel: viewModel) 28 | .padding(.bottom, 4) 29 | EventListView() 30 | .environmentObject(viewModel) 31 | Spacer() 32 | CalendarFooter(openSettings: Self.openSettingsWindow) 33 | .environmentObject(viewModel) 34 | } 35 | .padding(.horizontal, horizontalPadding) 36 | .padding(.vertical, 10) 37 | } 38 | 39 | /// Opens a window displaying a Swiftui View for app settings 40 | static func openSettingsWindow() { 41 | if windowRef == nil { 42 | let newWindowRef = NSWindow( 43 | contentRect: NSRect(x: 100, y: 100, width: 100, height: 400), 44 | styleMask: [.titled, .closable, .miniaturizable], 45 | backing: .buffered, defer: false) 46 | self.windowRef = newWindowRef 47 | self.windowRef?.setFrameAutosaveName("Calendar Quick View Settings") 48 | self.windowRef?.isReleasedWhenClosed = false 49 | self.windowRef?.contentView = NSHostingView(rootView: SettingsTabView()) 50 | Self.windowToFront() 51 | } else { 52 | Self.windowToFront() 53 | } 54 | } 55 | 56 | static private func windowToFront() { 57 | self.windowRef?.orderFrontRegardless() 58 | self.windowRef?.makeKey() 59 | self.windowRef?.becomeFirstResponder() 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /CalendarQuickView/Widget/CalendarWidget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarWidget.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/2/21. 6 | // 7 | 8 | import SwiftUI 9 | import WidgetKit 10 | 11 | struct Provider: TimelineProvider { 12 | 13 | typealias Entry = SimpleEntry 14 | 15 | func placeholder(in context: Context) -> SimpleEntry { 16 | return SimpleEntry() 17 | } 18 | 19 | func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void) { 20 | completion(SimpleEntry()) 21 | } 22 | 23 | func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { 24 | completion(SimpleEntry()) 25 | } 26 | } 27 | 28 | //struct SimpleEntry: TimelineEntry { 29 | // 30 | //} 31 | 32 | @main 33 | struct Calendar_Widget: Widget { 34 | private let kind: String = "Calendar_Widget" 35 | 36 | public var body: some WidgetConfiguration { 37 | StaticConfiguration( 38 | kind: kind, 39 | provider: Provider(), 40 | content: { entry in 41 | Text("YOYOY") 42 | }) 43 | .configurationDisplayName("Random Emoji") 44 | .description("Display a widget with an emoji that is updated randomly.") 45 | .supportedFamilies([.systemSmall]) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /CalendarQuickView/Widget/CalendarWidgetProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarWidgetProvider.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/2/21. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | public struct CalendarWidgetProvider { 12 | func all() -> [String] { 13 | return ["a", "b", "c", "d"] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CalendarQuickView/en-US.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "NSMenuItem"; title = "Customize Toolbar…"; ObjectID = "1UK-8n-QPP"; */ 3 | "1UK-8n-QPP.title" = "Customize Toolbar…"; 4 | 5 | /* Class = "NSMenuItem"; title = "CalendarQuickView"; ObjectID = "1Xt-HY-uBw"; */ 6 | "1Xt-HY-uBw.title" = "CalendarQuickView"; 7 | 8 | /* Class = "NSMenu"; title = "Find"; ObjectID = "1b7-l0-nxx"; */ 9 | "1b7-l0-nxx.title" = "Find"; 10 | 11 | /* Class = "NSMenuItem"; title = "Lower"; ObjectID = "1tx-W0-xDw"; */ 12 | "1tx-W0-xDw.title" = "Lower"; 13 | 14 | /* Class = "NSMenuItem"; title = "Raise"; ObjectID = "2h7-ER-AoG"; */ 15 | "2h7-ER-AoG.title" = "Raise"; 16 | 17 | /* Class = "NSMenuItem"; title = "Transformations"; ObjectID = "2oI-Rn-ZJC"; */ 18 | "2oI-Rn-ZJC.title" = "Transformations"; 19 | 20 | /* Class = "NSMenu"; title = "Spelling"; ObjectID = "3IN-sU-3Bg"; */ 21 | "3IN-sU-3Bg.title" = "Spelling"; 22 | 23 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "3Om-Ey-2VK"; */ 24 | "3Om-Ey-2VK.title" = "Use Default"; 25 | 26 | /* Class = "NSMenu"; title = "Speech"; ObjectID = "3rS-ZA-NoH"; */ 27 | "3rS-ZA-NoH.title" = "Speech"; 28 | 29 | /* Class = "NSMenuItem"; title = "Tighten"; ObjectID = "46P-cB-AYj"; */ 30 | "46P-cB-AYj.title" = "Tighten"; 31 | 32 | /* Class = "NSMenuItem"; title = "Find"; ObjectID = "4EN-yA-p0u"; */ 33 | "4EN-yA-p0u.title" = "Find"; 34 | 35 | /* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */ 36 | "4J7-dP-txa.title" = "Enter Full Screen"; 37 | 38 | /* Class = "NSMenuItem"; title = "Quit CalendarQuickView"; ObjectID = "4sb-4s-VLi"; */ 39 | "4sb-4s-VLi.title" = "Quit CalendarQuickView"; 40 | 41 | /* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */ 42 | "5QF-Oa-p0T.title" = "Edit"; 43 | 44 | /* Class = "NSMenuItem"; title = "Copy Style"; ObjectID = "5Vv-lz-BsD"; */ 45 | "5Vv-lz-BsD.title" = "Copy Style"; 46 | 47 | /* Class = "NSMenuItem"; title = "About CalendarQuickView"; ObjectID = "5kV-Vb-QxS"; */ 48 | "5kV-Vb-QxS.title" = "About CalendarQuickView"; 49 | 50 | /* Class = "NSMenuItem"; title = "Redo"; ObjectID = "6dh-zS-Vam"; */ 51 | "6dh-zS-Vam.title" = "Redo"; 52 | 53 | /* Class = "NSMenuItem"; title = "Correct Spelling Automatically"; ObjectID = "78Y-hA-62v"; */ 54 | "78Y-hA-62v.title" = "Correct Spelling Automatically"; 55 | 56 | /* Class = "NSMenu"; title = "Writing Direction"; ObjectID = "8mr-sm-Yjd"; */ 57 | "8mr-sm-Yjd.title" = "Writing Direction"; 58 | 59 | /* Class = "NSMenuItem"; title = "Substitutions"; ObjectID = "9ic-FL-obx"; */ 60 | "9ic-FL-obx.title" = "Substitutions"; 61 | 62 | /* Class = "NSMenuItem"; title = "Smart Copy/Paste"; ObjectID = "9yt-4B-nSM"; */ 63 | "9yt-4B-nSM.title" = "Smart Copy/Paste"; 64 | 65 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ 66 | "AYu-sK-qS6.title" = "Main Menu"; 67 | 68 | /* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ 69 | "BOF-NM-1cW.title" = "Preferences…"; 70 | 71 | /* Class = "NSMenuItem"; title = "\tLeft to Right"; ObjectID = "BgM-ve-c93"; */ 72 | "BgM-ve-c93.title" = "\tLeft to Right"; 73 | 74 | /* Class = "NSMenuItem"; title = "Save As…"; ObjectID = "Bw7-FT-i3A"; */ 75 | "Bw7-FT-i3A.title" = "Save As…"; 76 | 77 | /* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */ 78 | "DVo-aG-piG.title" = "Close"; 79 | 80 | /* Class = "NSMenuItem"; title = "Spelling and Grammar"; ObjectID = "Dv1-io-Yv7"; */ 81 | "Dv1-io-Yv7.title" = "Spelling and Grammar"; 82 | 83 | /* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */ 84 | "F2S-fz-NVQ.title" = "Help"; 85 | 86 | /* Class = "NSMenuItem"; title = "CalendarQuickView Help"; ObjectID = "FKE-Sm-Kum"; */ 87 | "FKE-Sm-Kum.title" = "CalendarQuickView Help"; 88 | 89 | /* Class = "NSMenuItem"; title = "Text"; ObjectID = "Fal-I4-PZk"; */ 90 | "Fal-I4-PZk.title" = "Text"; 91 | 92 | /* Class = "NSMenu"; title = "Substitutions"; ObjectID = "FeM-D8-WVr"; */ 93 | "FeM-D8-WVr.title" = "Substitutions"; 94 | 95 | /* Class = "NSMenuItem"; title = "Bold"; ObjectID = "GB9-OM-e27"; */ 96 | "GB9-OM-e27.title" = "Bold"; 97 | 98 | /* Class = "NSMenu"; title = "Format"; ObjectID = "GEO-Iw-cKr"; */ 99 | "GEO-Iw-cKr.title" = "Format"; 100 | 101 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "GUa-eO-cwY"; */ 102 | "GUa-eO-cwY.title" = "Use Default"; 103 | 104 | /* Class = "NSMenuItem"; title = "Font"; ObjectID = "Gi5-1S-RQB"; */ 105 | "Gi5-1S-RQB.title" = "Font"; 106 | 107 | /* Class = "NSMenuItem"; title = "Writing Direction"; ObjectID = "H1b-Si-o9J"; */ 108 | "H1b-Si-o9J.title" = "Writing Direction"; 109 | 110 | /* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */ 111 | "H8h-7b-M4v.title" = "View"; 112 | 113 | /* Class = "NSMenuItem"; title = "Text Replacement"; ObjectID = "HFQ-gK-NFA"; */ 114 | "HFQ-gK-NFA.title" = "Text Replacement"; 115 | 116 | /* Class = "NSMenuItem"; title = "Show Spelling and Grammar"; ObjectID = "HFo-cy-zxI"; */ 117 | "HFo-cy-zxI.title" = "Show Spelling and Grammar"; 118 | 119 | /* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */ 120 | "HyV-fh-RgO.title" = "View"; 121 | 122 | /* Class = "NSMenuItem"; title = "Subscript"; ObjectID = "I0S-gh-46l"; */ 123 | "I0S-gh-46l.title" = "Subscript"; 124 | 125 | /* Class = "NSMenuItem"; title = "Open…"; ObjectID = "IAo-SY-fd9"; */ 126 | "IAo-SY-fd9.title" = "Open…"; 127 | 128 | /* Class = "NSMenuItem"; title = "Justify"; ObjectID = "J5U-5w-g23"; */ 129 | "J5U-5w-g23.title" = "Justify"; 130 | 131 | /* Class = "NSMenuItem"; title = "Use None"; ObjectID = "J7y-lM-qPV"; */ 132 | "J7y-lM-qPV.title" = "Use None"; 133 | 134 | /* Class = "NSMenuItem"; title = "Revert to Saved"; ObjectID = "KaW-ft-85H"; */ 135 | "KaW-ft-85H.title" = "Revert to Saved"; 136 | 137 | /* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ 138 | "Kd2-mp-pUS.title" = "Show All"; 139 | 140 | /* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */ 141 | "LE2-aR-0XJ.title" = "Bring All to Front"; 142 | 143 | /* Class = "NSMenuItem"; title = "Paste Ruler"; ObjectID = "LVM-kO-fVI"; */ 144 | "LVM-kO-fVI.title" = "Paste Ruler"; 145 | 146 | /* Class = "NSMenuItem"; title = "\tLeft to Right"; ObjectID = "Lbh-J2-qVU"; */ 147 | "Lbh-J2-qVU.title" = "\tLeft to Right"; 148 | 149 | /* Class = "NSMenuItem"; title = "Copy Ruler"; ObjectID = "MkV-Pr-PK5"; */ 150 | "MkV-Pr-PK5.title" = "Copy Ruler"; 151 | 152 | /* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ 153 | "NMo-om-nkz.title" = "Services"; 154 | 155 | /* Class = "NSMenuItem"; title = "\tDefault"; ObjectID = "Nop-cj-93Q"; */ 156 | "Nop-cj-93Q.title" = "\tDefault"; 157 | 158 | /* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */ 159 | "OY7-WF-poV.title" = "Minimize"; 160 | 161 | /* Class = "NSMenuItem"; title = "Baseline"; ObjectID = "OaQ-X3-Vso"; */ 162 | "OaQ-X3-Vso.title" = "Baseline"; 163 | 164 | /* Class = "NSMenuItem"; title = "Hide CalendarQuickView"; ObjectID = "Olw-nP-bQN"; */ 165 | "Olw-nP-bQN.title" = "Hide CalendarQuickView"; 166 | 167 | /* Class = "NSMenuItem"; title = "Find Previous"; ObjectID = "OwM-mh-QMV"; */ 168 | "OwM-mh-QMV.title" = "Find Previous"; 169 | 170 | /* Class = "NSMenuItem"; title = "Stop Speaking"; ObjectID = "Oyz-dy-DGm"; */ 171 | "Oyz-dy-DGm.title" = "Stop Speaking"; 172 | 173 | /* Class = "NSMenuItem"; title = "Bigger"; ObjectID = "Ptp-SP-VEL"; */ 174 | "Ptp-SP-VEL.title" = "Bigger"; 175 | 176 | /* Class = "NSMenuItem"; title = "Show Fonts"; ObjectID = "Q5e-8K-NDq"; */ 177 | "Q5e-8K-NDq.title" = "Show Fonts"; 178 | 179 | /* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */ 180 | "R4o-n2-Eq4.title" = "Zoom"; 181 | 182 | /* Class = "NSMenuItem"; title = "\tRight to Left"; ObjectID = "RB4-Sm-HuC"; */ 183 | "RB4-Sm-HuC.title" = "\tRight to Left"; 184 | 185 | /* Class = "NSMenuItem"; title = "Superscript"; ObjectID = "Rqc-34-cIF"; */ 186 | "Rqc-34-cIF.title" = "Superscript"; 187 | 188 | /* Class = "NSMenuItem"; title = "Select All"; ObjectID = "Ruw-6m-B2m"; */ 189 | "Ruw-6m-B2m.title" = "Select All"; 190 | 191 | /* Class = "NSMenuItem"; title = "Jump to Selection"; ObjectID = "S0p-oC-mLd"; */ 192 | "S0p-oC-mLd.title" = "Jump to Selection"; 193 | 194 | /* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */ 195 | "Td7-aD-5lo.title" = "Window"; 196 | 197 | /* Class = "NSMenuItem"; title = "Capitalize"; ObjectID = "UEZ-Bs-lqG"; */ 198 | "UEZ-Bs-lqG.title" = "Capitalize"; 199 | 200 | /* Class = "NSMenuItem"; title = "Center"; ObjectID = "VIY-Ag-zcb"; */ 201 | "VIY-Ag-zcb.title" = "Center"; 202 | 203 | /* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ 204 | "Vdr-fp-XzO.title" = "Hide Others"; 205 | 206 | /* Class = "NSMenuItem"; title = "Italic"; ObjectID = "Vjx-xi-njq"; */ 207 | "Vjx-xi-njq.title" = "Italic"; 208 | 209 | /* Class = "NSMenu"; title = "Edit"; ObjectID = "W48-6f-4Dl"; */ 210 | "W48-6f-4Dl.title" = "Edit"; 211 | 212 | /* Class = "NSMenuItem"; title = "Underline"; ObjectID = "WRG-CD-K1S"; */ 213 | "WRG-CD-K1S.title" = "Underline"; 214 | 215 | /* Class = "NSMenuItem"; title = "New"; ObjectID = "Was-JA-tGl"; */ 216 | "Was-JA-tGl.title" = "New"; 217 | 218 | /* Class = "NSMenuItem"; title = "Paste and Match Style"; ObjectID = "WeT-3V-zwk"; */ 219 | "WeT-3V-zwk.title" = "Paste and Match Style"; 220 | 221 | /* Class = "NSMenuItem"; title = "Find…"; ObjectID = "Xz5-n4-O0W"; */ 222 | "Xz5-n4-O0W.title" = "Find…"; 223 | 224 | /* Class = "NSMenuItem"; title = "Find and Replace…"; ObjectID = "YEy-JH-Tfz"; */ 225 | "YEy-JH-Tfz.title" = "Find and Replace…"; 226 | 227 | /* Class = "NSMenuItem"; title = "\tDefault"; ObjectID = "YGs-j5-SAR"; */ 228 | "YGs-j5-SAR.title" = "\tDefault"; 229 | 230 | /* Class = "NSMenuItem"; title = "Start Speaking"; ObjectID = "Ynk-f8-cLZ"; */ 231 | "Ynk-f8-cLZ.title" = "Start Speaking"; 232 | 233 | /* Class = "NSMenuItem"; title = "Align Left"; ObjectID = "ZM1-6Q-yy1"; */ 234 | "ZM1-6Q-yy1.title" = "Align Left"; 235 | 236 | /* Class = "NSMenuItem"; title = "Paragraph"; ObjectID = "ZvO-Gk-QUH"; */ 237 | "ZvO-Gk-QUH.title" = "Paragraph"; 238 | 239 | /* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */ 240 | "aTl-1u-JFS.title" = "Print…"; 241 | 242 | /* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */ 243 | "aUF-d1-5bR.title" = "Window"; 244 | 245 | /* Class = "NSMenu"; title = "Font"; ObjectID = "aXa-aM-Jaq"; */ 246 | "aXa-aM-Jaq.title" = "Font"; 247 | 248 | /* Class = "NSMenuItem"; title = "Use Default"; ObjectID = "agt-UL-0e3"; */ 249 | "agt-UL-0e3.title" = "Use Default"; 250 | 251 | /* Class = "NSMenuItem"; title = "Show Colors"; ObjectID = "bgn-CT-cEk"; */ 252 | "bgn-CT-cEk.title" = "Show Colors"; 253 | 254 | /* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */ 255 | "bib-Uj-vzu.title" = "File"; 256 | 257 | /* Class = "NSMenuItem"; title = "Use Selection for Find"; ObjectID = "buJ-ug-pKt"; */ 258 | "buJ-ug-pKt.title" = "Use Selection for Find"; 259 | 260 | /* Class = "NSMenu"; title = "Transformations"; ObjectID = "c8a-y6-VQd"; */ 261 | "c8a-y6-VQd.title" = "Transformations"; 262 | 263 | /* Class = "NSMenuItem"; title = "Use None"; ObjectID = "cDB-IK-hbR"; */ 264 | "cDB-IK-hbR.title" = "Use None"; 265 | 266 | /* Class = "NSMenuItem"; title = "Selection"; ObjectID = "cqv-fj-IhA"; */ 267 | "cqv-fj-IhA.title" = "Selection"; 268 | 269 | /* Class = "NSMenuItem"; title = "Smart Links"; ObjectID = "cwL-P1-jid"; */ 270 | "cwL-P1-jid.title" = "Smart Links"; 271 | 272 | /* Class = "NSMenuItem"; title = "Make Lower Case"; ObjectID = "d9M-CD-aMd"; */ 273 | "d9M-CD-aMd.title" = "Make Lower Case"; 274 | 275 | /* Class = "NSMenu"; title = "Text"; ObjectID = "d9c-me-L2H"; */ 276 | "d9c-me-L2H.title" = "Text"; 277 | 278 | /* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */ 279 | "dMs-cI-mzQ.title" = "File"; 280 | 281 | /* Class = "NSMenuItem"; title = "Undo"; ObjectID = "dRJ-4n-Yzg"; */ 282 | "dRJ-4n-Yzg.title" = "Undo"; 283 | 284 | /* Class = "NSMenuItem"; title = "Paste"; ObjectID = "gVA-U4-sdL"; */ 285 | "gVA-U4-sdL.title" = "Paste"; 286 | 287 | /* Class = "NSMenuItem"; title = "Smart Quotes"; ObjectID = "hQb-2v-fYv"; */ 288 | "hQb-2v-fYv.title" = "Smart Quotes"; 289 | 290 | /* Class = "NSMenuItem"; title = "Check Document Now"; ObjectID = "hz2-CU-CR7"; */ 291 | "hz2-CU-CR7.title" = "Check Document Now"; 292 | 293 | /* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ 294 | "hz9-B4-Xy5.title" = "Services"; 295 | 296 | /* Class = "NSMenuItem"; title = "Smaller"; ObjectID = "i1d-Er-qST"; */ 297 | "i1d-Er-qST.title" = "Smaller"; 298 | 299 | /* Class = "NSMenu"; title = "Baseline"; ObjectID = "ijk-EB-dga"; */ 300 | "ijk-EB-dga.title" = "Baseline"; 301 | 302 | /* Class = "NSMenuItem"; title = "Kern"; ObjectID = "jBQ-r6-VK2"; */ 303 | "jBQ-r6-VK2.title" = "Kern"; 304 | 305 | /* Class = "NSMenuItem"; title = "\tRight to Left"; ObjectID = "jFq-tB-4Kx"; */ 306 | "jFq-tB-4Kx.title" = "\tRight to Left"; 307 | 308 | /* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */ 309 | "jxT-CU-nIS.title" = "Format"; 310 | 311 | /* Class = "NSMenuItem"; title = "Show Sidebar"; ObjectID = "kIP-vf-haE"; */ 312 | "kIP-vf-haE.title" = "Show Sidebar"; 313 | 314 | /* Class = "NSMenuItem"; title = "Check Grammar With Spelling"; ObjectID = "mK6-2p-4JG"; */ 315 | "mK6-2p-4JG.title" = "Check Grammar With Spelling"; 316 | 317 | /* Class = "NSMenuItem"; title = "Ligatures"; ObjectID = "o6e-r0-MWq"; */ 318 | "o6e-r0-MWq.title" = "Ligatures"; 319 | 320 | /* Class = "NSMenu"; title = "Open Recent"; ObjectID = "oas-Oc-fiZ"; */ 321 | "oas-Oc-fiZ.title" = "Open Recent"; 322 | 323 | /* Class = "NSMenuItem"; title = "Loosen"; ObjectID = "ogc-rX-tC1"; */ 324 | "ogc-rX-tC1.title" = "Loosen"; 325 | 326 | /* Class = "NSMenuItem"; title = "Delete"; ObjectID = "pa3-QI-u2k"; */ 327 | "pa3-QI-u2k.title" = "Delete"; 328 | 329 | /* Class = "NSMenuItem"; title = "Save…"; ObjectID = "pxx-59-PXV"; */ 330 | "pxx-59-PXV.title" = "Save…"; 331 | 332 | /* Class = "NSMenuItem"; title = "Find Next"; ObjectID = "q09-fT-Sye"; */ 333 | "q09-fT-Sye.title" = "Find Next"; 334 | 335 | /* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */ 336 | "qIS-W8-SiK.title" = "Page Setup…"; 337 | 338 | /* Class = "NSMenuItem"; title = "Check Spelling While Typing"; ObjectID = "rbD-Rh-wIN"; */ 339 | "rbD-Rh-wIN.title" = "Check Spelling While Typing"; 340 | 341 | /* Class = "NSMenuItem"; title = "Smart Dashes"; ObjectID = "rgM-f4-ycn"; */ 342 | "rgM-f4-ycn.title" = "Smart Dashes"; 343 | 344 | /* Class = "NSMenuItem"; title = "Show Toolbar"; ObjectID = "snW-S8-Cw5"; */ 345 | "snW-S8-Cw5.title" = "Show Toolbar"; 346 | 347 | /* Class = "NSMenuItem"; title = "Data Detectors"; ObjectID = "tRr-pd-1PS"; */ 348 | "tRr-pd-1PS.title" = "Data Detectors"; 349 | 350 | /* Class = "NSMenuItem"; title = "Open Recent"; ObjectID = "tXI-mr-wws"; */ 351 | "tXI-mr-wws.title" = "Open Recent"; 352 | 353 | /* Class = "NSMenu"; title = "Kern"; ObjectID = "tlD-Oa-oAM"; */ 354 | "tlD-Oa-oAM.title" = "Kern"; 355 | 356 | /* Class = "NSMenu"; title = "CalendarQuickView"; ObjectID = "uQy-DD-JDr"; */ 357 | "uQy-DD-JDr.title" = "CalendarQuickView"; 358 | 359 | /* Class = "NSMenuItem"; title = "Cut"; ObjectID = "uRl-iY-unG"; */ 360 | "uRl-iY-unG.title" = "Cut"; 361 | 362 | /* Class = "NSMenuItem"; title = "Paste Style"; ObjectID = "vKC-jM-MkH"; */ 363 | "vKC-jM-MkH.title" = "Paste Style"; 364 | 365 | /* Class = "NSMenuItem"; title = "Show Ruler"; ObjectID = "vLm-3I-IUL"; */ 366 | "vLm-3I-IUL.title" = "Show Ruler"; 367 | 368 | /* Class = "NSMenuItem"; title = "Clear Menu"; ObjectID = "vNY-rz-j42"; */ 369 | "vNY-rz-j42.title" = "Clear Menu"; 370 | 371 | /* Class = "NSMenuItem"; title = "Make Upper Case"; ObjectID = "vmV-6d-7jI"; */ 372 | "vmV-6d-7jI.title" = "Make Upper Case"; 373 | 374 | /* Class = "NSMenu"; title = "Ligatures"; ObjectID = "w0m-vy-SC9"; */ 375 | "w0m-vy-SC9.title" = "Ligatures"; 376 | 377 | /* Class = "NSMenuItem"; title = "Align Right"; ObjectID = "wb2-vD-lq4"; */ 378 | "wb2-vD-lq4.title" = "Align Right"; 379 | 380 | /* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */ 381 | "wpr-3q-Mcd.title" = "Help"; 382 | 383 | /* Class = "NSMenuItem"; title = "Copy"; ObjectID = "x3v-GG-iWU"; */ 384 | "x3v-GG-iWU.title" = "Copy"; 385 | 386 | /* Class = "NSMenuItem"; title = "Use All"; ObjectID = "xQD-1f-W4t"; */ 387 | "xQD-1f-W4t.title" = "Use All"; 388 | 389 | /* Class = "NSMenuItem"; title = "Speech"; ObjectID = "xrE-MZ-jX0"; */ 390 | "xrE-MZ-jX0.title" = "Speech"; 391 | 392 | /* Class = "NSMenuItem"; title = "Show Substitutions"; ObjectID = "z6F-FW-3nz"; */ 393 | "z6F-FW-3nz.title" = "Show Substitutions"; 394 | -------------------------------------------------------------------------------- /CalendarWidget/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /CalendarWidget/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /CalendarWidget/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CalendarWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /CalendarWidget/CalendarWidget.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.personal-information.calendars 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CalendarWidget/CalendarWidget.intentdefinition: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | INEnums 6 | 7 | INIntentDefinitionModelVersion 8 | 1.2 9 | INIntentDefinitionNamespace 10 | 88xZPY 11 | INIntentDefinitionSystemVersion 12 | 20A294 13 | INIntentDefinitionToolsBuildVersion 14 | 12A6144 15 | INIntentDefinitionToolsVersion 16 | 12.0 17 | INIntents 18 | 19 | 20 | INIntentCategory 21 | information 22 | INIntentDescriptionID 23 | tVvJ9c 24 | INIntentEligibleForWidgets 25 | 26 | INIntentIneligibleForSuggestions 27 | 28 | INIntentName 29 | Configuration 30 | INIntentResponse 31 | 32 | INIntentResponseCodes 33 | 34 | 35 | INIntentResponseCodeName 36 | success 37 | INIntentResponseCodeSuccess 38 | 39 | 40 | 41 | INIntentResponseCodeName 42 | failure 43 | 44 | 45 | 46 | INIntentTitle 47 | Configuration 48 | INIntentTitleID 49 | gpCwrM 50 | INIntentType 51 | Custom 52 | INIntentVerb 53 | View 54 | 55 | 56 | INTypes 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /CalendarWidget/CalendarWidget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CalendarWidget.swift 3 | // CalendarWidget 4 | // 5 | // Created by Michael Ellis on 11/19/21. 6 | // 7 | 8 | import WidgetKit 9 | import SwiftUI 10 | import Intents 11 | 12 | struct Provider: IntentTimelineProvider { 13 | func placeholder(in context: Context) -> CalendarWidgetData { 14 | CalendarWidgetData(date: Date(), configuration: ConfigurationIntent()) 15 | } 16 | 17 | func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (CalendarWidgetData) -> ()) { 18 | let entry = CalendarWidgetData(date: Date(), configuration: configuration) 19 | completion(entry) 20 | } 21 | 22 | func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline) -> ()) { 23 | var entries: [CalendarWidgetData] = [] 24 | 25 | let currentDate = Date() 26 | // Current time and Current time + 1 hour 27 | for hourOffset in 0 ..< 2 { 28 | let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! 29 | let entry = CalendarWidgetData(date: entryDate, configuration: configuration) 30 | entries.append(entry) 31 | } 32 | // Today and the next 4 days 33 | for dayOffset in 0 ..< 5 { 34 | let entryDate = Calendar.current.date(byAdding: .day, value: dayOffset, to: currentDate)! 35 | let entry = CalendarWidgetData(date: entryDate, configuration: configuration) 36 | entries.append(entry) 37 | } 38 | 39 | let timeline = Timeline(entries: entries, policy: .atEnd) 40 | completion(timeline) 41 | } 42 | } 43 | 44 | struct CalendarWidgetData: TimelineEntry { 45 | let date: Date 46 | let configuration: ConfigurationIntent 47 | } 48 | 49 | @main 50 | struct CalendarWidget: Widget { 51 | let kind: String = "CalendarWidget" 52 | 53 | var body: some WidgetConfiguration { 54 | IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in 55 | WidgetCalendarView() 56 | } 57 | .configurationDisplayName("Current Month View") 58 | .description("This is a calendar view displaying the current month.") 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /CalendarWidget/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.widgetkit-extension 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CalendarWidget/WidgetCalendarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WidgetCalendarView.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/20/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WidgetCalendarView: View { 11 | 12 | let displayMonth = Date() 13 | let weekDayFormatter = DateFormatter.weekDayFormatter 14 | var days: [[Date]] = [] 15 | 16 | init() { 17 | let daysToDisplay = getGetCalendarDays().chunked(into: 7) 18 | self.days = daysToDisplay 19 | } 20 | 21 | var body: some View { 22 | GeometryReader { parent in 23 | let fontSize: Font = parent.size.height < 200 ? .caption : parent.size.height < 350 ? .body : .title2 24 | VStack(spacing: 0) { 25 | Spacer() 26 | HStack(spacing: 4) { 27 | ForEach(self.days.first ?? [], id: \.self) { date in 28 | Text(weekDayFormatter.string(from: date)) 29 | .frame(width: parent.size.height / 10, height: parent.size.height / 10) 30 | .font(fontSize) 31 | } 32 | } 33 | .foregroundColor(ColorStore.shared.titleTextColor) 34 | ForEach(getGetCalendarDays().chunked(into: 7), id: \.self) { weekDays in 35 | HStack(spacing: 4) { 36 | Spacer() 37 | ForEach(weekDays, id:\.self) { date in 38 | // Each individual day 39 | CalendarDay(date: date, fontSize: fontSize, cellSize: parent.size.height / 10, dayShape: .roundedSquare, month: self.displayMonth) 40 | .padding(.vertical, 2) 41 | } 42 | Spacer() 43 | } 44 | } 45 | Spacer() 46 | } 47 | } 48 | } 49 | 50 | /// Generates 6 weeks worth of days in an array 51 | public func getGetCalendarDays() -> [Date] { 52 | guard let monthInterval = Calendar.current.dateInterval(of: .month, for: Date()), 53 | let monthFirstWeek = Calendar.current.dateInterval(of: .weekOfMonth, for: monthInterval.start), 54 | let sixWeeksFromStart = Calendar.current.date(byAdding: .day, value: 7 * 6, to: monthFirstWeek.start) else { 55 | return [] 56 | } 57 | // get 6 weeks of days 58 | let dateInterval = DateInterval(start: monthFirstWeek.start, end: sixWeeksFromStart) 59 | return Calendar.current.generateDays(for: dateInterval) 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.5) 5 | rexml 6 | addressable (2.8.0) 7 | public_suffix (>= 2.0.2, < 5.0) 8 | artifactory (3.0.15) 9 | atomos (0.1.3) 10 | aws-eventstream (1.2.0) 11 | aws-partitions (1.530.0) 12 | aws-sdk-core (3.122.1) 13 | aws-eventstream (~> 1, >= 1.0.2) 14 | aws-partitions (~> 1, >= 1.525.0) 15 | aws-sigv4 (~> 1.1) 16 | jmespath (~> 1.0) 17 | aws-sdk-kms (1.51.0) 18 | aws-sdk-core (~> 3, >= 3.122.0) 19 | aws-sigv4 (~> 1.1) 20 | aws-sdk-s3 (1.105.1) 21 | aws-sdk-core (~> 3, >= 3.122.0) 22 | aws-sdk-kms (~> 1) 23 | aws-sigv4 (~> 1.4) 24 | aws-sigv4 (1.4.0) 25 | aws-eventstream (~> 1, >= 1.0.2) 26 | babosa (1.0.4) 27 | claide (1.0.3) 28 | colored (1.2) 29 | colored2 (3.1.2) 30 | commander (4.6.0) 31 | highline (~> 2.0.0) 32 | declarative (0.0.20) 33 | digest-crc (0.6.4) 34 | rake (>= 12.0.0, < 14.0.0) 35 | domain_name (0.5.20190701) 36 | unf (>= 0.0.5, < 1.0.0) 37 | dotenv (2.7.6) 38 | emoji_regex (3.2.3) 39 | excon (0.88.0) 40 | faraday (1.8.0) 41 | faraday-em_http (~> 1.0) 42 | faraday-em_synchrony (~> 1.0) 43 | faraday-excon (~> 1.1) 44 | faraday-httpclient (~> 1.0.1) 45 | faraday-net_http (~> 1.0) 46 | faraday-net_http_persistent (~> 1.1) 47 | faraday-patron (~> 1.0) 48 | faraday-rack (~> 1.0) 49 | multipart-post (>= 1.2, < 3) 50 | ruby2_keywords (>= 0.0.4) 51 | faraday-cookie_jar (0.0.7) 52 | faraday (>= 0.8.0) 53 | http-cookie (~> 1.0.0) 54 | faraday-em_http (1.0.0) 55 | faraday-em_synchrony (1.0.0) 56 | faraday-excon (1.1.0) 57 | faraday-httpclient (1.0.1) 58 | faraday-net_http (1.0.1) 59 | faraday-net_http_persistent (1.2.0) 60 | faraday-patron (1.0.0) 61 | faraday-rack (1.0.0) 62 | faraday_middleware (1.2.0) 63 | faraday (~> 1.0) 64 | fastimage (2.2.5) 65 | fastlane (2.197.0) 66 | CFPropertyList (>= 2.3, < 4.0.0) 67 | addressable (>= 2.8, < 3.0.0) 68 | artifactory (~> 3.0) 69 | aws-sdk-s3 (~> 1.0) 70 | babosa (>= 1.0.3, < 2.0.0) 71 | bundler (>= 1.12.0, < 3.0.0) 72 | colored 73 | commander (~> 4.6) 74 | dotenv (>= 2.1.1, < 3.0.0) 75 | emoji_regex (>= 0.1, < 4.0) 76 | excon (>= 0.71.0, < 1.0.0) 77 | faraday (~> 1.0) 78 | faraday-cookie_jar (~> 0.0.6) 79 | faraday_middleware (~> 1.0) 80 | fastimage (>= 2.1.0, < 3.0.0) 81 | gh_inspector (>= 1.1.2, < 2.0.0) 82 | google-apis-androidpublisher_v3 (~> 0.3) 83 | google-apis-playcustomapp_v1 (~> 0.1) 84 | google-cloud-storage (~> 1.31) 85 | highline (~> 2.0) 86 | json (< 3.0.0) 87 | jwt (>= 2.1.0, < 3) 88 | mini_magick (>= 4.9.4, < 5.0.0) 89 | multipart-post (~> 2.0.0) 90 | naturally (~> 2.2) 91 | optparse (~> 0.1.1) 92 | plist (>= 3.1.0, < 4.0.0) 93 | rubyzip (>= 2.0.0, < 3.0.0) 94 | security (= 0.1.3) 95 | simctl (~> 1.6.3) 96 | terminal-notifier (>= 2.0.0, < 3.0.0) 97 | terminal-table (>= 1.4.5, < 2.0.0) 98 | tty-screen (>= 0.6.3, < 1.0.0) 99 | tty-spinner (>= 0.8.0, < 1.0.0) 100 | word_wrap (~> 1.0.0) 101 | xcodeproj (>= 1.13.0, < 2.0.0) 102 | xcpretty (~> 0.3.0) 103 | xcpretty-travis-formatter (>= 0.0.3) 104 | gh_inspector (1.1.3) 105 | google-apis-androidpublisher_v3 (0.13.0) 106 | google-apis-core (>= 0.4, < 2.a) 107 | google-apis-core (0.4.1) 108 | addressable (~> 2.5, >= 2.5.1) 109 | googleauth (>= 0.16.2, < 2.a) 110 | httpclient (>= 2.8.1, < 3.a) 111 | mini_mime (~> 1.0) 112 | representable (~> 3.0) 113 | retriable (>= 2.0, < 4.a) 114 | rexml 115 | webrick 116 | google-apis-iamcredentials_v1 (0.8.0) 117 | google-apis-core (>= 0.4, < 2.a) 118 | google-apis-playcustomapp_v1 (0.6.0) 119 | google-apis-core (>= 0.4, < 2.a) 120 | google-apis-storage_v1 (0.9.0) 121 | google-apis-core (>= 0.4, < 2.a) 122 | google-cloud-core (1.6.0) 123 | google-cloud-env (~> 1.0) 124 | google-cloud-errors (~> 1.0) 125 | google-cloud-env (1.5.0) 126 | faraday (>= 0.17.3, < 2.0) 127 | google-cloud-errors (1.2.0) 128 | google-cloud-storage (1.34.1) 129 | addressable (~> 2.5) 130 | digest-crc (~> 0.4) 131 | google-apis-iamcredentials_v1 (~> 0.1) 132 | google-apis-storage_v1 (~> 0.1) 133 | google-cloud-core (~> 1.6) 134 | googleauth (>= 0.16.2, < 2.a) 135 | mini_mime (~> 1.0) 136 | googleauth (1.1.0) 137 | faraday (>= 0.17.3, < 2.0) 138 | jwt (>= 1.4, < 3.0) 139 | memoist (~> 0.16) 140 | multi_json (~> 1.11) 141 | os (>= 0.9, < 2.0) 142 | signet (>= 0.16, < 2.a) 143 | highline (2.0.3) 144 | http-cookie (1.0.4) 145 | domain_name (~> 0.5) 146 | httpclient (2.8.3) 147 | jmespath (1.4.0) 148 | json (2.6.1) 149 | jwt (2.3.0) 150 | memoist (0.16.2) 151 | mini_magick (4.11.0) 152 | mini_mime (1.1.2) 153 | multi_json (1.15.0) 154 | multipart-post (2.0.0) 155 | nanaimo (0.3.0) 156 | naturally (2.2.1) 157 | optparse (0.1.1) 158 | os (1.1.4) 159 | plist (3.6.0) 160 | public_suffix (4.0.6) 161 | rake (13.0.6) 162 | representable (3.1.1) 163 | declarative (< 0.1.0) 164 | trailblazer-option (>= 0.1.1, < 0.2.0) 165 | uber (< 0.2.0) 166 | retriable (3.1.2) 167 | rexml (3.2.5) 168 | rouge (2.0.7) 169 | ruby2_keywords (0.0.5) 170 | rubyzip (2.3.2) 171 | security (0.1.3) 172 | signet (0.16.0) 173 | addressable (~> 2.8) 174 | faraday (>= 0.17.3, < 2.0) 175 | jwt (>= 1.5, < 3.0) 176 | multi_json (~> 1.10) 177 | simctl (1.6.8) 178 | CFPropertyList 179 | naturally 180 | terminal-notifier (2.0.0) 181 | terminal-table (1.8.0) 182 | unicode-display_width (~> 1.1, >= 1.1.1) 183 | trailblazer-option (0.1.2) 184 | tty-cursor (0.7.1) 185 | tty-screen (0.8.1) 186 | tty-spinner (0.9.3) 187 | tty-cursor (~> 0.7) 188 | uber (0.1.0) 189 | unf (0.1.4) 190 | unf_ext 191 | unf_ext (0.0.8) 192 | unicode-display_width (1.8.0) 193 | webrick (1.7.0) 194 | word_wrap (1.0.0) 195 | xcodeproj (1.21.0) 196 | CFPropertyList (>= 2.3.3, < 4.0) 197 | atomos (~> 0.1.3) 198 | claide (>= 1.0.2, < 2.0) 199 | colored2 (~> 3.1) 200 | nanaimo (~> 0.3.0) 201 | rexml (~> 3.2.4) 202 | xcpretty (0.3.0) 203 | rouge (~> 2.0.7) 204 | xcpretty-travis-formatter (1.0.1) 205 | xcpretty (~> 0.2, >= 0.0.7) 206 | 207 | PLATFORMS 208 | x86_64-darwin-21 209 | 210 | DEPENDENCIES 211 | fastlane 212 | 213 | BUNDLED WITH 214 | 2.2.22 215 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Calendar Quick View 2 | ## Quick Menu Calendar in the mac app store 3 | 4 | ### An open source macOS calendar preview utility 5 | ### [Download from the Mac App Store](https://apps.apple.com/us/app/quick-menu-calendar/id1594094974) 6 | 7 | Visualizations are important, with this app you can view a calendar by clicking an icon in your menu bar! 8 | The dock icon is optional, the colors are optional, everything is customizable. 9 | 10 | Interested in customizing something even more? Fork this project and make a pull request, please! 11 | 12 | 13 | 14 | # Interested in contributing? 15 | 16 | [Please report issues, ask for features, etc.](https://github.com/michael94ellis/CalendarQuickView/issues/new) 17 | 18 | [Check out the Project for tasks to be performed](https://github.com/users/michael94ellis/projects/1) 19 | 20 | Work together, be kind, and leave things better than you found them. If you see something to improve please make a github issue, please reach out for guiadance or any questions you may have! 21 | 22 | -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/Shared/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/Shared/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/Shared/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/Shared/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/Shared/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/Shared/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michael94ellis/CalendarQuickView/80d6a8d90a40457cd5fb9cb5a5f488737b134150/Shared/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /Shared/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "32.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "64.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "128.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "256.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "512.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "1024.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Shared/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/contrast.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "6", 9 | "green" : "6", 10 | "red" : "6" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "light" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "6", 27 | "green" : "6", 28 | "red" : "6" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | }, 33 | { 34 | "appearances" : [ 35 | { 36 | "appearance" : "luminosity", 37 | "value" : "dark" 38 | } 39 | ], 40 | "color" : { 41 | "color-space" : "srgb", 42 | "components" : { 43 | "alpha" : "1.000", 44 | "blue" : "248", 45 | "green" : "248", 46 | "red" : "248" 47 | } 48 | }, 49 | "idiom" : "universal" 50 | } 51 | ], 52 | "info" : { 53 | "author" : "xcode", 54 | "version" : 1 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/coral.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x7F", 9 | "green" : "0x7F", 10 | "red" : "0xF6" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x5F", 27 | "green" : "0x5F", 28 | "red" : "0xE6" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/jet.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.047", 9 | "green" : "0.067", 10 | "red" : "0.102" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.933", 27 | "green" : "0.857", 28 | "red" : "0.863" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/jonquil.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.914", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/lavendar.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xEA", 9 | "green" : "0xE8", 10 | "red" : "0xF6" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xDA", 27 | "green" : "0xC8", 28 | "red" : "0xD6" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/mustard.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.031", 9 | "green" : "0.753", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/onyx.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.208", 9 | "green" : "0.212", 10 | "red" : "0.208" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "59", 27 | "green" : "62", 28 | "red" : "60" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/pink.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "193", 9 | "green" : "128", 10 | "red" : "249" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "157", 27 | "green" : "151", 28 | "red" : "247" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/rose.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x69", 9 | "green" : "0x5B", 10 | "red" : "0xF4" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x40", 27 | "green" : "0x40", 28 | "red" : "0xC3" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/sky.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.875", 9 | "green" : "0.692", 10 | "red" : "0.127" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.875", 27 | "green" : "0.824", 28 | "red" : "0.444" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/stone.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.596", 9 | "green" : "0.620", 10 | "red" : "0.624" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/tart.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x54", 9 | "green" : "0x54", 10 | "red" : "0xF3" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x24", 27 | "green" : "0x2F", 28 | "red" : "0xC3" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/vermillion.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x29", 9 | "green" : "0x3F", 10 | "red" : "0xE0" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x09", 27 | "green" : "0x0F", 28 | "red" : "0xD0" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Colors.xcassets/wood.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x01", 9 | "green" : "0x00", 10 | "red" : "0x5A" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x00", 27 | "green" : "0x00", 28 | "red" : "0x33" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/Extensions/Array-Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array-Extension.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/4/21. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Array { 11 | 12 | func chunked(into size: Int) -> [[Element]] { 13 | return stride(from: 0, to: count, by: size).map { 14 | Array(self[$0 ..< Swift.min($0 + size, count)]) 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Shared/Extensions/Calendar-Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Calendar-Extension.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 10/29/21. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Calendar { 11 | 12 | func generateDates( 13 | for dateInterval: DateInterval, 14 | matching components: DateComponents 15 | ) -> [Date] { 16 | var dates = [dateInterval.start] 17 | 18 | enumerateDates( 19 | startingAfter: dateInterval.start, 20 | matching: components, 21 | matchingPolicy: .nextTime 22 | ) { date, _, stop in 23 | guard let date = date else { 24 | return 25 | } 26 | 27 | guard date < dateInterval.end else { 28 | stop = true 29 | return 30 | } 31 | 32 | dates.append(date) 33 | } 34 | 35 | return dates 36 | } 37 | 38 | func generateDays(for dateInterval: DateInterval) -> [Date] { 39 | generateDates( 40 | for: dateInterval, 41 | matching: dateComponents([.hour, .minute, .second], from: dateInterval.start) 42 | ) 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Shared/Extensions/Date-Extention.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Date-Extention.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 10/29/21. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Date: RawRepresentable { 11 | 12 | private static let formatter = ISO8601DateFormatter() 13 | 14 | public var rawValue: String { 15 | Date.formatter.string(from: self) 16 | } 17 | 18 | public init?(rawValue: String) { 19 | self = Date.formatter.date(from: rawValue) ?? Date() 20 | } 21 | 22 | public func startOfMonth(using calendar: Calendar) -> Date { 23 | calendar.date(from: calendar.dateComponents([.year, .month], from: self)) ?? self 24 | } 25 | 26 | public mutating func incrementMonths(by n: Int, using calendar: Calendar = .current) { 27 | self = calendar.date(byAdding: .month, value: n, to: self) ?? self 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Shared/Extensions/DateFormatter-Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DateFormatter-Extension.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 10/29/21. 6 | // 7 | 8 | import Foundation 9 | 10 | extension DateFormatter { 11 | 12 | static let weekDayFormatter = DateFormatter(dateFormat: "EEEEE", calendar: Calendar.current) 13 | 14 | convenience init(dateFormat: String, calendar: Calendar) { 15 | self.init() 16 | self.dateFormat = dateFormat 17 | self.calendar = calendar 18 | } 19 | 20 | convenience init(dateFormat: String) { 21 | self.init() 22 | self.dateFormat = dateFormat 23 | self.calendar = Calendar.current 24 | } 25 | 26 | static var monthAndYear: DateFormatter { 27 | let formatter = DateFormatter() 28 | formatter.dateFormat = "MMMM yyyy" 29 | return formatter 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Shared/Extensions/View-Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // View-Extension.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/7/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | extension View { 11 | /// Applies the given transform if the given condition evaluates to `true`. 12 | /// - Parameters: 13 | /// - condition: The condition to evaluate. 14 | /// - transform: The transform to apply to the source `View`. 15 | /// - Returns: Either the original `View` or the modified `View` if the condition is `true`. 16 | @ViewBuilder func `if`(_ condition: Bool, transform: (Self) -> Content) -> some View { 17 | if condition { 18 | transform(self) 19 | } else { 20 | self 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Shared/Utilities.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String-Constants.swift 3 | // CalendarQuickView 4 | // 5 | // Created by Michael Ellis on 11/4/21. 6 | // 7 | 8 | import AppKit 9 | import SwiftUI 10 | 11 | struct AppStorageKeys { 12 | static let titleDateFormat = "titleDateFormat" 13 | static let eventDateFormat = "eventDateFormat" 14 | static let showWeekDayHeader = "showWeekDayHeader" 15 | 16 | static let selectedDay = "selectedDay" 17 | static let calendarSize = "calendarSize" 18 | static let calendarAccessGranted = "calendarAccessGranted" 19 | 20 | static let eventDisplayFromDate = "eventDisplayFromDate" 21 | static let numOfEventsToDisplay = "numOfEventsToDisplay" 22 | static let dayDisplayShape = "dayShapeDisplay" 23 | static let isEventFeatureEnabled = "isEventFeatureEnabled" 24 | static let showDockIcon = "showDockIcon" 25 | } 26 | 27 | enum CalendarSize: String, CaseIterable, Codable { 28 | case small 29 | case medium 30 | case large 31 | } 32 | 33 | enum TitleDateFormat: String, CaseIterable { 34 | case shortMonthOnly = "MMM" 35 | case shortMonthAndYear = "MMM YY" 36 | case fullMonthShortYear = "MMMM YY" 37 | case fullMonthOnly = "MMMM" 38 | case fullMonthAndYear = "MMMM YYYY" 39 | 40 | var displayName: String { 41 | switch(self) { 42 | case .shortMonthOnly: return "Short Month Only" 43 | case .shortMonthAndYear: return "Short Month and Year" 44 | case .fullMonthShortYear: return "Full Month Short Year" 45 | case .fullMonthOnly: return "Full Month Only" 46 | case .fullMonthAndYear: return "Full Month and Year" 47 | } 48 | } 49 | } 50 | 51 | /// This date format will be used in the Event List View, to display upcoming events 52 | enum EventDateFormat: String, CaseIterable { 53 | /// d 54 | case shortDayOnly = "d" 55 | /// dd 56 | case fullDayOnly = "dd" 57 | /// M/d 58 | case shortMonthAndDay = "M/d" 59 | /// M/dd 60 | case shortMonthFullDay = "M/dd" 61 | /// MM/dd 62 | case fullMonthAndDay = "MM/dd" 63 | /// d/M 64 | case shortDayAndMonth = "d/M" 65 | /// dd/MM 66 | case fullDayFullMonth = "dd/MM" 67 | /// The value to display in a Picker 68 | var displayName: String { 69 | switch(self) { 70 | case .shortDayOnly: return "Short Day Only (7)" 71 | case .fullDayOnly: return "Full Day Only (07)" 72 | case .shortMonthAndDay: return "Short Month and Day (3/7)" 73 | case .shortMonthFullDay: return "Short Month Full Day (3/07)" 74 | case .fullMonthAndDay: return "Full Month and Day (03/07)" 75 | case .shortDayAndMonth: return "Short Day and Month (7/3)" 76 | case .fullDayFullMonth: return "Full Day and Month (07/03)" 77 | } 78 | } 79 | } 80 | 81 | enum DayDisplayShape: String, CaseIterable { 82 | case square 83 | case roundedSquare 84 | case circle 85 | case none 86 | 87 | var shape: AnyShape { 88 | switch(self) { 89 | case .roundedSquare: 90 | return AnyShape(RoundedRectangle(cornerRadius: 4)) 91 | case .circle: 92 | return AnyShape(Circle()) 93 | case .square: 94 | return AnyShape(Rectangle()) 95 | case .none: 96 | return AnyShape(Rectangle()) 97 | } 98 | } 99 | 100 | var displayName: String { 101 | switch(self) { 102 | case .square: return "Square" 103 | case .roundedSquare: return "Rounded Square" 104 | case .circle: return "Circle" 105 | case .none: return "None" 106 | } 107 | } 108 | } 109 | 110 | struct AnyShape: Shape { 111 | init(_ wrapped: S) { 112 | _path = { rect in 113 | let path = wrapped.path(in: rect) 114 | return path 115 | } 116 | } 117 | 118 | func path(in rect: CGRect) -> Path { 119 | return _path(rect) 120 | } 121 | 122 | private let _path: (CGRect) -> Path 123 | } 124 | --------------------------------------------------------------------------------