Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change start date #23

Merged
merged 7 commits into from
May 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Tickmate/Tickmate.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
5991968F25F813ED003215CC /* PresetTracksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5991968E25F813ED003215CC /* PresetTracksView.swift */; };
5991969225F817F7003215CC /* PresetTracks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5991969125F817F7003215CC /* PresetTracks.swift */; };
599D9F5225EC5A4900DF3795 /* TracksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 599D9F5125EC5A4900DF3795 /* TracksView.swift */; };
59A0D8932645CF1600E01E61 /* View+DismissKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59A0D8922645CF1600E01E61 /* View+DismissKeyboard.swift */; };
59C23A6725E70D7000AFBC4B /* SymbolsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59C23A6625E70D7000AFBC4B /* SymbolsList.swift */; };
59C23A6C25E70E1A00AFBC4B /* SymbolPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59C23A6B25E70E1A00AFBC4B /* SymbolPicker.swift */; };
59E6E14E25F88177008A74A9 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59E6E14D25F88177008A74A9 /* SettingsView.swift */; };
Expand Down Expand Up @@ -47,6 +48,7 @@
5991968E25F813ED003215CC /* PresetTracksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresetTracksView.swift; sourceTree = "<group>"; };
5991969125F817F7003215CC /* PresetTracks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PresetTracks.swift; sourceTree = "<group>"; };
599D9F5125EC5A4900DF3795 /* TracksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TracksView.swift; sourceTree = "<group>"; };
59A0D8922645CF1600E01E61 /* View+DismissKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+DismissKeyboard.swift"; sourceTree = "<group>"; };
59C23A6625E70D7000AFBC4B /* SymbolsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolsList.swift; sourceTree = "<group>"; };
59C23A6B25E70E1A00AFBC4B /* SymbolPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolPicker.swift; sourceTree = "<group>"; };
59E6E14D25F88177008A74A9 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -110,6 +112,7 @@
597DF5AF25E5E90800DC8D28 /* Color+RGB.swift */,
597A7FDC25F6E1C900256268 /* StateEditButton.swift */,
59E9397425F98BCB002FD8CD /* AcknowledgementLink.swift */,
59A0D8922645CF1600E01E61 /* View+DismissKeyboard.swift */,
);
path = "Supplementary Views";
sourceTree = "<group>";
Expand Down Expand Up @@ -288,6 +291,7 @@
5991969225F817F7003215CC /* PresetTracks.swift in Sources */,
599D9F5225EC5A4900DF3795 /* TracksView.swift in Sources */,
59F6EA9D25E369830069DF40 /* Tickmate+Convenience.swift in Sources */,
59A0D8932645CF1600E01E61 /* View+DismissKeyboard.swift in Sources */,
59EF633725E5DC93003E7259 /* TextWithCaption.swift in Sources */,
597DF5B025E5E90800DC8D28 /* Color+RGB.swift in Sources */,
59E6E15125F8837E008A74A9 /* Defaults.swift in Sources */,
Expand Down Expand Up @@ -423,6 +427,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Tickmate/Tickmate.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_ASSET_PATHS = "\"Tickmate/Preview Content\"";
DEVELOPMENT_TEAM = A4525544Q4;
ENABLE_PREVIEWS = YES;
Expand All @@ -446,6 +451,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Tickmate/Tickmate.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_ASSET_PATHS = "\"Tickmate/Preview Content\"";
DEVELOPMENT_TEAM = A4525544Q4;
ENABLE_PREVIEWS = YES;
Expand Down
10 changes: 7 additions & 3 deletions Tickmate/Tickmate/Controllers/TickController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ class TickController: NSObject, ObservableObject {
weak var trackController: TrackController?
var todayOffset: Int?

init(track: Track, trackController: TrackController) {
init(track: Track, trackController: TrackController, preview: Bool) {
self.track = track
self.trackController = trackController

let moc = track.managedObjectContext ?? PersistenceController.preview.container.viewContext
let moc = track.managedObjectContext ?? (preview ? PersistenceController.preview : PersistenceController.shared).container.viewContext

let fetchRequest: NSFetchRequest<Tick> = Tick.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "track == %@", track)
fetchRequest.sortDescriptors = [
Expand Down Expand Up @@ -54,7 +55,10 @@ class TickController: NSObject, ObservableObject {
let startDateString = track.startDate,
let startDate = DateInRegion(startDateString, region: .current)?.dateTruncated(at: [.hour, .minute, .second]),
let today = trackController?.date.in(region: .current).dateTruncated(at: [.hour, .minute, .second]),
let todayOffset = (today - startDate).toUnit(.day) else { return }
// Subtract 2 hours here to overestimate the offset to account for for any daylight savings time changes.
// Because we're truncating at the number of days, having one or two hours extra won't increase
// the day offset, but having one hour less because of DST would incorrectly offset the day.
let todayOffset = (today - (startDate - 2.hours)).toUnit(.day) else { return }
self.todayOffset = todayOffset

var ticks = [Tick?]()
Expand Down
54 changes: 51 additions & 3 deletions Tickmate/Tickmate/Controllers/TrackController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,27 @@ import CoreData
import SwiftUI
import SwiftDate

//MARK: TrackController

class TrackController: NSObject, ObservableObject {

//MARK: Properties

var tickControllers: [Track: TickController] = [:]

var date: Date
var weekday: Int
@Published var weekStartDay: Int
@Published var relativeDates: Bool

private var preview: Bool
private var work: DispatchWorkItem?

var fetchedResultsController: NSFetchedResultsController<Track>

init(preview: Bool = false) {
self.preview = preview

UserDefaults.standard.register(defaults: [
Defaults.customDayStartMinutes.rawValue: 0,
Defaults.weekStartDay.rawValue: 2,
Expand All @@ -40,7 +47,7 @@ class TrackController: NSObject, ObservableObject {
relativeDates = UserDefaults.standard.bool(forKey: Defaults.relativeDates.rawValue)

// FRC
let context = preview ? PersistenceController.preview.container.viewContext : PersistenceController.shared.container.viewContext
let context = (preview ? PersistenceController.preview : PersistenceController.shared).container.viewContext

let fetchRequest: NSFetchRequest<Track> = Track.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Track.index, ascending: true)]
Expand All @@ -61,6 +68,8 @@ class TrackController: NSObject, ObservableObject {
}
}

//MARK: Date Formatters

private var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .short
Expand All @@ -81,22 +90,26 @@ class TrackController: NSObject, ObservableObject {
return formatter
}()

//MARK: Ticks

func loadTicks(for track: Track) {
if let tickController = tickControllers[track] {
tickController.loadTicks()
} else {
tickControllers[track] = TickController(track: track, trackController: self)
tickControllers[track] = TickController(track: track, trackController: self, preview: preview)
}
}

func tickController(for track: Track) -> TickController {
tickControllers[track] ?? {
let tickController = TickController(track: track, trackController: self)
let tickController = TickController(track: track, trackController: self, preview: preview)
tickControllers[track] = tickController
return tickController
}()
}

//MARK: Labels

func dayLabel(day: Int) -> TextWithCaption {
let date = self.date - day.days

Expand Down Expand Up @@ -128,6 +141,8 @@ class TrackController: NSObject, ObservableObject {
}
}

//MARK: Track CRUD

func newTrack(index: Int16, context moc: NSManagedObjectContext) -> Track {
Track(name: "New Track", startDate: TrackController.iso8601.string(from: date.in(region: .current).date), index: index, context: moc)
}
Expand All @@ -148,6 +163,37 @@ class TrackController: NSObject, ObservableObject {
moc.delete(track)
}

func save(_ trackRepresentation: TrackRepresentation, to track: Track, context moc: NSManagedObjectContext) {
let oldStartDate = track.startDate
trackRepresentation.save(to: track)
if track.startDate != oldStartDate {
// The start date changed
updateTickDateOffsets(for: track, oldStartString: oldStartDate)
loadTicks(for: track)
}
PersistenceController.save(context: moc)
}

func updateTickDateOffsets(for track: Track, oldStartString: String?) {
guard let oldStartString = oldStartString,
let newStartString = track.startDate,
let oldStartDate = DateInRegion(oldStartString, region: .current),
let newStartDate = DateInRegion(newStartString, region: .current) else { return }
let calculatedOffset: Int?
if oldStartDate > newStartDate {
calculatedOffset = (oldStartDate - (newStartDate - 2.hours)).toUnit(.day)
} else {
calculatedOffset = ((oldStartDate - 2.hours) - newStartDate).toUnit(.day)
}

guard let intOffset = calculatedOffset,
let ticks = track.ticks as? Set<Tick> else { return }
let offset = Int16(intOffset)
ticks.forEach { $0.dayOffset += offset }
}

//MARK: Settings

func setCustomDayStart(minutes givenMinutes: Int) {
let minutes: Int
if UserDefaults.standard.bool(forKey: Defaults.customDayStart.rawValue) {
Expand Down Expand Up @@ -202,6 +248,8 @@ class TrackController: NSObject, ObservableObject {

}

//MARK: Fetched Results Controller Delegate

extension TrackController: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
withAnimation {
Expand Down
2 changes: 1 addition & 1 deletion Tickmate/Tickmate/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
Expand Down
14 changes: 12 additions & 2 deletions Tickmate/Tickmate/Model/TrackRepresentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@
//

import SwiftUI
import SwiftDate

struct TrackRepresentation: Equatable, Hashable {
var name: String
var color: Color
var multiple: Bool
var reversed: Bool
var systemImage: String?
var startDate: Date

init(name: String = "", color: Color = .black, multiple: Bool = false, reversed: Bool = false, systemImage: String? = nil) {
init(name: String = "", color: Color = .black, multiple: Bool = false, reversed: Bool = false, systemImage: String? = nil, startDate: Date = Date()) {
self.name = name
self.color = color
self.multiple = multiple
self.reversed = reversed
self.systemImage = systemImage
self.startDate = startDate
}

init(name: String = "", red: Int, green: Int, blue: Int, multiple: Bool = false, reversed: Bool = false, systemImage: String? = nil) {
Expand All @@ -28,6 +31,7 @@ struct TrackRepresentation: Equatable, Hashable {
self.multiple = multiple
self.reversed = reversed
self.systemImage = systemImage
self.startDate = Date()
}

var lightText: Bool {
Expand All @@ -45,6 +49,10 @@ struct TrackRepresentation: Equatable, Hashable {
name = track.name == "New Track" ? "" : track.name ?? ""
multiple = track.multiple
reversed = track.reversed
if let startDateString = track.startDate,
let startDate = TrackController.iso8601.date(from: startDateString) {
self.startDate = startDate
}

if let trackImage = track.systemImage {
systemImage = trackImage
Expand All @@ -65,6 +73,7 @@ struct TrackRepresentation: Equatable, Hashable {
track.reversed = reversed
track.systemImage = systemImage
track.color = Int32(color.rgb)
track.startDate = TrackController.iso8601.string(from: startDate)
}

static func == (rep: TrackRepresentation, track: Track) -> Bool {
Expand All @@ -73,7 +82,8 @@ struct TrackRepresentation: Equatable, Hashable {
rep.multiple == track.multiple &&
rep.reversed == track.reversed &&
rep.systemImage == track.systemImage &&
Int32(rep.color.rgb) == track.color
Int32(rep.color.rgb) == track.color &&
TrackController.iso8601.string(from: rep.startDate) == track.startDate
}

static func == (track: Track, rep: TrackRepresentation) -> Bool {
Expand Down
16 changes: 16 additions & 0 deletions Tickmate/Tickmate/Supplementary Views/View+DismissKeyboard.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// View+DismissKeyboard.swift
// Tickmate
//
// Created by Isaac Lyons on 5/7/21.
//

import SwiftUI

#if canImport(UIKit)
extension View {
func dismissKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
#endif
2 changes: 1 addition & 1 deletion Tickmate/Tickmate/Tickmate.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<string>production</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.vc.isv.Tickmate</string>
Expand Down
1 change: 0 additions & 1 deletion Tickmate/Tickmate/Views/TicksView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ struct TicksView: View {
.environmentObject(vcContainer)
.environmentObject(trackController)
.introspectViewController { vc in
print("TicksView sheet")
vc.presentationController?.delegate = vcContainer
}
}
Expand Down
Loading