From 7c2de764b48f7643fe839b55d0179d0b19cf579e Mon Sep 17 00:00:00 2001 From: Trey t Date: Sat, 15 Jan 2022 18:05:48 -0600 Subject: [PATCH] work around widgets ... not sure if they work --- Feels.xcodeproj/project.pbxproj | 20 +- .../xcschemes/xcschememanagement.plist | 4 +- .../average.imageset/Contents.json | 24 ++ .../average.imageset/meh-regular.svg | 1 + .../bad.imageset/Contents.json | 24 ++ .../bad.imageset/frown-regular.svg | 1 + .../good.imageset/Contents.json | 24 ++ .../good.imageset/grin-regular.svg | 1 + .../great.imageset/Contents.json | 24 ++ .../great.imageset/smile-beam-regular.svg | 1 + .../horrible.imageset/Contents.json | 24 ++ .../horrible.imageset/sad-tear-regular.svg | 1 + .../missing.imageset/Contents.json | 21 ++ .../missing.imageset/exclamation-solid.svg | 1 + FeelsWidget/FeelsWidget.swift | 321 +++++++++++------- Shared/AppDelegate.swift | 12 +- .../missing.imageset/Contents.json | 2 +- .../Screen Shot 2022-01-13 at 5.02.34 PM.png | Bin 6819 -> 0 bytes .../missing.imageset/exclamation-solid.svg | 1 + Shared/Persistence.swift | 45 +-- Shared/Random.swift | 2 +- Shared/views/AddMoodHeaderView.swift | 18 +- Shared/views/FilterView.swift | 2 +- 23 files changed, 375 insertions(+), 199 deletions(-) create mode 100644 FeelsWidget/Assets.xcassets/average.imageset/Contents.json create mode 100644 FeelsWidget/Assets.xcassets/average.imageset/meh-regular.svg create mode 100644 FeelsWidget/Assets.xcassets/bad.imageset/Contents.json create mode 100644 FeelsWidget/Assets.xcassets/bad.imageset/frown-regular.svg create mode 100644 FeelsWidget/Assets.xcassets/good.imageset/Contents.json create mode 100644 FeelsWidget/Assets.xcassets/good.imageset/grin-regular.svg create mode 100644 FeelsWidget/Assets.xcassets/great.imageset/Contents.json create mode 100644 FeelsWidget/Assets.xcassets/great.imageset/smile-beam-regular.svg create mode 100644 FeelsWidget/Assets.xcassets/horrible.imageset/Contents.json create mode 100644 FeelsWidget/Assets.xcassets/horrible.imageset/sad-tear-regular.svg create mode 100644 FeelsWidget/Assets.xcassets/missing.imageset/Contents.json create mode 100644 FeelsWidget/Assets.xcassets/missing.imageset/exclamation-solid.svg delete mode 100644 Shared/Assets.xcassets/missing.imageset/Screen Shot 2022-01-13 at 5.02.34 PM.png create mode 100644 Shared/Assets.xcassets/missing.imageset/exclamation-solid.svg diff --git a/Feels.xcodeproj/project.pbxproj b/Feels.xcodeproj/project.pbxproj index 33d2ea0..ac2183e 100644 --- a/Feels.xcodeproj/project.pbxproj +++ b/Feels.xcodeproj/project.pbxproj @@ -7,13 +7,14 @@ objects = { /* Begin PBXBuildFile section */ - 1C412080278E23CC00D9153A /* Charts in Frameworks */ = {isa = PBXBuildFile; productRef = 1C41207F278E23CC00D9153A /* Charts */; }; 1C412082278F2B8800D9153A /* FilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C412081278F2B8800D9153A /* FilterView.swift */; }; 1C412083278F2B8800D9153A /* FilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C412081278F2B8800D9153A /* FilterView.swift */; }; 1C683FCA2792281400745862 /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C683FC92792281400745862 /* Stats.swift */; }; 1C683FCB2792281400745862 /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C683FC92792281400745862 /* Stats.swift */; }; 1C683FCC2792281400745862 /* Stats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C683FC92792281400745862 /* Stats.swift */; }; 1C744F2C278CE15600953A57 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C744F2B278CE15600953A57 /* AppDelegate.swift */; }; + 1CA2662A2793843200C0E12C /* Charts in Frameworks */ = {isa = PBXBuildFile; productRef = 1CA266292793843200C0E12C /* Charts */; }; + 1CA2662D2793908700C0E12C /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90AEF278C7DDF001C4FEA /* Persistence.swift */; }; 1CC469AA278F30A0003E0C6E /* BGTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CC469A9278F30A0003E0C6E /* BGTask.swift */; }; 1CC469AC27907D48003E0C6E /* CircleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CC469AB27907D48003E0C6E /* CircleView.swift */; }; 1CD90B07278C7DE0001C4FEA /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90B06278C7DE0001C4FEA /* Tests_iOS.swift */; }; @@ -25,7 +26,6 @@ 1CD90B18278C7DE0001C4FEA /* FeelsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90AED278C7DDF001C4FEA /* FeelsApp.swift */; }; 1CD90B19278C7DE0001C4FEA /* FeelsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90AED278C7DDF001C4FEA /* FeelsApp.swift */; }; 1CD90B1C278C7DE0001C4FEA /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90AEF278C7DDF001C4FEA /* Persistence.swift */; }; - 1CD90B1D278C7DE0001C4FEA /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90AEF278C7DDF001C4FEA /* Persistence.swift */; }; 1CD90B1E278C7DE0001C4FEA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1CD90AF0278C7DE0001C4FEA /* Assets.xcassets */; }; 1CD90B1F278C7DE0001C4FEA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1CD90AF0278C7DE0001C4FEA /* Assets.xcassets */; }; 1CD90B37278C7E38001C4FEA /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90B32278C7E38001C4FEA /* SettingsView.swift */; }; @@ -45,7 +45,6 @@ 1CD90B52278C7E7A001C4FEA /* FeelsWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90B4E278C7E7A001C4FEA /* FeelsWidget.intentdefinition */; }; 1CD90B53278C7E7A001C4FEA /* FeelsWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90B4E278C7E7A001C4FEA /* FeelsWidget.intentdefinition */; }; 1CD90B56278C7E7A001C4FEA /* FeelsWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 1CD90B45278C7E7A001C4FEA /* FeelsWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 1CD90B5B278C7E91001C4FEA /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90AEF278C7DDF001C4FEA /* Persistence.swift */; }; 1CD90B5D278C7EAD001C4FEA /* Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90B5C278C7EAD001C4FEA /* Random.swift */; }; 1CD90B5E278C7EAD001C4FEA /* Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90B5C278C7EAD001C4FEA /* Random.swift */; }; 1CD90B5F278C7EAD001C4FEA /* Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD90B5C278C7EAD001C4FEA /* Random.swift */; }; @@ -149,7 +148,7 @@ buildActionMask = 2147483647; files = ( 1CD90B6C278C7F78001C4FEA /* CloudKit.framework in Frameworks */, - 1C412080278E23CC00D9153A /* Charts in Frameworks */, + 1CA2662A2793843200C0E12C /* Charts in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -324,7 +323,7 @@ ); name = "Feels (iOS)"; packageProductDependencies = ( - 1C41207F278E23CC00D9153A /* Charts */, + 1CA266292793843200C0E12C /* Charts */, ); productName = "Feels (iOS)"; productReference = 1CD90AF5278C7DE0001C4FEA /* Feels.app */; @@ -439,7 +438,7 @@ ); mainGroup = 1CD90AE5278C7DDF001C4FEA; packageReferences = ( - 1C41207E278E23CB00D9153A /* XCRemoteSwiftPackageReference "Charts" */, + 1CA266282793843200C0E12C /* XCRemoteSwiftPackageReference "Charts" */, ); productRefGroup = 1CD90AF6278C7DE0001C4FEA /* Products */; projectDirPath = ""; @@ -535,7 +534,6 @@ 1CD90B38278C7E38001C4FEA /* SettingsView.swift in Sources */, 1CD90B67278C7EBA001C4FEA /* MoodEntryExtension.swift in Sources */, 1CD90B77278C8119001C4FEA /* LocalNotification.swift in Sources */, - 1CD90B1D278C7DE0001C4FEA /* Persistence.swift in Sources */, 1CD90B19278C7DE0001C4FEA /* FeelsApp.swift in Sources */, 1CD90B5E278C7EAD001C4FEA /* Random.swift in Sources */, ); @@ -565,8 +563,8 @@ buildActionMask = 2147483647; files = ( 1CD90B65278C7EBA001C4FEA /* Mood.swift in Sources */, + 1CA2662D2793908700C0E12C /* Persistence.swift in Sources */, 1CD90B5F278C7EAD001C4FEA /* Random.swift in Sources */, - 1CD90B5B278C7E91001C4FEA /* Persistence.swift in Sources */, 1CD90B68278C7EBA001C4FEA /* MoodEntryExtension.swift in Sources */, 1CD90B71278C80CA001C4FEA /* Feels.xcdatamodeld in Sources */, 1C683FCB2792281400745862 /* Stats.swift in Sources */, @@ -1040,7 +1038,7 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 1C41207E278E23CB00D9153A /* XCRemoteSwiftPackageReference "Charts" */ = { + 1CA266282793843200C0E12C /* XCRemoteSwiftPackageReference "Charts" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/danielgindi/Charts"; requirement = { @@ -1051,9 +1049,9 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 1C41207F278E23CC00D9153A /* Charts */ = { + 1CA266292793843200C0E12C /* Charts */ = { isa = XCSwiftPackageProductDependency; - package = 1C41207E278E23CB00D9153A /* XCRemoteSwiftPackageReference "Charts" */; + package = 1CA266282793843200C0E12C /* XCRemoteSwiftPackageReference "Charts" */; productName = Charts; }; /* End XCSwiftPackageProductDependency section */ diff --git a/Feels.xcodeproj/xcuserdata/treyt.xcuserdatad/xcschemes/xcschememanagement.plist b/Feels.xcodeproj/xcuserdata/treyt.xcuserdatad/xcschemes/xcschememanagement.plist index ff9be8c..ed7ab37 100644 --- a/Feels.xcodeproj/xcuserdata/treyt.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Feels.xcodeproj/xcuserdata/treyt.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,12 @@ Feels (iOS).xcscheme_^#shared#^_ orderHint - 0 + 1 Feels (macOS).xcscheme_^#shared#^_ orderHint - 1 + 0 FeelsWidgetExtension.xcscheme_^#shared#^_ diff --git a/FeelsWidget/Assets.xcassets/average.imageset/Contents.json b/FeelsWidget/Assets.xcassets/average.imageset/Contents.json new file mode 100644 index 0000000..00fb6a2 --- /dev/null +++ b/FeelsWidget/Assets.xcassets/average.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "meh-regular.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/FeelsWidget/Assets.xcassets/average.imageset/meh-regular.svg b/FeelsWidget/Assets.xcassets/average.imageset/meh-regular.svg new file mode 100644 index 0000000..9ad9cf9 --- /dev/null +++ b/FeelsWidget/Assets.xcassets/average.imageset/meh-regular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FeelsWidget/Assets.xcassets/bad.imageset/Contents.json b/FeelsWidget/Assets.xcassets/bad.imageset/Contents.json new file mode 100644 index 0000000..a8ac09d --- /dev/null +++ b/FeelsWidget/Assets.xcassets/bad.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "frown-regular.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/FeelsWidget/Assets.xcassets/bad.imageset/frown-regular.svg b/FeelsWidget/Assets.xcassets/bad.imageset/frown-regular.svg new file mode 100644 index 0000000..e32249b --- /dev/null +++ b/FeelsWidget/Assets.xcassets/bad.imageset/frown-regular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FeelsWidget/Assets.xcassets/good.imageset/Contents.json b/FeelsWidget/Assets.xcassets/good.imageset/Contents.json new file mode 100644 index 0000000..a685e3c --- /dev/null +++ b/FeelsWidget/Assets.xcassets/good.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "grin-regular.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/FeelsWidget/Assets.xcassets/good.imageset/grin-regular.svg b/FeelsWidget/Assets.xcassets/good.imageset/grin-regular.svg new file mode 100644 index 0000000..380aed4 --- /dev/null +++ b/FeelsWidget/Assets.xcassets/good.imageset/grin-regular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FeelsWidget/Assets.xcassets/great.imageset/Contents.json b/FeelsWidget/Assets.xcassets/great.imageset/Contents.json new file mode 100644 index 0000000..f3c745f --- /dev/null +++ b/FeelsWidget/Assets.xcassets/great.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "smile-beam-regular.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/FeelsWidget/Assets.xcassets/great.imageset/smile-beam-regular.svg b/FeelsWidget/Assets.xcassets/great.imageset/smile-beam-regular.svg new file mode 100644 index 0000000..3c09689 --- /dev/null +++ b/FeelsWidget/Assets.xcassets/great.imageset/smile-beam-regular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FeelsWidget/Assets.xcassets/horrible.imageset/Contents.json b/FeelsWidget/Assets.xcassets/horrible.imageset/Contents.json new file mode 100644 index 0000000..d7421a5 --- /dev/null +++ b/FeelsWidget/Assets.xcassets/horrible.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "sad-tear-regular.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/FeelsWidget/Assets.xcassets/horrible.imageset/sad-tear-regular.svg b/FeelsWidget/Assets.xcassets/horrible.imageset/sad-tear-regular.svg new file mode 100644 index 0000000..edae2d2 --- /dev/null +++ b/FeelsWidget/Assets.xcassets/horrible.imageset/sad-tear-regular.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FeelsWidget/Assets.xcassets/missing.imageset/Contents.json b/FeelsWidget/Assets.xcassets/missing.imageset/Contents.json new file mode 100644 index 0000000..c82dff9 --- /dev/null +++ b/FeelsWidget/Assets.xcassets/missing.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "exclamation-solid.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FeelsWidget/Assets.xcassets/missing.imageset/exclamation-solid.svg b/FeelsWidget/Assets.xcassets/missing.imageset/exclamation-solid.svg new file mode 100644 index 0000000..32de166 --- /dev/null +++ b/FeelsWidget/Assets.xcassets/missing.imageset/exclamation-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FeelsWidget/FeelsWidget.swift b/FeelsWidget/FeelsWidget.swift index 4b4ea31..ab0b98a 100644 --- a/FeelsWidget/FeelsWidget.swift +++ b/FeelsWidget/FeelsWidget.swift @@ -10,39 +10,97 @@ import SwiftUI import Intents import CoreData +class WatchTimelineView: Identifiable { + let id = UUID() + let image: Image + let date: Date + let color: Color + + init(image: Image, date: Date, color: Color) { + self.image = image + self.date = date + self.color = color + } +} + +struct TimeLineCreator { + static func getData() -> [MoodEntry] { + let dateAtEnd = Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: Date())! + var tenDaysAgo = Calendar.current.date(byAdding: .day, value: -10, to: dateAtEnd)! + tenDaysAgo = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: tenDaysAgo)! + let moodEntry = PersistenceController.shared.getData(startDate: tenDaysAgo, endDate: dateAtEnd, includedDays: [1,2,3,4,5,6,7]) + return moodEntry + } + + static func createTimeLineViews(fromEntries: [MoodEntry]) -> [WatchTimelineView] { + var returnViews = [WatchTimelineView]() + + for pastDays in 0...10 { + let pastDate = Calendar.current.date(byAdding: .day, value: -pastDays, to: Date())! + + if let item = fromEntries.filter({ entry in + let components = Calendar.current.dateComponents([.day, .month, .year], from: pastDate) + let day = components.day + let month = components.month + let year = components.year + + let entryComponents = Calendar.current.dateComponents([.day, .month, .year], from: entry.forDate!) + let entryDay = entryComponents.day + let entryMonth = entryComponents.month + let entryYear = entryComponents.year + + return day == entryDay && month == entryMonth && year == entryYear + }).first { + let timeLineView = WatchTimelineView(image: item.mood.icon, date: pastDate, color: item.mood.color) + returnViews.append(timeLineView) + } else { + let timeLineView = WatchTimelineView(image: Mood.missing.icon, date: pastDate, color: Mood.missing.color) + returnViews.append(timeLineView) + } + } + return returnViews + } +} + struct Provider: IntentTimelineProvider { /* placeholder for widget, no data gets redacted auto */ func placeholder(in context: Context) -> SimpleEntry { - let date = Date() - let moodEntry = PersistenceController.shared.moodEntries(forStartDate: date, count: 10) - return SimpleEntry(date: date, configuration: ConfigurationIntent(), mood: moodEntry) + var sampleViews = [WatchTimelineView]() + for pastDay in 0...10 { + let pastDate = Calendar.current.date(byAdding: .day, value: -pastDay, to: Date())! + let mood = Mood.allValues.randomElement()! + sampleViews.append( WatchTimelineView(image: mood.icon, date: pastDate, color: mood.color) ) + } + return SimpleEntry(date: Date(), configuration: ConfigurationIntent(), timeLineViews: sampleViews) } func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) { + var timeLineViews = [WatchTimelineView]() + if context.isPreview { - + for pastDay in 0...10 { + let pastDate = Calendar.current.date(byAdding: .day, value: -pastDay, to: Date())! + let mood = Mood.allValues.randomElement()! + timeLineViews.append( WatchTimelineView(image: mood.icon, date: pastDate, color: mood.color) ) + } + } else { + let data = TimeLineCreator.getData() + timeLineViews = TimeLineCreator.createTimeLineViews(fromEntries: data) } - var calendar = Calendar.current - calendar.timeZone = NSTimeZone.local - let todayStart = calendar.startOfDay(for: Date()) - let userEntries = PersistenceController.shared.moodEntries(forStartDate: todayStart, count: 10) - - let entry = SimpleEntry(date: Date(), configuration: configuration, mood: userEntries) + let entry = SimpleEntry(date: Date(), configuration: configuration, timeLineViews: timeLineViews) completion(entry) } func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline) -> ()) { - var calendar = Calendar.current - calendar.timeZone = NSTimeZone.local - let todayStart = calendar.startOfDay(for: Date()) - let userEntries = PersistenceController.shared.moodEntries(forStartDate: todayStart, count: 10) + let data = TimeLineCreator.getData() + let views = TimeLineCreator.createTimeLineViews(fromEntries: data) - let entry = SimpleEntry(date: Date(), configuration: configuration, mood: userEntries) - let timeline = Timeline(entries: [entry], policy: .after(Random.widgetUpdateTime)) + let entry = SimpleEntry(date: Date(), configuration: configuration, timeLineViews: views) + let timeline = Timeline(entries: [entry], policy: .after(Random.tomorrowMidnightThirty)) completion(timeline) } } @@ -50,13 +108,13 @@ struct Provider: IntentTimelineProvider { struct SimpleEntry: TimelineEntry { let date: Date let configuration: ConfigurationIntent - let mood: [MoodEntry] + let timeLineViews: [WatchTimelineView] let showStats: Bool - init(date: Date, configuration: ConfigurationIntent, mood: [MoodEntry], showStats: Bool = false) { + init(date: Date, configuration: ConfigurationIntent, timeLineViews: [WatchTimelineView], showStats: Bool = false) { self.date = date self.configuration = configuration - self.mood = mood + self.timeLineViews = timeLineViews self.showStats = showStats } } @@ -71,19 +129,21 @@ struct FeelsWidgetEntryView : View { var body: some View { ZStack { Color(UIColor.systemBackground) - switch family { case .systemSmall: SmallWidgetView(entry: entry) case .systemMedium: MediumWidgetView(entry: entry) case .systemLarge: - LargeWidgetView(entry: entry) + MediumWidgetView(entry: entry) case .systemExtraLarge: - LargeWidgetView(entry: entry) + MediumWidgetView(entry: entry) @unknown default: fatalError() } + }.onReceive(NotificationCenter.default.publisher(for: .NSPersistentStoreRemoteChange)) { _ in + // make sure you don't call this too often + WidgetCenter.shared.reloadAllTimelines() } } } @@ -92,14 +152,55 @@ struct SmallWidgetView: View { var entry: Provider.Entry var body: some View { - VStack { - if let first = entry.mood.first { - EntryCardCollectionView(moodEntries: Array([first])) - .padding() - } else { - Text("🤷‍♂️") - .font(.system(size: 50)) + ZStack { + Color(UIColor.secondarySystemBackground) + HStack { + ForEach([entry.timeLineViews.first!]) { watchView in + EntryCard(timeLineView: watchView) + } } + .padding() + } + .clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous)) + .frame(minHeight: 0, maxHeight: 55) + .padding() + } +} + +struct TimeHeaderView: View { + let startDate: Date + let endDate: Date + + var formatter: DateFormatter { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .medium + return dateFormatter + } + + var body: some View { + HStack { + Text(startDate, formatter: formatter) + .font(.system(.footnote)) + Text(" - ") + .font(.system(.footnote)) + Text(endDate, formatter: formatter) + .font(.system(.footnote)) + } + } +} + +struct TimeBodyView: View { + let group: [WatchTimelineView] + + var body: some View { + ZStack { + Color(UIColor.secondarySystemBackground) + HStack { + ForEach(group) { watchView in + EntryCard(timeLineView: watchView) + } + } + .padding() } } } @@ -107,32 +208,20 @@ struct SmallWidgetView: View { struct MediumWidgetView: View { var entry: Provider.Entry - var formatter: DateFormatter { - let dateFormatter = DateFormatter() - dateFormatter.dateStyle = .medium - return dateFormatter - } - - var firstGroup: [MoodEntry] { - Array(self.entry.mood.prefix(5)) + var firstGroup: [WatchTimelineView] { + Array(self.entry.timeLineViews.prefix(5)) } var body: some View { VStack { Spacer() - HStack { - Text(firstGroup.first?.forDate ?? Date(), formatter: formatter) - .font(.system(.footnote)) - Text(" - ") - .font(.system(.footnote)) - Text(firstGroup.last?.forDate ?? Date(), formatter: formatter) - .font(.system(.footnote)) - } - .frame(minWidth: 0, maxWidth: .infinity) - .multilineTextAlignment(.leading) + TimeHeaderView(startDate: firstGroup.first!.date, endDate: firstGroup.last!.date) + .frame(minWidth: 0, maxWidth: .infinity) + .multilineTextAlignment(.leading) - EntryCardCollectionView(moodEntries: firstGroup) + TimeBodyView(group: firstGroup) + .clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous)) .frame(minHeight: 0, maxHeight: 55) .padding() @@ -141,86 +230,47 @@ struct MediumWidgetView: View { } } -struct LargeWidgetView: View { - var entry: Provider.Entry - - var formatter: DateFormatter { - let dateFormatter = DateFormatter() - dateFormatter.dateStyle = .medium - return dateFormatter - } - - var firstGroup: [MoodEntry] { - Array(self.entry.mood.prefix(5)) - } - - var lastGroup: [MoodEntry] { - Array(self.entry.mood.suffix(5)) - } - - - var body: some View { - VStack { - Spacer() - - HStack { - Text(firstGroup.first?.forDate ?? Date(), formatter: formatter) - .font(.system(.footnote)) - Text(" - ") - .font(.system(.footnote)) - Text(firstGroup.last?.forDate ?? Date(), formatter: formatter) - .font(.system(.footnote)) - } - .frame(minWidth: 0, maxWidth: .infinity) - .multilineTextAlignment(.leading) - - EntryCardCollectionView(moodEntries: firstGroup) - .frame(minHeight: 0, maxHeight: 55) - .padding() - - Spacer() - - HStack { - Text(lastGroup.first?.forDate ?? Date(), formatter: formatter) - .font(.system(.footnote)) - Text(" - ") - Text(lastGroup.last?.forDate ?? Date(), formatter: formatter) - .font(.system(.footnote)) - } - .frame(minWidth: 0, maxWidth: .infinity) - .multilineTextAlignment(.leading) - - EntryCardCollectionView(moodEntries: lastGroup) - .frame(minHeight: 0, maxHeight: 55) - .padding() - - Spacer() - } - } -} +//struct LargeWidgetView: View { +// var entry: Provider.Entry +// +// var formatter: DateFormatter { +// let dateFormatter = DateFormatter() +// dateFormatter.dateStyle = .medium +// return dateFormatter +// } +// +// +// var body: some View { +// VStack { +// Spacer() +// +// ForEach([Array(self.entry.timeLineViews.prefix(5)), Array(self.entry.timeLineViews.suffix(5))]) { group in +// +// TimeHeaderView(startDate: group.first!, endDate: group.last!) +// .frame(minWidth: 0, maxWidth: .infinity) +// .multilineTextAlignment(.leading) +// +// TimeBodyView(group: group) +// .clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous)) +// .frame(minHeight: 0, maxHeight: 55) +// .padding() +// +// Spacer() +// } +// } +// } +//} -struct EntryCardCollectionView: View { - var moodEntries: [MoodEntry] - - var body: some View { - ZStack { - Color(UIColor.secondarySystemBackground) - HStack { - ForEach(moodEntries) { mood in - EntryCard(moodEntry: mood) - } - } - .padding() - } - .clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous)) - } -} struct EntryCard: View { - var moodEntry: MoodEntry + var timeLineView: WatchTimelineView var body: some View { - moodEntry.mood.icon.font(.system(size: 50)) + timeLineView.image + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 50, height: 50, alignment: .center) + .foregroundColor(timeLineView.color) } } @@ -236,30 +286,37 @@ struct FeelsWidget: Widget { } .configurationDisplayName("Feels") .description("") - .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) + .supportedFamilies([.systemSmall, .systemMedium]) } } struct FeelsWidget_Previews: PreviewProvider { + static var data: [WatchTimelineView] { + var data = PersistenceController.shared.randomEntries(count: 10) + data.remove(at: 2) + let views = TimeLineCreator.createTimeLineViews(fromEntries: data) + return views + } + static var previews: some View { Group { FeelsWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent(), - mood: PersistenceController.shared.randomEntries(count: 1))) + timeLineViews: FeelsWidget_Previews.data)) .previewContext(WidgetPreviewContext(family: .systemSmall)) .environment(\.sizeCategory, .small) FeelsWidgetEntryView(entry: SimpleEntry(date: Date(), configuration: ConfigurationIntent(), - mood: PersistenceController.shared.randomEntries(count: 3))) + timeLineViews: FeelsWidget_Previews.data)) .previewContext(WidgetPreviewContext(family: .systemMedium)) .environment(\.sizeCategory, .medium) - - FeelsWidgetEntryView(entry: SimpleEntry(date: Date(), - configuration: ConfigurationIntent(), - mood: PersistenceController.shared.randomEntries(count: 10))) - .previewContext(WidgetPreviewContext(family: .systemLarge)) - .environment(\.sizeCategory, .large) +// +// FeelsWidgetEntryView(entry: SimpleEntry(date: Date(), +// configuration: ConfigurationIntent(), +// timeLineViews: FeelsWidget_Previews.data)) +// .previewContext(WidgetPreviewContext(family: .systemLarge)) +// .environment(\.sizeCategory, .large) } } } diff --git a/Shared/AppDelegate.swift b/Shared/AppDelegate.swift index 97eff28..84649a7 100644 --- a/Shared/AppDelegate.swift +++ b/Shared/AppDelegate.swift @@ -12,21 +12,15 @@ import WidgetKit // AppDelegate.swift class AppDelegate: NSObject, UIApplicationDelegate { + + + func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { // PersistenceController.shared.clearDB() - NotificationCenter.default.addObserver(self, - selector: #selector(fetchChanges), - name: .NSPersistentStoreRemoteChange, - object: PersistenceController.shared.container.persistentStoreCoordinator) - application.registerForRemoteNotifications() UNUserNotificationCenter.current().delegate = self return true } - - @objc func fetchChanges(note: Notification) { - WidgetCenter.shared.reloadAllTimelines() - } } extension AppDelegate: UNUserNotificationCenterDelegate { diff --git a/Shared/Assets.xcassets/missing.imageset/Contents.json b/Shared/Assets.xcassets/missing.imageset/Contents.json index dabdec4..c82dff9 100644 --- a/Shared/Assets.xcassets/missing.imageset/Contents.json +++ b/Shared/Assets.xcassets/missing.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Screen Shot 2022-01-13 at 5.02.34 PM.png", + "filename" : "exclamation-solid.svg", "idiom" : "universal", "scale" : "1x" }, diff --git a/Shared/Assets.xcassets/missing.imageset/Screen Shot 2022-01-13 at 5.02.34 PM.png b/Shared/Assets.xcassets/missing.imageset/Screen Shot 2022-01-13 at 5.02.34 PM.png deleted file mode 100644 index f2e032602e875df1481ec9f7a3e6b25e3bcd6873..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6819 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 dOfKUQsiq*6b)EJt