import Foundation import SwiftDate import DifferenceKit public struct DateSection: Differentiable, DifferentiableSection, Hashable where T: Differentiable & Hashable { var timestamp: Double = 0 var dateString: String public var elements: [T] public var header: String { "\(dateString) (\(elements.count))" } public init(source: DateSection, elements: C) where C : Swift.Collection, C.Element == Self.Collection.Element { self.timestamp = source.timestamp self.dateString = source.dateString self.elements = Array(elements) } public init(original: DateSection, items: [T]) { self = original self.elements = items } public init(timestamp: Double, items: [T]) { let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .medium let now = DateInRegion(Date(), region: Region.current) let monthStart = now.dateAtStartOf(.month) let weekStart = now.dateAtStartOf(.weekOfMonth) let date = Date(timeIntervalSince1970: timestamp) let dateInRegion = DateInRegion(date, region: Region.current) if dateInRegion.isToday { self.dateString = NSLocalizedString("Today", comment: "") } else if dateInRegion.isYesterday { self.dateString = NSLocalizedString("Yesterday", comment: "") } else if dateInRegion.isAfterDate(weekStart, granularity: .day) { formatter.dateFormat = "EEEE" self.dateString = formatter.string(from: date) } else if dateInRegion.isAfterDate(monthStart, orEqual: false, granularity: .day) { formatter.dateStyle = .medium formatter.timeStyle = .none self.dateString = formatter.string(from: date) } else { formatter.dateFormat = "LLLL yyyy" self.dateString = formatter.string(from: date) } self.timestamp = timestamp self.elements = items } public mutating func append(_ element: T) { self.elements.append(element) } public mutating func insert(_ element: T, at index: Int) { self.elements.insert(element, at: index) } public func index(of element: T) -> Int? { elements.firstIndex { $0.differenceIdentifier == element.differenceIdentifier } } public mutating func replace(_ element: T, at index: Int) { elements[index] = element } public mutating func remove(at index: Int) { elements.remove(at: index) } // MARK: - Differentiable public var differenceIdentifier: String { return dateString } public func isContentEqual(to source: DateSection) -> Bool { return self.differenceIdentifier == source.differenceIdentifier } // MARK: - Hashable public static func == (lhs: DateSection, rhs: DateSection) -> Bool { return lhs.timestamp == rhs.timestamp && lhs.elements == rhs.elements } public func hash(into hasher: inout Hasher) { hasher.combine(self.timestamp) hasher.combine(self.elements) } }