move apple snooze view and supporting code to separate file

This commit is contained in:
Satindar Dhillon
2022-02-15 11:29:18 -08:00
parent 06a38ae407
commit 1ba9082238
2 changed files with 135 additions and 123 deletions

View File

@ -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 {

View File

@ -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())
}
}