expo-calendar-kit 2.1.5 → 2.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/ExpoCalendarKitView.swift +202 -349
- package/package.json +1 -1
|
@@ -1,410 +1,263 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
2
|
import UIKit
|
|
3
|
-
import EventKit
|
|
4
3
|
import CalendarKit
|
|
4
|
+
import EventKit
|
|
5
5
|
|
|
6
|
-
// MARK: -
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
let endDate: Date
|
|
12
|
-
let color: UIColor?
|
|
13
|
-
let backgroundColor: UIColor?
|
|
14
|
-
let isAllDay: Bool
|
|
15
|
-
let location: String?
|
|
16
|
-
let notes: String?
|
|
17
|
-
let userInfo: [String: Any]?
|
|
18
|
-
|
|
19
|
-
init(from dict: [String: Any]) {
|
|
20
|
-
self.id = dict["id"] as? String ?? UUID().uuidString
|
|
21
|
-
self.title = dict["title"] as? String ?? ""
|
|
22
|
-
|
|
23
|
-
// Handle date parsing
|
|
24
|
-
if let startTimestamp = dict["startDate"] as? Double {
|
|
25
|
-
self.startDate = Date(timeIntervalSince1970: startTimestamp / 1000)
|
|
26
|
-
} else {
|
|
27
|
-
self.startDate = Date()
|
|
6
|
+
// MARK: - EKWrapper (copied from CalendarApp)
|
|
7
|
+
final class EKWrapper: EventDescriptor {
|
|
8
|
+
public var dateInterval: DateInterval {
|
|
9
|
+
get {
|
|
10
|
+
DateInterval(start: ekEvent.startDate, end: ekEvent.endDate)
|
|
28
11
|
}
|
|
29
12
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
self.endDate = Date().addingTimeInterval(3600) // 1 hour later
|
|
13
|
+
set {
|
|
14
|
+
ekEvent.startDate = newValue.start
|
|
15
|
+
ekEvent.endDate = newValue.end
|
|
34
16
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
self.color = nil
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public var isAllDay: Bool {
|
|
20
|
+
get {
|
|
21
|
+
ekEvent.isAllDay
|
|
41
22
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
self.backgroundColor = UIColor(hex: backgroundColorHex)
|
|
45
|
-
} else {
|
|
46
|
-
self.backgroundColor = nil
|
|
23
|
+
set {
|
|
24
|
+
ekEvent.isAllDay = newValue
|
|
47
25
|
}
|
|
48
|
-
|
|
49
|
-
self.isAllDay = dict["isAllDay"] as? Bool ?? false
|
|
50
|
-
self.location = dict["location"] as? String
|
|
51
|
-
self.notes = dict["notes"] as? String
|
|
52
|
-
self.userInfo = dict["userInfo"] as? [String: Any]
|
|
53
26
|
}
|
|
54
27
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
ekEvent.title = self.title
|
|
59
|
-
ekEvent.startDate = self.startDate
|
|
60
|
-
ekEvent.endDate = self.endDate
|
|
61
|
-
ekEvent.isAllDay = self.isAllDay
|
|
62
|
-
if let location = self.location {
|
|
63
|
-
ekEvent.location = location
|
|
64
|
-
}
|
|
65
|
-
if let notes = self.notes {
|
|
66
|
-
ekEvent.notes = notes
|
|
28
|
+
public var text: String {
|
|
29
|
+
get {
|
|
30
|
+
ekEvent.title
|
|
67
31
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
ekEvent.
|
|
32
|
+
|
|
33
|
+
set {
|
|
34
|
+
ekEvent.title = newValue
|
|
71
35
|
}
|
|
72
|
-
return ekEvent
|
|
73
36
|
}
|
|
37
|
+
|
|
38
|
+
public var attributedText: NSAttributedString?
|
|
39
|
+
public var lineBreakMode: NSLineBreakMode?
|
|
74
40
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return String(notes.dropFirst("ExpoCalendarKit_ID:".count))
|
|
41
|
+
public var color: UIColor {
|
|
42
|
+
get {
|
|
43
|
+
UIColor(cgColor: ekEvent.calendar.cgColor)
|
|
79
44
|
}
|
|
80
|
-
return nil
|
|
81
45
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// MARK: - Main Calendar View
|
|
85
|
-
public class ExpoCalendarKitView: UIView, DayViewDelegate, EventDataSource {
|
|
86
|
-
private var dayView: DayView!
|
|
87
|
-
private var events: [CalendarEvent] = []
|
|
88
|
-
private var currentDate: Date = Date()
|
|
89
46
|
|
|
90
|
-
|
|
91
|
-
|
|
47
|
+
public var backgroundColor = UIColor()
|
|
48
|
+
public var textColor = SystemColors.label
|
|
49
|
+
public var font = UIFont.boldSystemFont(ofSize: 12)
|
|
50
|
+
public weak var editedEvent: EventDescriptor? {
|
|
51
|
+
didSet {
|
|
52
|
+
updateColors()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
92
55
|
|
|
93
|
-
|
|
94
|
-
var onEventPress: ((String) -> Void)?
|
|
95
|
-
var onEventLongPress: ((String) -> Void)?
|
|
96
|
-
var onTimePress: ((Double) -> Void)?
|
|
97
|
-
var onTimeLongPress: ((Double) -> Void)?
|
|
98
|
-
var onDateChanged: ((Double) -> Void)?
|
|
56
|
+
public private(set) var ekEvent: EKEvent
|
|
99
57
|
|
|
100
|
-
public
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
setupCalendarView()
|
|
58
|
+
public init(eventKitEvent: EKEvent) {
|
|
59
|
+
self.ekEvent = eventKitEvent
|
|
60
|
+
applyStandardColors()
|
|
104
61
|
}
|
|
105
62
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
63
|
+
public func makeEditable() -> Self {
|
|
64
|
+
let cloned = Self(eventKitEvent: ekEvent)
|
|
65
|
+
cloned.editedEvent = self
|
|
66
|
+
return cloned
|
|
109
67
|
}
|
|
110
68
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
dayView = DayView()
|
|
115
|
-
dayView.delegate = self
|
|
116
|
-
dayView.dataSource = self
|
|
117
|
-
dayView.translatesAutoresizingMaskIntoConstraints = false
|
|
118
|
-
addSubview(dayView)
|
|
119
|
-
|
|
120
|
-
NSLayoutConstraint.activate([
|
|
121
|
-
dayView.topAnchor.constraint(equalTo: topAnchor),
|
|
122
|
-
dayView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
123
|
-
dayView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
124
|
-
dayView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
|
125
|
-
])
|
|
126
|
-
|
|
127
|
-
// Apply default style
|
|
128
|
-
applyStyle()
|
|
129
|
-
|
|
130
|
-
// Set initial date
|
|
131
|
-
dayView.move(to: currentDate)
|
|
132
|
-
|
|
133
|
-
print("🔥 CalendarKit DayView setup complete")
|
|
69
|
+
public func commitEditing() {
|
|
70
|
+
guard let edited = editedEvent else {return}
|
|
71
|
+
edited.dateInterval = dateInterval
|
|
134
72
|
}
|
|
135
73
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
print("🔥 setEvents called with \(eventDicts.count) events")
|
|
139
|
-
self.events = eventDicts.map { CalendarEvent(from: $0) }
|
|
140
|
-
print("🔥 Converted to \(self.events.count) CalendarEvent objects")
|
|
141
|
-
for (index, event) in self.events.enumerated() {
|
|
142
|
-
print("🔥 Event \(index): \(event.title) from \(event.startDate) to \(event.endDate)")
|
|
143
|
-
}
|
|
144
|
-
if let dayView = dayView {
|
|
145
|
-
dayView.reloadData()
|
|
146
|
-
}
|
|
74
|
+
private func updateColors() {
|
|
75
|
+
(editedEvent != nil) ? applyEditingColors() : applyStandardColors()
|
|
147
76
|
}
|
|
148
77
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
78
|
+
/// Colors used when event is not in editing mode
|
|
79
|
+
private func applyStandardColors() {
|
|
80
|
+
backgroundColor = dynamicStandardBackgroundColor()
|
|
81
|
+
textColor = dynamicStandardTextColor()
|
|
154
82
|
}
|
|
155
83
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
84
|
+
/// Colors used in editing mode
|
|
85
|
+
private func applyEditingColors() {
|
|
86
|
+
backgroundColor = color.withAlphaComponent(0.95)
|
|
87
|
+
textColor = .white
|
|
159
88
|
}
|
|
160
89
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
90
|
+
/// Dynamic color that changes depending on the user interface style (dark / light)
|
|
91
|
+
private func dynamicStandardBackgroundColor() -> UIColor {
|
|
92
|
+
let light = backgroundColorForLightTheme(baseColor: color)
|
|
93
|
+
let dark = backgroundColorForDarkTheme(baseColor: color)
|
|
94
|
+
return dynamicColor(light: light, dark: dark)
|
|
165
95
|
}
|
|
166
96
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// Apply only the colors that are supported by CalendarKit
|
|
173
|
-
if let headerBgColor = customCalendarStyle.headerBackgroundColor {
|
|
174
|
-
style.header.backgroundColor = headerBgColor
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if let timelineBgColor = customCalendarStyle.timelineBackgroundColor {
|
|
178
|
-
style.timeline.backgroundColor = timelineBgColor
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if let timeTextColor = customCalendarStyle.timeTextColor {
|
|
182
|
-
style.timeline.timeColor = timeTextColor
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if let separatorColor = customCalendarStyle.separatorColor {
|
|
186
|
-
style.timeline.separatorColor = separatorColor
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
dayView.updateStyle(style)
|
|
97
|
+
/// Dynamic color that changes depending on the user interface style (dark / light)
|
|
98
|
+
private func dynamicStandardTextColor() -> UIColor {
|
|
99
|
+
let light = textColorForLightTheme(baseColor: color)
|
|
100
|
+
return dynamicColor(light: light, dark: color)
|
|
190
101
|
}
|
|
191
102
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
// HARDCODED EVENTS FOR TESTING - BYPASS BRIDGING ISSUES
|
|
198
|
-
let today = Date()
|
|
199
|
-
|
|
200
|
-
let meeting = calendar.date(bySettingHour: 10, minute: 0, second: 0, of: today) ?? today
|
|
201
|
-
let meetingEnd = calendar.date(bySettingHour: 11, minute: 0, second: 0, of: today) ?? today
|
|
202
|
-
|
|
203
|
-
let lunch = calendar.date(bySettingHour: 12, minute: 0, second: 0, of: today) ?? today
|
|
204
|
-
let lunchEnd = calendar.date(bySettingHour: 13, minute: 0, second: 0, of: today) ?? today
|
|
205
|
-
|
|
206
|
-
let review = calendar.date(bySettingHour: 14, minute: 0, second: 0, of: today) ?? today
|
|
207
|
-
let reviewEnd = calendar.date(bySettingHour: 15, minute: 0, second: 0, of: today) ?? today
|
|
208
|
-
|
|
209
|
-
let hardcodedEvents: [CalendarEvent] = [
|
|
210
|
-
CalendarEvent(from: [
|
|
211
|
-
"id": "hardcoded1",
|
|
212
|
-
"title": "🔥 HARDCODED Meeting",
|
|
213
|
-
"startDate": meeting.timeIntervalSince1970 * 1000,
|
|
214
|
-
"endDate": meetingEnd.timeIntervalSince1970 * 1000,
|
|
215
|
-
"backgroundColor": "#FF0000",
|
|
216
|
-
"color": "#FFFFFF"
|
|
217
|
-
]),
|
|
218
|
-
CalendarEvent(from: [
|
|
219
|
-
"id": "hardcoded2",
|
|
220
|
-
"title": "🔥 HARDCODED Lunch",
|
|
221
|
-
"startDate": lunch.timeIntervalSince1970 * 1000,
|
|
222
|
-
"endDate": lunchEnd.timeIntervalSince1970 * 1000,
|
|
223
|
-
"backgroundColor": "#00FF00",
|
|
224
|
-
"color": "#FFFFFF"
|
|
225
|
-
]),
|
|
226
|
-
CalendarEvent(from: [
|
|
227
|
-
"id": "hardcoded3",
|
|
228
|
-
"title": "🔥 HARDCODED Review",
|
|
229
|
-
"startDate": review.timeIntervalSince1970 * 1000,
|
|
230
|
-
"endDate": reviewEnd.timeIntervalSince1970 * 1000,
|
|
231
|
-
"backgroundColor": "#0000FF",
|
|
232
|
-
"color": "#FFFFFF"
|
|
233
|
-
])
|
|
234
|
-
]
|
|
235
|
-
|
|
236
|
-
print("🔥 Using hardcoded events instead of bridged events")
|
|
237
|
-
let result = hardcodedEvents.compactMap { event in
|
|
238
|
-
let isToday = calendar.isDate(event.startDate, inSameDayAs: date) ||
|
|
239
|
-
calendar.isDate(event.endDate, inSameDayAs: date) ||
|
|
240
|
-
(event.startDate < date && event.endDate > date)
|
|
241
|
-
print("🔥 Hardcoded Event '\(event.title)': \(event.startDate) - \(event.endDate), isToday: \(isToday)")
|
|
242
|
-
if isToday {
|
|
243
|
-
let ekEvent = event.toEKEvent()
|
|
244
|
-
return EKWrapper(eventKitEvent: ekEvent)
|
|
245
|
-
}
|
|
246
|
-
return nil
|
|
247
|
-
}
|
|
248
|
-
print("🔥 Returning \(result.count) hardcoded events for date \(date)")
|
|
249
|
-
return result
|
|
103
|
+
private func textColorForLightTheme(baseColor: UIColor) -> UIColor {
|
|
104
|
+
var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
|
|
105
|
+
baseColor.getHue(&h, saturation: &s, brightness: &b, alpha: &a)
|
|
106
|
+
return UIColor(hue: h, saturation: s, brightness: b * 0.4, alpha: a)
|
|
250
107
|
}
|
|
251
108
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if let ekWrapper = eventView.descriptor as? EKWrapper {
|
|
255
|
-
let eventId = CalendarEvent.extractOriginalId(from: ekWrapper.ekEvent) ?? ekWrapper.ekEvent.title ?? ""
|
|
256
|
-
onEventPress?(eventId)
|
|
257
|
-
}
|
|
109
|
+
private func backgroundColorForLightTheme(baseColor: UIColor) -> UIColor {
|
|
110
|
+
baseColor.withAlphaComponent(0.3)
|
|
258
111
|
}
|
|
259
112
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
113
|
+
private func backgroundColorForDarkTheme(baseColor: UIColor) -> UIColor {
|
|
114
|
+
var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
|
|
115
|
+
color.getHue(&h, saturation: &s, brightness: &b, alpha: &a)
|
|
116
|
+
return UIColor(hue: h, saturation: s, brightness: b * 0.4, alpha: a * 0.8)
|
|
265
117
|
}
|
|
266
118
|
|
|
267
|
-
|
|
268
|
-
|
|
119
|
+
private func dynamicColor(light: UIColor, dark: UIColor) -> UIColor {
|
|
120
|
+
if #available(iOS 13.0, *) {
|
|
121
|
+
return UIColor { traitCollection in
|
|
122
|
+
let interfaceStyle = traitCollection.userInterfaceStyle
|
|
123
|
+
switch interfaceStyle {
|
|
124
|
+
case .dark:
|
|
125
|
+
return dark
|
|
126
|
+
default:
|
|
127
|
+
return light
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
return light
|
|
132
|
+
}
|
|
269
133
|
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// MARK: - Calendar View Controller (following CalendarApp pattern)
|
|
137
|
+
final class CalendarViewController: DayViewController {
|
|
138
|
+
private var eventStore = EKEventStore() // Not used but needed for EKEvent creation
|
|
270
139
|
|
|
271
|
-
|
|
272
|
-
|
|
140
|
+
override func viewDidLoad() {
|
|
141
|
+
super.viewDidLoad()
|
|
142
|
+
print("🔥 CalendarViewController viewDidLoad called")
|
|
143
|
+
// Don't request calendar access - we'll use hardcoded events
|
|
273
144
|
}
|
|
274
145
|
|
|
275
|
-
|
|
276
|
-
// Handle drag begin if needed
|
|
277
|
-
}
|
|
146
|
+
// MARK: - DayViewDataSource
|
|
278
147
|
|
|
279
|
-
|
|
280
|
-
|
|
148
|
+
// This is the main method - following CalendarApp pattern exactly
|
|
149
|
+
override func eventsForDate(_ date: Date) -> [EventDescriptor] {
|
|
150
|
+
print("🔥 eventsForDate called for \(date)")
|
|
151
|
+
|
|
152
|
+
let calendar = Calendar.current
|
|
153
|
+
|
|
154
|
+
// Check if the requested date is today
|
|
155
|
+
guard calendar.isDate(date, inSameDayAs: Date()) else {
|
|
156
|
+
print("🔥 Not today, returning empty events")
|
|
157
|
+
return []
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
print("🔥 Creating hardcoded events for today using CalendarApp pattern")
|
|
161
|
+
|
|
162
|
+
// Create hardcoded events using EKEvent (like CalendarApp)
|
|
163
|
+
var events: [EKWrapper] = []
|
|
164
|
+
|
|
165
|
+
// Event 1: Meeting
|
|
166
|
+
let meetingEvent = EKEvent(eventStore: eventStore)
|
|
167
|
+
meetingEvent.title = "🔥 HARDCODED Meeting"
|
|
168
|
+
meetingEvent.startDate = calendar.date(bySettingHour: 10, minute: 0, second: 0, of: Date()) ?? Date()
|
|
169
|
+
meetingEvent.endDate = calendar.date(bySettingHour: 11, minute: 0, second: 0, of: Date()) ?? Date()
|
|
170
|
+
meetingEvent.calendar = createMockCalendar(color: UIColor.red)
|
|
171
|
+
events.append(EKWrapper(eventKitEvent: meetingEvent))
|
|
172
|
+
|
|
173
|
+
// Event 2: Lunch
|
|
174
|
+
let lunchEvent = EKEvent(eventStore: eventStore)
|
|
175
|
+
lunchEvent.title = "🔥 HARDCODED Lunch"
|
|
176
|
+
lunchEvent.startDate = calendar.date(bySettingHour: 12, minute: 0, second: 0, of: Date()) ?? Date()
|
|
177
|
+
lunchEvent.endDate = calendar.date(bySettingHour: 13, minute: 0, second: 0, of: Date()) ?? Date()
|
|
178
|
+
lunchEvent.calendar = createMockCalendar(color: UIColor.green)
|
|
179
|
+
events.append(EKWrapper(eventKitEvent: lunchEvent))
|
|
180
|
+
|
|
181
|
+
// Event 3: Review
|
|
182
|
+
let reviewEvent = EKEvent(eventStore: eventStore)
|
|
183
|
+
reviewEvent.title = "🔥 HARDCODED Review"
|
|
184
|
+
reviewEvent.startDate = calendar.date(bySettingHour: 14, minute: 0, second: 0, of: Date()) ?? Date()
|
|
185
|
+
reviewEvent.endDate = calendar.date(bySettingHour: 15, minute: 0, second: 0, of: Date()) ?? Date()
|
|
186
|
+
reviewEvent.calendar = createMockCalendar(color: UIColor.blue)
|
|
187
|
+
events.append(EKWrapper(eventKitEvent: reviewEvent))
|
|
188
|
+
|
|
189
|
+
print("🔥 Returning \(events.count) hardcoded events")
|
|
190
|
+
return events
|
|
281
191
|
}
|
|
282
192
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
193
|
+
private func createMockCalendar(color: UIColor) -> EKCalendar {
|
|
194
|
+
let calendar = EKCalendar(for: .event, eventStore: eventStore)
|
|
195
|
+
calendar.cgColor = color.cgColor
|
|
196
|
+
return calendar
|
|
286
197
|
}
|
|
287
198
|
|
|
288
|
-
|
|
289
|
-
currentDate = date
|
|
290
|
-
onDateChanged?(date.timeIntervalSince1970 * 1000)
|
|
291
|
-
}
|
|
199
|
+
// MARK: - DayViewDelegate
|
|
292
200
|
|
|
293
|
-
|
|
294
|
-
|
|
201
|
+
override func dayViewDidSelectEventView(_ eventView: EventView) {
|
|
202
|
+
guard let ckEvent = eventView.descriptor as? EKWrapper else {
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
print("🔥 Event selected: \(ckEvent.ekEvent.title ?? "Unknown")")
|
|
295
206
|
}
|
|
296
207
|
}
|
|
297
208
|
|
|
298
|
-
// MARK: -
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { return nil }
|
|
307
|
-
|
|
308
|
-
let red = CGFloat((rgb & 0xFF0000) >> 16) / 255.0
|
|
309
|
-
let green = CGFloat((rgb & 0x00FF00) >> 8) / 255.0
|
|
310
|
-
let blue = CGFloat(rgb & 0x0000FF) / 255.0
|
|
311
|
-
|
|
312
|
-
self.init(red: red, green: green, blue: blue, alpha: 1.0)
|
|
209
|
+
// MARK: - Expo View Wrapper
|
|
210
|
+
public class ExpoCalendarKitView: UIView {
|
|
211
|
+
private var calendarViewController: CalendarViewController!
|
|
212
|
+
|
|
213
|
+
public override init(frame: CGRect) {
|
|
214
|
+
print("🔥 ExpoCalendarKitView init called with frame: \(frame)")
|
|
215
|
+
super.init(frame: frame)
|
|
216
|
+
setupCalendarViewController()
|
|
313
217
|
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// MARK: - Style Configuration
|
|
317
|
-
struct ExpoCalendarStyle {
|
|
318
|
-
var backgroundColor: UIColor?
|
|
319
|
-
var headerBackgroundColor: UIColor?
|
|
320
|
-
var headerTextColor: UIColor?
|
|
321
|
-
var weekdayTextColor: UIColor?
|
|
322
|
-
var timelineBackgroundColor: UIColor?
|
|
323
|
-
var timeTextColor: UIColor?
|
|
324
|
-
var eventBackgroundColor: UIColor?
|
|
325
|
-
var eventTextColor: UIColor?
|
|
326
|
-
var todayBackgroundColor: UIColor?
|
|
327
|
-
var todayTextColor: UIColor?
|
|
328
|
-
var separatorColor: UIColor?
|
|
329
|
-
var hourLineColor: UIColor?
|
|
330
|
-
var halfHourLineColor: UIColor?
|
|
331
|
-
var quarterHourLineColor: UIColor?
|
|
332
|
-
var timelineWidth: CGFloat?
|
|
333
|
-
var hourHeight: CGFloat?
|
|
334
|
-
var eventMargin: CGFloat?
|
|
335
|
-
var eventCornerRadius: CGFloat?
|
|
336
218
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
if let headerTextColorHex = dict["headerTextColor"] as? String {
|
|
347
|
-
headerTextColor = UIColor(hex: headerTextColorHex)
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if let weekdayTextColorHex = dict["weekdayTextColor"] as? String {
|
|
351
|
-
weekdayTextColor = UIColor(hex: weekdayTextColorHex)
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
if let timelineBgColorHex = dict["timelineBackgroundColor"] as? String {
|
|
355
|
-
timelineBackgroundColor = UIColor(hex: timelineBgColorHex)
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if let timeTextColorHex = dict["timeTextColor"] as? String {
|
|
359
|
-
timeTextColor = UIColor(hex: timeTextColorHex)
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
if let eventBgColorHex = dict["eventBackgroundColor"] as? String {
|
|
363
|
-
eventBackgroundColor = UIColor(hex: eventBgColorHex)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
if let eventTextColorHex = dict["eventTextColor"] as? String {
|
|
367
|
-
eventTextColor = UIColor(hex: eventTextColorHex)
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
if let todayBgColorHex = dict["todayBackgroundColor"] as? String {
|
|
371
|
-
todayBackgroundColor = UIColor(hex: todayBgColorHex)
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
if let todayTextColorHex = dict["todayTextColor"] as? String {
|
|
375
|
-
todayTextColor = UIColor(hex: todayTextColorHex)
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if let separatorColorHex = dict["separatorColor"] as? String {
|
|
379
|
-
separatorColor = UIColor(hex: separatorColorHex)
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
if let hourLineColorHex = dict["hourLineColor"] as? String {
|
|
383
|
-
hourLineColor = UIColor(hex: hourLineColorHex)
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
if let halfHourLineColorHex = dict["halfHourLineColor"] as? String {
|
|
387
|
-
halfHourLineColor = UIColor(hex: halfHourLineColorHex)
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
if let quarterHourLineColorHex = dict["quarterHourLineColor"] as? String {
|
|
391
|
-
quarterHourLineColor = UIColor(hex: quarterHourLineColorHex)
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if let width = dict["timelineWidth"] as? NSNumber {
|
|
395
|
-
timelineWidth = CGFloat(width.floatValue)
|
|
396
|
-
}
|
|
219
|
+
required public init?(coder: NSCoder) {
|
|
220
|
+
super.init(coder: coder)
|
|
221
|
+
setupCalendarViewController()
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private func setupCalendarViewController() {
|
|
225
|
+
print("🔥 setupCalendarViewController called")
|
|
397
226
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
227
|
+
calendarViewController = CalendarViewController()
|
|
228
|
+
addSubview(calendarViewController.view)
|
|
401
229
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
230
|
+
calendarViewController.view.translatesAutoresizingMaskIntoConstraints = false
|
|
231
|
+
NSLayoutConstraint.activate([
|
|
232
|
+
calendarViewController.view.topAnchor.constraint(equalTo: topAnchor),
|
|
233
|
+
calendarViewController.view.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
234
|
+
calendarViewController.view.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
235
|
+
calendarViewController.view.bottomAnchor.constraint(equalTo: bottomAnchor)
|
|
236
|
+
])
|
|
405
237
|
|
|
406
|
-
|
|
407
|
-
eventCornerRadius = CGFloat(radius.floatValue)
|
|
408
|
-
}
|
|
238
|
+
print("🔥 CalendarViewController setup complete")
|
|
409
239
|
}
|
|
410
|
-
|
|
240
|
+
|
|
241
|
+
// MARK: - Public Methods (for React Native bridge)
|
|
242
|
+
public func setEvents(_ eventDicts: [[String: Any]]) {
|
|
243
|
+
print("🔥 setEvents called with \(eventDicts.count) events (ignored - using hardcoded)")
|
|
244
|
+
// For now, ignore and use hardcoded events
|
|
245
|
+
calendarViewController.reloadData()
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
public func setDate(_ timestamp: Double) {
|
|
249
|
+
let date = Date(timeIntervalSince1970: timestamp / 1000)
|
|
250
|
+
print("🔥 setDate called with \(date)")
|
|
251
|
+
calendarViewController.move(to: date)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public func updateStyle(_ styleDict: [String: Any]) {
|
|
255
|
+
print("🔥 updateStyle called")
|
|
256
|
+
// Apply custom style if needed
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
public func scrollToCurrentTime() {
|
|
260
|
+
print("🔥 scrollToCurrentTime called")
|
|
261
|
+
calendarViewController.scrollToFirstEvent()
|
|
262
|
+
}
|
|
263
|
+
}
|