Skip to content

Commit

Permalink
Allow days to be sorted with today at the top
Browse files Browse the repository at this point in the history
Closes #70
  • Loading branch information
skjiisa committed Apr 20, 2024
1 parent cc8504b commit 0c5e464
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 26 deletions.
33 changes: 27 additions & 6 deletions Tickmate/Tickmate/Controllers/TrackController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,39 @@ class TrackController: NSObject, ObservableObject {
return (weekday, dateFormatter.string(from: date))
}

func weekend(day: Int) -> Bool {
func isWeekEnd(day: Int) -> Bool {
// The Swift % operator doesn't calculate
// the modulo from negative numbers,
// so we're adding 7 and %ing again.
(weekday - day % 7 + 7) % 7 + 1 == weekStartDay
}

private func isWeekStart(day: Int) -> Bool {
(weekday - day % 7 + 6) % 7 + 1 == weekStartDay
}

func insets(day: Int) -> Edge.Set? {
weekend(day: day)
? .bottom
: (weekday - day % 7 + 6) % 7 + 1 == weekStartDay
? .top : nil
let todayAtTop = UserDefaults(suiteName: groupID)?.bool(forKey: Defaults.todayAtTop.rawValue) ?? false
var after: Edge.Set { todayAtTop ? .top : .bottom }
var before: Edge.Set { todayAtTop ? .bottom : .top }

if isWeekEnd(day: day) {
return after
} else if isWeekStart(day: day) {
return before
} else {
return .none
}
}

func shouldShowSeparatorBelow(day: Int) -> Bool {
let todayAtTop = UserDefaults(suiteName: groupID)?.bool(forKey: Defaults.todayAtTop.rawValue) ?? false

if todayAtTop {
return isWeekStart(day: day)
} else {
return isWeekEnd(day: day)
}
}

//MARK: Track CRUD
Expand Down Expand Up @@ -300,7 +321,7 @@ class TrackController: NSObject, ObservableObject {
}
}

// TODO: Update this to instead save _now_, but prevent a second save from happening for 5 seconds (or whatever interval)
// TODO: Update this and the below to instead save _now_, but prevent a second save from happening for 5 seconds (or whatever interval)
/// Schedule a Core Data save on the current view context.
///
/// Call this function when you want to save a small change when other small changes may happen soon after.
Expand Down
3 changes: 2 additions & 1 deletion Tickmate/Tickmate/Model/Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Defaults.swift
// Tickmate
//
// Created by Isaac Lyons on 3/9/21.
// Created by Elaine Lyons on 3/9/21.
//

import Foundation
Expand All @@ -23,4 +23,5 @@ enum Defaults: String {
case appGroupDatabaseMigration // Bool
case userDefaultsMigration // Bool App Group
case lastUpdateTime // String App Group
case todayAtTop // Bool App Group
}
2 changes: 1 addition & 1 deletion Tickmate/Tickmate/TickmateApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// TickmateApp.swift
// Tickmate
//
// Created by Isaac Lyons on 2/19/21.
// Created by Elaine Lyons on 2/19/21.
//

import SwiftUI
Expand Down
15 changes: 15 additions & 0 deletions Tickmate/Tickmate/Views/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ struct SettingsView: View {
@AppStorage(Defaults.weekStartDay.rawValue, store: UserDefaults(suiteName: groupID))
private var weekStartDay = 2

@AppStorage(Defaults.todayAtTop.rawValue, store: UserDefaults(suiteName: groupID))
private var todayAtTop = false

@AppStorage(Defaults.weekSeparatorSpaces.rawValue) private var weekSeparatorSpaces: Bool = true
@AppStorage(Defaults.weekSeparatorLines.rawValue) private var weekSeparatorLines: Bool = true
@AppStorage(Defaults.relativeDates.rawValue) private var relativeDates = true
Expand Down Expand Up @@ -50,6 +53,15 @@ struct SettingsView: View {
}
}

Section {
Picker("Put today at the", selection: $todayAtTop) {
Text("top")
.tag(true)
Text("bottom")
.tag(false)
}
}

Section {
Toggle(isOn: $relativeDates) {
TextWithCaption(text: "Use relative dates", caption: "Today, Yesterday")
Expand Down Expand Up @@ -167,6 +179,9 @@ struct SettingsView: View {
}
.onChange(of: customDayStart, perform: updateCustomDayStart)
.onChange(of: timeOffset, perform: updateCustomDayStart)
.onChange(of: todayAtTop) { _ in
trackController.scheduleTimelineRefresh()
}
.onChange(of: weekStartDay) { value in
trackController.weekStartDay = value
}
Expand Down
6 changes: 3 additions & 3 deletions Tickmate/Tickmate/Views/TickView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ struct DayRow<C: RandomAccessCollection>: View where C.Element == Track {
}

@ViewBuilder
private var backgroud: some View {
if lines && trackController.weekend(day: day) {
private var background: some View {
if lines && trackController.shouldShowSeparatorBelow(day: day) {
VStack {
Spacer()
Capsule()
Expand Down Expand Up @@ -70,7 +70,7 @@ struct DayRow<C: RandomAccessCollection>: View where C.Element == Track {
.opacity(0)
}
}
.listRowBackground(backgroud)
.listRowBackground(background)
.id(day)
}
}
Expand Down
29 changes: 19 additions & 10 deletions Tickmate/Tickmate/Views/TicksView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ struct TicksView: View {
fetchRequest.wrappedValue
}

@AppStorage(Defaults.todayAtTop.rawValue, store: UserDefaults(suiteName: groupID))
private var todayAtTop = false
@AppStorage(Defaults.weekSeparatorLines.rawValue) private var weekSeparatorLines: Bool = true
@AppStorage(Defaults.weekSeparatorSpaces.rawValue) private var weekSeparatorSpaces: Bool = true

Expand Down Expand Up @@ -122,24 +124,31 @@ struct TicksView: View {

ScrollViewReader { proxy in
List {
Button("Go to bottom") {
proxy.scrollTo(0)
if !todayAtTop {
Button("Go to bottom") {
proxy.scrollTo(0)
}
}

ForEach(0..<365) { dayComplement in
DayRow(364 - dayComplement, tracks: tracks, spaces: weekSeparatorSpaces, lines: weekSeparatorLines)
.listRowInsets(.init(top: 4, leading: 0, bottom: 4, trailing: 0))
#if os(iOS)
.padding(.horizontal)
#endif
ForEach(0..<365) { row in
DayRow(
todayAtTop ? row : 364 - row,
tracks: tracks,
spaces: weekSeparatorSpaces,
lines: weekSeparatorLines
)
.listRowInsets(.init(top: 4, leading: 0, bottom: 4, trailing: 0))
#if os(iOS)
.padding(.horizontal)
#endif
}
}
.listStyle(PlainListStyle())
.introspect(.list, on: .iOS(.v14, .v15)) { tableView in
tableView.scrollsToTop = false
tableView.scrollsToTop = todayAtTop
}
.introspect(.list, on: .iOS(.v16, .v17)) { collectionView in
collectionView.scrollsToTop = false
collectionView.scrollsToTop = todayAtTop
}
.padding(0)
.onAppear {
Expand Down
21 changes: 16 additions & 5 deletions Tickmate/TicksWidget/TicksWidget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ struct TicksWidgetEntryView : View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.widgetFamily) private var widgetFamily

@AppStorage(Defaults.todayAtTop.rawValue, store: UserDefaults(suiteName: groupID))
private var todayAtTop = false

//MARK: Properties

var entry: Provider.Entry
Expand Down Expand Up @@ -206,6 +209,14 @@ struct TicksWidgetEntryView : View {
: min(entry.configuration.numDays?.intValue ?? defaultNumDays, maxNumDays)
}

struct Row: Identifiable {
var id: Int { value }
var value: Int
}
var rows: [Row] {
(0..<numDays).map(Row.init(value:))
}

var defaultNumTracks: Int {
switch widgetFamily {
case .systemSmall:
Expand Down Expand Up @@ -273,13 +284,13 @@ struct TicksWidgetEntryView : View {
Divider()
}

ForEach(0..<numDays) { dayComplement in
let day = numDays - 1 - dayComplement
ForEach(rows) { row in
let day = todayAtTop ? row.value : (numDays - 1 - row.value)
DayRow(day, tracks: tracks, spaces: false, lines: false, widget: true, compact: compact)

if dayComplement < numDays - 1 {
if entry.configuration.weekSeparators?.boolValue ?? true
&& entry.trackController.weekend(day: day) {
if row.value < numDays - 1 {
if entry.configuration.weekSeparators?.boolValue ?? true,
entry.trackController.shouldShowSeparatorBelow(day: day) {
Capsule()
.foregroundColor(.gray)
.frame(height: 2)
Expand Down

0 comments on commit 0c5e464

Please sign in to comment.