From 1ba90822387680c439c54d9ef25f895e49025bfd Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Tue, 15 Feb 2022 11:29:18 -0800 Subject: [PATCH] move apple snooze view and supporting code to separate file --- .../PrimaryContainerViews/HomeFeedView.swift | 128 +---------------- .../Sources/Views/SnoozeView.swift | 130 ++++++++++++++++++ 2 files changed, 135 insertions(+), 123 deletions(-) create mode 100644 apple/OmnivoreKit/Sources/Views/SnoozeView.swift diff --git a/apple/OmnivoreKit/Sources/Views/PrimaryContainerViews/HomeFeedView.swift b/apple/OmnivoreKit/Sources/Views/PrimaryContainerViews/HomeFeedView.swift index 252e17275..f7066c59a 100644 --- a/apple/OmnivoreKit/Sources/Views/PrimaryContainerViews/HomeFeedView.swift +++ b/apple/OmnivoreKit/Sources/Views/PrimaryContainerViews/HomeFeedView.swift @@ -239,7 +239,11 @@ public struct HomeFeedView: View { } } .formSheet(isPresented: $snoozePresented) { - snoozeView + SnoozeView(snoozePresented: $snoozePresented, itemToSnooze: $itemToSnooze) { linkId, until, successMessage in + viewModel.performActionSubject.send( + .snooze(linkId: linkId, until: until, successMessage: successMessage) + ) + } } #endif .onAppear { @@ -249,128 +253,6 @@ public struct HomeFeedView: View { } } - struct SnoozeIconButtonView: View { - let snooze: Snooze - let action: (_ snooze: Snooze) -> Void - - var body: some View { - Button(action: { - action(snooze) - }) { - VStack(alignment: .center, spacing: 8) { - snooze.icon - .font(.appTitle) - .foregroundColor(.appYellow48) - Text(snooze.title) - .font(.appBody) - .foregroundColor(.appGrayText) - Text(snooze.untilStr) - .font(.appCaption) - .foregroundColor(.appGrayText) - } - .frame( - maxWidth: .infinity, - maxHeight: .infinity - ) - } - .frame(height: 100) - } - } - - struct Snooze { - let until: Date - let icon: Image - let title: String - let untilStr: String - - init(until: Date, icon: Image, title: String, needsDay: Bool) { - self.until = until - self.icon = icon - self.title = title - let formatter = DateFormatter() - formatter.dateFormat = needsDay ? "EEE h:mm a" : "h:mm a" - self.untilStr = formatter.string(from: until) - } - } - - var snoozeValues: [Snooze] { - let now = Date() - return Self.snoozeValuesForDate(now: now) - } - - static func snoozeValuesForDate(now: Date) -> [Snooze] { - var res: [Snooze] = [] - let calendar = Calendar.current - let components = calendar.dateComponents([.year, .month, .day, .hour, .timeZone, .weekday], from: now) - - var tonightComponent = components - tonightComponent.hour = 20 - - var thisMorningComponent = components - thisMorningComponent.hour = 8 - - let tonight = calendar.date(from: tonightComponent)! - let thisMorning = calendar.date(from: thisMorningComponent)! - - let tomorrowMorning = Calendar.current.date(byAdding: DateComponents(day: 1), to: thisMorning) - - // Add either tonight or tomorrow night - if now < tonight { - res.append(Snooze(until: tonight, icon: .moonStars, title: "Tonight", needsDay: false)) - } else { - let tomorrowNight = Calendar.current.date(byAdding: DateComponents(day: 1), to: tonight)! - res.append(Snooze(until: tomorrowNight, icon: .moonStars, title: "Tomorrow night", needsDay: false)) - } - - if let tomorrowMorning = tomorrowMorning { - res.append(Snooze(until: tomorrowMorning, icon: .sunHorizon, title: "Tomorrow morning", needsDay: false)) - } - - if let weekday = components.weekday { - // Add this or next weekend - if weekday < 5 { - let thisWeekend = Calendar.current.date(byAdding: DateComponents(day: 7 - weekday), to: thisMorning) - res.append(Snooze(until: thisWeekend!, icon: .mountains, title: "This weekend", needsDay: true)) - } else { - let nextWeekend = Calendar.current.date(byAdding: DateComponents(day: 7 - (weekday - 5)), to: thisMorning)! - res.append(Snooze(until: nextWeekend, icon: .mountains, title: "Next weekend", needsDay: true)) - } - let nextWeek = Calendar.current.date(byAdding: DateComponents(day: weekday + 5), to: thisMorning)! - res.append(Snooze(until: nextWeek, icon: .chartLineUp, title: "Next week", needsDay: true)) - } - - return Array(res.sorted(by: { $0.until > $1.until }).reversed()) - } - - func snoozeItem(_ snooze: Snooze) { - if let item = itemToSnooze { - withAnimation(.linear(duration: 0.4)) { - viewModel.performActionSubject.send(.snooze(linkId: item.id, until: snooze.until, successMessage: "Snoozed until \(snooze.untilStr)")) - } - } - itemToSnooze = nil - snoozePresented = false - } - - var snoozeView: some View { - VStack { - Spacer() - - HStack { - SnoozeIconButtonView(snooze: snoozeValues[0], action: { snoozeItem($0) }) - SnoozeIconButtonView(snooze: snoozeValues[1], action: { snoozeItem($0) }) - } - - Spacer(minLength: 32) - - HStack { - SnoozeIconButtonView(snooze: snoozeValues[2], action: { snoozeItem($0) }) - SnoozeIconButtonView(snooze: snoozeValues[3], action: { snoozeItem($0) }) - } - Spacer() - }.padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)) - } - public var body: some View { #if os(iOS) if UIDevice.isIPhone { diff --git a/apple/OmnivoreKit/Sources/Views/SnoozeView.swift b/apple/OmnivoreKit/Sources/Views/SnoozeView.swift new file mode 100644 index 000000000..e126f80d2 --- /dev/null +++ b/apple/OmnivoreKit/Sources/Views/SnoozeView.swift @@ -0,0 +1,130 @@ +import Models +import SwiftUI + +struct SnoozeView: View { + @Binding var snoozePresented: Bool + @Binding var itemToSnooze: FeedItem? + let snoozeAction: (String, Date, String?) -> Void + + var body: some View { + VStack { + Spacer() + + HStack { + SnoozeIconButtonView(snooze: Snooze.snoozeValues[0], action: { snoozeItem($0) }) + SnoozeIconButtonView(snooze: Snooze.snoozeValues[1], action: { snoozeItem($0) }) + } + + Spacer(minLength: 32) + + HStack { + SnoozeIconButtonView(snooze: Snooze.snoozeValues[2], action: { snoozeItem($0) }) + SnoozeIconButtonView(snooze: Snooze.snoozeValues[3], action: { snoozeItem($0) }) + } + Spacer() + }.padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)) + } + + private func snoozeItem(_ snooze: Snooze) { + if let item = itemToSnooze { + withAnimation(.linear(duration: 0.4)) { + snoozeAction(item.id, snooze.until, "Snoozed until \(snooze.untilStr)") + } + } + itemToSnooze = nil + snoozePresented = false + } +} + +private struct SnoozeIconButtonView: View { + let snooze: Snooze + let action: (_ snooze: Snooze) -> Void + + var body: some View { + Button(action: { + action(snooze) + }) { + VStack(alignment: .center, spacing: 8) { + snooze.icon + .font(.appTitle) + .foregroundColor(.appYellow48) + Text(snooze.title) + .font(.appBody) + .foregroundColor(.appGrayText) + Text(snooze.untilStr) + .font(.appCaption) + .foregroundColor(.appGrayText) + } + .frame( + maxWidth: .infinity, + maxHeight: .infinity + ) + } + .frame(height: 100) + } +} + +private struct Snooze { + let until: Date + let icon: Image + let title: String + let untilStr: String + + init(until: Date, icon: Image, title: String, needsDay: Bool) { + self.until = until + self.icon = icon + self.title = title + let formatter = DateFormatter() + formatter.dateFormat = needsDay ? "EEE h:mm a" : "h:mm a" + self.untilStr = formatter.string(from: until) + } + + static var snoozeValues: [Snooze] { + let now = Date() + return snoozeValuesForDate(now: now) + } + + static func snoozeValuesForDate(now: Date) -> [Snooze] { + var res: [Snooze] = [] + let calendar = Calendar.current + let components = calendar.dateComponents([.year, .month, .day, .hour, .timeZone, .weekday], from: now) + + var tonightComponent = components + tonightComponent.hour = 20 + + var thisMorningComponent = components + thisMorningComponent.hour = 8 + + let tonight = calendar.date(from: tonightComponent)! + let thisMorning = calendar.date(from: thisMorningComponent)! + + let tomorrowMorning = Calendar.current.date(byAdding: DateComponents(day: 1), to: thisMorning) + + // Add either tonight or tomorrow night + if now < tonight { + res.append(Snooze(until: tonight, icon: .moonStars, title: "Tonight", needsDay: false)) + } else { + let tomorrowNight = Calendar.current.date(byAdding: DateComponents(day: 1), to: tonight)! + res.append(Snooze(until: tomorrowNight, icon: .moonStars, title: "Tomorrow night", needsDay: false)) + } + + if let tomorrowMorning = tomorrowMorning { + res.append(Snooze(until: tomorrowMorning, icon: .sunHorizon, title: "Tomorrow morning", needsDay: false)) + } + + if let weekday = components.weekday { + // Add this or next weekend + if weekday < 5 { + let thisWeekend = Calendar.current.date(byAdding: DateComponents(day: 7 - weekday), to: thisMorning) + res.append(Snooze(until: thisWeekend!, icon: .mountains, title: "This weekend", needsDay: true)) + } else { + let nextWeekend = Calendar.current.date(byAdding: DateComponents(day: 7 - (weekday - 5)), to: thisMorning)! + res.append(Snooze(until: nextWeekend, icon: .mountains, title: "Next weekend", needsDay: true)) + } + let nextWeek = Calendar.current.date(byAdding: DateComponents(day: weekday + 5), to: thisMorning)! + res.append(Snooze(until: nextWeek, icon: .chartLineUp, title: "Next week", needsDay: true)) + } + + return Array(res.sorted(by: { $0.until > $1.until }).reversed()) + } +}