kvyatkovskys / KVKCalendar

A most fully customization calendar for Apple platforms 📅
https://kvyatkovskys.github.io/KVKCalendar/
MIT License
537 stars 118 forks source link

Use the `willAddNewEvent(_: _:)` method that return `Event?` instead of the old method that return `Bool`. #370

Closed rakuyoMo closed 1 month ago

rakuyoMo commented 1 month ago

Create conditions for modifying event.

For the current architecture, we have the following code:

func willAddNewEvent(_ event: Event, _ date: Date?) -> Bool {
    guard
        let date = date,
        // Add 1 second to avoid overlapping with the start time of subsequent events
        let start = style.calendar.date(byAdding: .second, value: 1, to: date),
        let end = style.calendar.date(byAdding: .hour, value: 1, to: date),
        !events.contains(where: { event in
            // When currently in the adding state || Long press at the time point of an existing event
            event.isNew || (start.sak.hour >= event.start.sak.hour && end.sak.hour <= event.end.sak.hour)
        })
    else {
        return false
    }

    let currentDate = Date()
    switch style.calendar.compare(end, to: currentDate, toGranularity: .day) {
    case .orderedSame:
        return end.sak.hour > currentDate.sak.hour

    case .orderedAscending:
        // Adding events with past dates is not allowed
        return false

    case .orderedDescending:
        return true
    }
}

func didAddNewEvent(_ event: Event, _ date: Date?) {
    guard
        let date = date,
        // Add 1 second to avoid overlapping with the start time of subsequent events
        let start = style.calendar.date(byAdding: .second, value: 1, to: date),
        let end = style.calendar.date(byAdding: .hour, value: 1, to: date)
    else {
        return
    }

    var newEvent = event
    newEvent.start = start
    newEvent.end = end

    events.append(newEvent)

    func _createTime(with keyPath: KeyPath<Event, Date>) -> TimeContainer {
        let tmpDate = newEvent[keyPath: keyPath].sak
        return .init(minute: tmpDate.minute, hour: tmpDate.hour)
    }

    startTime = _createTime(with: \.start)
    endTime = _createTime(with: \.end)
}

You can find two similar guard codes.

The new method in pr can simplify this process:

func willAddNewEvent(_ event: Event, _ date: Date?) -> Event? {
    guard
        let date = date,
        // Add 1 second to avoid overlapping with the start time of subsequent events
        let start = style.calendar.date(byAdding: .second, value: 1, to: date),
        let end = style.calendar.date(byAdding: .hour, value: 1, to: date),
        !events.contains(where: { event in
            // When currently in the adding state || Long press at the time point of an existing event
            event.isNew || (start.sak.hour >= event.start.sak.hour && end.sak.hour <= event.end.sak.hour)
        })
    else {
        return nil
    }

    lazy var createNewEvent: () -> Event = {
        var newEvent = event
        newEvent.start = start
        newEvent.end = end
        return newEvent
    }

    let currentDate = Date()
    switch style.calendar.compare(end, to: currentDate, toGranularity: .day) {
    case .orderedSame:
        return (end.sak.hour > currentDate.sak.hour) ? createNewEvent() : nil

    case .orderedAscending:
        // Adding events with past dates is not allowed
        return nil

    case .orderedDescending:
        return createNewEvent()
    }
}

func didAddNewEvent(_ event: Event, _ date: Date?) {
    events.append(event)

    func _createTime(with keyPath: KeyPath<Event, Date>) -> TimeContainer {
        let tmpDate = event[keyPath: keyPath].sak
        return .init(minute: tmpDate.minute, hour: tmpDate.hour)
    }

    startTime = _createTime(with: \.start)
    endTime = _creat
}