Skip to content

Commit

Permalink
Merge pull request #23 from Isvvc/change-start-date
Browse files Browse the repository at this point in the history
Change start date
  • Loading branch information
skjiisa authored May 7, 2021
2 parents 2949dd1 + c3e5c62 commit 3c8403c
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 24 deletions.
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

0 comments on commit 3c8403c

Please sign in to comment.