work around widgets ... not sure if they work
This commit is contained in:
@@ -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<Entry>) -> ()) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user