|
|
|
|
@@ -26,49 +26,29 @@ class WatchTimelineView: Identifiable {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct TimeLineCreator {
|
|
|
|
|
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])
|
|
|
|
|
static func createViews(daysBack: Int) -> [WatchTimelineView] {
|
|
|
|
|
var timeLineView = [WatchTimelineView]()
|
|
|
|
|
|
|
|
|
|
return moodEntry
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func createTimeLineViewsfrom(entries: [MoodEntry]) -> [WatchTimelineView] {
|
|
|
|
|
var returnViews = [WatchTimelineView]()
|
|
|
|
|
|
|
|
|
|
for pastDays in 0...10 {
|
|
|
|
|
let pastDate = Calendar.current.date(byAdding: .day, value: -pastDays, to: Date())!
|
|
|
|
|
for day in 0..<daysBack{
|
|
|
|
|
let day = Calendar.current.date(byAdding: .day, value: -day, to: Date())!
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
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 == Mood.missing ? Color(UIColor.label) : item.mood.color,
|
|
|
|
|
graphic: item.mood.graphic)
|
|
|
|
|
returnViews.append(timeLineView)
|
|
|
|
|
let dayStart = Calendar.current.startOfDay(for: day)
|
|
|
|
|
let dayEnd = Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: dayStart)!
|
|
|
|
|
|
|
|
|
|
if let todayEntry = PersistenceController.shared.getData(startDate: dayStart, endDate: dayEnd, includedDays: []).first {
|
|
|
|
|
timeLineView.append(WatchTimelineView(image: todayEntry.mood.icon,
|
|
|
|
|
date: dayStart,
|
|
|
|
|
color: todayEntry.mood.color,
|
|
|
|
|
graphic: todayEntry.mood.graphic))
|
|
|
|
|
} else {
|
|
|
|
|
let timeLineView = WatchTimelineView(image: Mood.missing.icon,
|
|
|
|
|
date: pastDate,
|
|
|
|
|
color: Color(UIColor.label),
|
|
|
|
|
graphic: Mood.missing.graphic)
|
|
|
|
|
returnViews.append(timeLineView)
|
|
|
|
|
timeLineView.append(WatchTimelineView(image: Mood.missing.icon,
|
|
|
|
|
date: dayStart,
|
|
|
|
|
color: Mood.missing.color,
|
|
|
|
|
graphic: Mood.missing.graphic))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
returnViews = returnViews.sorted(by: { $0.date > $1.date })
|
|
|
|
|
return returnViews
|
|
|
|
|
timeLineView = timeLineView.sorted(by: { $0.date > $1.date })
|
|
|
|
|
return timeLineView
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -80,41 +60,29 @@ struct Provider: IntentTimelineProvider {
|
|
|
|
|
gets redacted auto
|
|
|
|
|
*/
|
|
|
|
|
func placeholder(in context: Context) -> SimpleEntry {
|
|
|
|
|
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, graphic: mood.graphic))
|
|
|
|
|
}
|
|
|
|
|
return SimpleEntry(date: Date(), configuration: ConfigurationIntent(), timeLineViews: sampleViews)
|
|
|
|
|
return SimpleEntry(date: Date(),
|
|
|
|
|
configuration: ConfigurationIntent(),
|
|
|
|
|
timeLineViews: TimeLineCreator.createViews(daysBack: 10))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
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, graphic: mood.graphic))
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
timeLineViews = timeLineCreator.createTimeLineViewsfrom(entries: lastTenEntries)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let entry = SimpleEntry(date: Date(), configuration: configuration, timeLineViews: timeLineViews)
|
|
|
|
|
let entry = SimpleEntry(date: Date(),
|
|
|
|
|
configuration: ConfigurationIntent(),
|
|
|
|
|
timeLineViews: TimeLineCreator.createViews(daysBack: 10))
|
|
|
|
|
completion(entry)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
|
|
|
|
|
let lastTenEntries = timeLineCreator.getLastTen()
|
|
|
|
|
let views = timeLineCreator.createTimeLineViewsfrom(entries: lastTenEntries)
|
|
|
|
|
let entry = SimpleEntry(date: Calendar.current.date(byAdding: .second, value: 15, to: Date())!,
|
|
|
|
|
configuration: ConfigurationIntent(),
|
|
|
|
|
timeLineViews: nil)
|
|
|
|
|
|
|
|
|
|
let entry = SimpleEntry(date: Date(), configuration: configuration, timeLineViews: views)
|
|
|
|
|
let midNightEntry = SimpleEntry(date: Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: Date())!,
|
|
|
|
|
configuration: ConfigurationIntent(),
|
|
|
|
|
timeLineViews: nil)
|
|
|
|
|
|
|
|
|
|
// TODO: make this update time make more sense
|
|
|
|
|
let timeline = Timeline(entries: [entry], policy: .after(Random.tomorrowMidnightThirty))
|
|
|
|
|
let date = Calendar.current.date(byAdding: .second, value: 10, to: Date())!
|
|
|
|
|
let timeline = Timeline(entries: [entry, midNightEntry], policy: .after(date))
|
|
|
|
|
completion(timeline)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -122,16 +90,17 @@ struct Provider: IntentTimelineProvider {
|
|
|
|
|
struct SimpleEntry: TimelineEntry {
|
|
|
|
|
let date: Date
|
|
|
|
|
let configuration: ConfigurationIntent
|
|
|
|
|
let timeLineViews: [WatchTimelineView]
|
|
|
|
|
let timeLineViews: [WatchTimelineView]?
|
|
|
|
|
let showStats: Bool
|
|
|
|
|
|
|
|
|
|
init(date: Date, configuration: ConfigurationIntent, timeLineViews: [WatchTimelineView], showStats: Bool = false) {
|
|
|
|
|
init(date: Date, configuration: ConfigurationIntent, timeLineViews: [WatchTimelineView]?, showStats: Bool = false) {
|
|
|
|
|
self.date = date
|
|
|
|
|
self.configuration = configuration
|
|
|
|
|
self.timeLineViews = timeLineViews
|
|
|
|
|
self.showStats = showStats
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************/
|
|
|
|
|
struct FeelsWidgetEntryView : View {
|
|
|
|
|
@Environment(\.sizeCategory) var sizeCategory
|
|
|
|
|
@@ -164,12 +133,18 @@ struct FeelsWidgetEntryView : View {
|
|
|
|
|
|
|
|
|
|
struct SmallWidgetView: View {
|
|
|
|
|
var entry: Provider.Entry
|
|
|
|
|
var timeLineView = [WatchTimelineView]()
|
|
|
|
|
|
|
|
|
|
init(entry: Provider.Entry) {
|
|
|
|
|
self.entry = entry
|
|
|
|
|
timeLineView = TimeLineCreator.createViews(daysBack: 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
|
ZStack {
|
|
|
|
|
Color(UIColor.secondarySystemBackground)
|
|
|
|
|
HStack {
|
|
|
|
|
ForEach([entry.timeLineViews.first!]) { watchView in
|
|
|
|
|
ForEach(self.timeLineView) { watchView in
|
|
|
|
|
EntryCard(timeLineView: watchView)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -183,20 +158,22 @@ struct SmallWidgetView: View {
|
|
|
|
|
|
|
|
|
|
struct MediumWidgetView: View {
|
|
|
|
|
var entry: Provider.Entry
|
|
|
|
|
|
|
|
|
|
var firstGroup: [WatchTimelineView] {
|
|
|
|
|
Array(self.entry.timeLineViews.prefix(5))
|
|
|
|
|
var timeLineView = [WatchTimelineView]()
|
|
|
|
|
|
|
|
|
|
init(entry: Provider.Entry) {
|
|
|
|
|
self.entry = entry
|
|
|
|
|
timeLineView = TimeLineCreator.createViews(daysBack: 5)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
|
VStack {
|
|
|
|
|
Spacer()
|
|
|
|
|
|
|
|
|
|
TimeHeaderView(startDate: firstGroup.first!.date, endDate: firstGroup.last!.date)
|
|
|
|
|
TimeHeaderView(startDate: timeLineView.first!.date, endDate: timeLineView.last!.date)
|
|
|
|
|
.frame(minWidth: 0, maxWidth: .infinity)
|
|
|
|
|
.multilineTextAlignment(.leading)
|
|
|
|
|
|
|
|
|
|
TimeBodyView(group: firstGroup)
|
|
|
|
|
TimeBodyView(group: timeLineView)
|
|
|
|
|
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
|
|
|
|
|
.frame(minHeight: 0, maxHeight: 55)
|
|
|
|
|
.padding()
|
|
|
|
|
@@ -224,10 +201,16 @@ struct FeelsGraphicWidgetEntryView : View {
|
|
|
|
|
|
|
|
|
|
struct SmallGraphicWidgetView: View {
|
|
|
|
|
var entry: Provider.Entry
|
|
|
|
|
|
|
|
|
|
var timeLineView = [WatchTimelineView]()
|
|
|
|
|
|
|
|
|
|
init(entry: Provider.Entry) {
|
|
|
|
|
self.entry = entry
|
|
|
|
|
timeLineView = TimeLineCreator.createViews(daysBack: 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
|
GeometryReader { geo in
|
|
|
|
|
entry.timeLineViews.first!.graphic
|
|
|
|
|
timeLineView.first!.graphic
|
|
|
|
|
.resizable()
|
|
|
|
|
.scaledToFit()
|
|
|
|
|
}
|
|
|
|
|
@@ -397,26 +380,19 @@ struct FeelsGraphicWidget: Widget {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct FeelsWidget_Previews: PreviewProvider {
|
|
|
|
|
static var data: [WatchTimelineView] {
|
|
|
|
|
var data = PersistenceController.shared.randomEntries(count: 10)
|
|
|
|
|
data.remove(at: 2)
|
|
|
|
|
let views = TimeLineCreator().createTimeLineViewsfrom(entries: data)
|
|
|
|
|
return views
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static var previews: some View {
|
|
|
|
|
Group {
|
|
|
|
|
FeelsWidgetEntryView(entry: SimpleEntry(date: Date(),
|
|
|
|
|
configuration: ConfigurationIntent(),
|
|
|
|
|
timeLineViews: FeelsWidget_Previews.data))
|
|
|
|
|
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
|
|
|
|
.environment(\.sizeCategory, .small)
|
|
|
|
|
|
|
|
|
|
FeelsWidgetEntryView(entry: SimpleEntry(date: Date(),
|
|
|
|
|
configuration: ConfigurationIntent(),
|
|
|
|
|
timeLineViews: FeelsWidget_Previews.data))
|
|
|
|
|
.previewContext(WidgetPreviewContext(family: .systemMedium))
|
|
|
|
|
.environment(\.sizeCategory, .medium)
|
|
|
|
|
// FeelsWidgetEntryView(entry: SimpleEntry(date: Date(),
|
|
|
|
|
// configuration: ConfigurationIntent(),
|
|
|
|
|
// timeLineViews: FeelsWidget_Previews.data))
|
|
|
|
|
// .previewContext(WidgetPreviewContext(family: .systemSmall))
|
|
|
|
|
// .environment(\.sizeCategory, .small)
|
|
|
|
|
//
|
|
|
|
|
// FeelsWidgetEntryView(entry: SimpleEntry(date: Date(),
|
|
|
|
|
// configuration: ConfigurationIntent(),
|
|
|
|
|
// timeLineViews: FeelsWidget_Previews.data))
|
|
|
|
|
// .previewContext(WidgetPreviewContext(family: .systemMedium))
|
|
|
|
|
// .environment(\.sizeCategory, .medium)
|
|
|
|
|
//
|
|
|
|
|
// FeelsWidgetEntryView(entry: SimpleEntry(date: Date(),
|
|
|
|
|
// configuration: ConfigurationIntent(),
|
|
|
|
|
|