Let a hidden iCal calendar become visible again
An iCal subscription could be banished but never un-banished. The server has always sent and accepted sidebar_hidden for subscriptions, but iOS left the field off ICalSubscription entirely and omitted "ical" from serverManagedSources, from setCalendarSidebarHidden and from both places that reconcile the server's flag. So the key went into banishedCalendarKeys and nothing ever took it out: refreshFromCache filters on that set as well as on hiddenCalendarKeys, which is why showing the calendar again left its events invisible and no amount of syncing helped. Closed on all four sides. The account models are also no longer brittle about absent fields. HomeAssistantAccount required auth_method, and CalDAVCalendar and GoogleCalendar required sidebar_hidden, with no custom decoder — one missing key threw, the `try?` at the call site turned that into an empty list, and the reconciliation silently did not run, stranding calendars as banished in exactly the same way. HACalendar already carried a lenient decoder for this reason; the other three now do too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ab0c64a9e1
commit
9f864617c2
@@ -111,6 +111,16 @@ struct CalDAVCalendar: Codable, Identifiable {
|
||||
case sidebarHidden = "sidebar_hidden"
|
||||
case remindersEnabled = "reminders_enabled"
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try c.decode(Int.self, forKey: .id)
|
||||
name = try c.decodeIfPresent(String.self, forKey: .name) ?? ""
|
||||
color = try c.decodeIfPresent(String.self, forKey: .color)
|
||||
enabled = try c.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||
sidebarHidden = try c.decodeIfPresent(Bool.self, forKey: .sidebarHidden) ?? false
|
||||
remindersEnabled = try c.decodeIfPresent(Bool.self, forKey: .remindersEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
struct LocalCalendar: Codable, Identifiable {
|
||||
@@ -161,12 +171,27 @@ struct ICalSubscription: Codable, Identifiable {
|
||||
var refreshMinutes: Int
|
||||
var lastFetched: String?
|
||||
var remindersEnabled: Bool?
|
||||
var sidebarHidden: Bool = false
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id, name, url, color, enabled
|
||||
case refreshMinutes = "refresh_minutes"
|
||||
case lastFetched = "last_fetched"
|
||||
case remindersEnabled = "reminders_enabled"
|
||||
case sidebarHidden = "sidebar_hidden"
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try c.decode(Int.self, forKey: .id)
|
||||
name = try c.decodeIfPresent(String.self, forKey: .name) ?? ""
|
||||
url = try c.decodeIfPresent(String.self, forKey: .url) ?? ""
|
||||
color = try c.decodeIfPresent(String.self, forKey: .color) ?? "#4285f4"
|
||||
enabled = try c.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||
refreshMinutes = try c.decodeIfPresent(Int.self, forKey: .refreshMinutes) ?? 60
|
||||
lastFetched = try c.decodeIfPresent(String.self, forKey: .lastFetched)
|
||||
remindersEnabled = try c.decodeIfPresent(Bool.self, forKey: .remindersEnabled)
|
||||
sidebarHidden = try c.decodeIfPresent(Bool.self, forKey: .sidebarHidden) ?? false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +214,16 @@ struct GoogleCalendar: Codable, Identifiable {
|
||||
case sidebarHidden = "sidebar_hidden"
|
||||
case remindersEnabled = "reminders_enabled"
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try c.decode(Int.self, forKey: .id)
|
||||
name = try c.decodeIfPresent(String.self, forKey: .name) ?? ""
|
||||
color = try c.decodeIfPresent(String.self, forKey: .color)
|
||||
enabled = try c.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||
sidebarHidden = try c.decodeIfPresent(Bool.self, forKey: .sidebarHidden) ?? false
|
||||
remindersEnabled = try c.decodeIfPresent(Bool.self, forKey: .remindersEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
struct HomeAssistantAccount: Codable, Identifiable {
|
||||
@@ -202,6 +237,15 @@ struct HomeAssistantAccount: Codable, Identifiable {
|
||||
case id, name, url, calendars
|
||||
case authMethod = "auth_method"
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try c.decode(Int.self, forKey: .id)
|
||||
name = try c.decodeIfPresent(String.self, forKey: .name) ?? "Home Assistant"
|
||||
url = try c.decodeIfPresent(String.self, forKey: .url) ?? ""
|
||||
authMethod = try c.decodeIfPresent(String.self, forKey: .authMethod) ?? "token"
|
||||
calendars = try c.decodeIfPresent([HACalendar].self, forKey: .calendars)
|
||||
}
|
||||
}
|
||||
|
||||
struct HACalendar: Codable, Identifiable {
|
||||
|
||||
Reference in New Issue
Block a user