play with widgets
add different widgets for large icon and last day made images smaller to avoid memory issues
This commit is contained in:
@@ -26,21 +26,22 @@ class WatchTimelineView: Identifiable {
|
||||
}
|
||||
|
||||
struct TimeLineCreator {
|
||||
static func getData() -> [MoodEntry] {
|
||||
public func getLastTen() -> [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
|
||||
|
||||
return moodEntry
|
||||
}
|
||||
|
||||
static func createTimeLineViews(fromEntries: [MoodEntry]) -> [WatchTimelineView] {
|
||||
func createTimeLineViewsfrom(entries: [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
|
||||
if let item = entries.filter({ entry in
|
||||
let components = Calendar.current.dateComponents([.day, .month, .year], from: pastDate)
|
||||
let day = components.day
|
||||
let month = components.month
|
||||
@@ -55,13 +56,13 @@ struct TimeLineCreator {
|
||||
}).first {
|
||||
let timeLineView = WatchTimelineView(image: item.mood.icon,
|
||||
date: pastDate,
|
||||
color: item.mood.color,
|
||||
color: item.mood == Mood.missing ? Color(UIColor.label) : item.mood.color,
|
||||
graphic: item.mood.graphic)
|
||||
returnViews.append(timeLineView)
|
||||
} else {
|
||||
let timeLineView = WatchTimelineView(image: Mood.missing.icon,
|
||||
date: pastDate,
|
||||
color: Mood.missing.color,
|
||||
color: Color(UIColor.label),
|
||||
graphic: Mood.missing.graphic)
|
||||
returnViews.append(timeLineView)
|
||||
}
|
||||
@@ -72,6 +73,8 @@ struct TimeLineCreator {
|
||||
}
|
||||
|
||||
struct Provider: IntentTimelineProvider {
|
||||
let timeLineCreator = TimeLineCreator()
|
||||
|
||||
/*
|
||||
placeholder for widget, no data
|
||||
gets redacted auto
|
||||
@@ -88,6 +91,7 @@ struct Provider: IntentTimelineProvider {
|
||||
|
||||
func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
|
||||
var timeLineViews = [WatchTimelineView]()
|
||||
let lastTenEntries = timeLineCreator.getLastTen()
|
||||
|
||||
if context.isPreview {
|
||||
for pastDay in 0...10 {
|
||||
@@ -96,8 +100,7 @@ struct Provider: IntentTimelineProvider {
|
||||
timeLineViews.append( WatchTimelineView(image: mood.icon, date: pastDate, color: mood.color, graphic: mood.graphic))
|
||||
}
|
||||
} else {
|
||||
let data = TimeLineCreator.getData()
|
||||
timeLineViews = TimeLineCreator.createTimeLineViews(fromEntries: data)
|
||||
timeLineViews = timeLineCreator.createTimeLineViewsfrom(entries: lastTenEntries)
|
||||
}
|
||||
|
||||
let entry = SimpleEntry(date: Date(), configuration: configuration, timeLineViews: timeLineViews)
|
||||
@@ -105,10 +108,12 @@ struct Provider: IntentTimelineProvider {
|
||||
}
|
||||
|
||||
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
|
||||
let data = TimeLineCreator.getData()
|
||||
let views = TimeLineCreator.createTimeLineViews(fromEntries: data)
|
||||
let lastTenEntries = timeLineCreator.getLastTen()
|
||||
let views = timeLineCreator.createTimeLineViewsfrom(entries: lastTenEntries)
|
||||
|
||||
let entry = SimpleEntry(date: Date(), configuration: configuration, timeLineViews: views)
|
||||
|
||||
// TODO: make this update time make more sense
|
||||
let timeline = Timeline(entries: [entry], policy: .after(Random.tomorrowMidnightThirty))
|
||||
completion(timeline)
|
||||
}
|
||||
@@ -127,7 +132,7 @@ struct SimpleEntry: TimelineEntry {
|
||||
self.showStats = showStats
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
struct FeelsWidgetEntryView : View {
|
||||
@Environment(\.sizeCategory) var sizeCategory
|
||||
@Environment(\.widgetFamily) var family
|
||||
@@ -157,22 +162,6 @@ struct FeelsWidgetEntryView : View {
|
||||
}
|
||||
}
|
||||
|
||||
struct FeelsGraphicWidgetEntryView : View {
|
||||
@Environment(\.sizeCategory) var sizeCategory
|
||||
@Environment(\.widgetFamily) var family
|
||||
|
||||
var entry: Provider.Entry
|
||||
|
||||
@ViewBuilder
|
||||
var body: some View {
|
||||
SmallGraphicWidgetView(entry: entry)
|
||||
.onReceive(NotificationCenter.default.publisher(for: .NSPersistentStoreRemoteChange)) { _ in
|
||||
// make sure you don't call this too often
|
||||
WidgetCenter.shared.reloadAllTimelines()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SmallWidgetView: View {
|
||||
var entry: Provider.Entry
|
||||
|
||||
@@ -192,6 +181,47 @@ struct SmallWidgetView: View {
|
||||
}
|
||||
}
|
||||
|
||||
struct MediumWidgetView: View {
|
||||
var entry: Provider.Entry
|
||||
|
||||
var firstGroup: [WatchTimelineView] {
|
||||
Array(self.entry.timeLineViews.prefix(5))
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
TimeHeaderView(startDate: firstGroup.first!.date, endDate: firstGroup.last!.date)
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.multilineTextAlignment(.leading)
|
||||
|
||||
TimeBodyView(group: firstGroup)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
|
||||
.frame(minHeight: 0, maxHeight: 55)
|
||||
.padding()
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
/**********************************************************/
|
||||
struct FeelsGraphicWidgetEntryView : View {
|
||||
@Environment(\.sizeCategory) var sizeCategory
|
||||
@Environment(\.widgetFamily) var family
|
||||
|
||||
var entry: Provider.Entry
|
||||
|
||||
@ViewBuilder
|
||||
var body: some View {
|
||||
SmallGraphicWidgetView(entry: entry)
|
||||
.onReceive(NotificationCenter.default.publisher(for: .NSPersistentStoreRemoteChange)) { _ in
|
||||
// make sure you don't call this too often
|
||||
WidgetCenter.shared.reloadAllTimelines()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SmallGraphicWidgetView: View {
|
||||
var entry: Provider.Entry
|
||||
|
||||
@@ -203,7 +233,31 @@ struct SmallGraphicWidgetView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
/**********************************************************/
|
||||
struct FeelsIconWidgetEntryView : View {
|
||||
@Environment(\.sizeCategory) var sizeCategory
|
||||
@Environment(\.widgetFamily) var family
|
||||
|
||||
var entry: Provider.Entry
|
||||
|
||||
@ViewBuilder
|
||||
var body: some View {
|
||||
SmallIconView(entry: entry)
|
||||
}
|
||||
}
|
||||
|
||||
struct SmallIconView: View {
|
||||
var entry: Provider.Entry
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geo in
|
||||
Mood.missing.graphic
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
}
|
||||
}
|
||||
}
|
||||
/**********************************************************/
|
||||
struct TimeHeaderView: View {
|
||||
let startDate: Date
|
||||
let endDate: Date
|
||||
@@ -242,30 +296,7 @@ struct TimeBodyView: View {
|
||||
}
|
||||
}
|
||||
|
||||
struct MediumWidgetView: View {
|
||||
var entry: Provider.Entry
|
||||
|
||||
var firstGroup: [WatchTimelineView] {
|
||||
Array(self.entry.timeLineViews.prefix(5))
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
TimeHeaderView(startDate: firstGroup.first!.date, endDate: firstGroup.last!.date)
|
||||
.frame(minWidth: 0, maxWidth: .infinity)
|
||||
.multilineTextAlignment(.leading)
|
||||
|
||||
TimeBodyView(group: firstGroup)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
|
||||
.frame(minHeight: 0, maxHeight: 55)
|
||||
.padding()
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//struct LargeWidgetView: View {
|
||||
// var entry: Provider.Entry
|
||||
@@ -316,6 +347,7 @@ struct FeelsBundle: WidgetBundle {
|
||||
var body: some Widget {
|
||||
FeelsWidget()
|
||||
FeelsGraphicWidget()
|
||||
FeelsIconWidget()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,6 +366,21 @@ struct FeelsWidget: Widget {
|
||||
}
|
||||
}
|
||||
|
||||
struct FeelsIconWidget: Widget {
|
||||
let kind: String = "FeelsIconWidget"
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
IntentConfiguration(kind: kind,
|
||||
intent: ConfigurationIntent.self,
|
||||
provider: Provider()) { entry in
|
||||
FeelsIconWidgetEntryView(entry: entry)
|
||||
}
|
||||
.configurationDisplayName("Feels Icon")
|
||||
.description("")
|
||||
.supportedFamilies([.systemSmall])
|
||||
}
|
||||
}
|
||||
|
||||
struct FeelsGraphicWidget: Widget {
|
||||
let kind: String = "FeelsGraphicWidget"
|
||||
|
||||
@@ -343,7 +390,7 @@ struct FeelsGraphicWidget: Widget {
|
||||
provider: Provider()) { entry in
|
||||
FeelsGraphicWidgetEntryView(entry: entry)
|
||||
}
|
||||
.configurationDisplayName("Feels")
|
||||
.configurationDisplayName("Mood Graphic")
|
||||
.description("")
|
||||
.supportedFamilies([.systemSmall])
|
||||
}
|
||||
@@ -353,7 +400,7 @@ 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)
|
||||
let views = TimeLineCreator().createTimeLineViewsfrom(entries: data)
|
||||
return views
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user