feat: render server display_title for group events (consistent across clients)

CalEvent parses display_title; the combined view uses it (group icon + owner
prefix from the server) instead of client-side decoration, with a fallback for
older servers. Raw title kept for editing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-06-01 17:54:23 +02:00
parent 8521a28520
commit b9547c15f9
2 changed files with 13 additions and 3 deletions

View File

@@ -38,6 +38,9 @@ struct CalEvent: Identifiable, Hashable {
var owner: EventPerson? = nil
var isGroupEvent: Bool = false
var displayColor: String? = nil
// Server-decorated title for the group combined view (group icon / owner
// prefix); rendered in group mode while `title` stays raw for editing.
var displayTitle: String? = nil
// Group view supplies a server-resolved colour; otherwise per-event then calendar colour.
var effectiveColor: String { displayColor ?? color ?? calendarColor }
@@ -78,7 +81,8 @@ struct CalEvent: Identifiable, Hashable {
isPrivate: json["private"] as? Bool ?? false,
owner: EventPerson.from(json["owner"]),
isGroupEvent: json["is_group_event"] as? Bool ?? false,
displayColor: (json["display_color"] as? String).flatMap { $0.isEmpty ? nil : $0 }
displayColor: (json["display_color"] as? String).flatMap { $0.isEmpty ? nil : $0 },
displayTitle: (json["display_title"] as? String).flatMap { $0.isEmpty ? nil : $0 }
)
}
}

View File

@@ -278,10 +278,16 @@ class CalendarStore {
/// Prefix a combined-view event with its owner (others) or 👥 + creator
/// (group calendar). Colour comes from the server's display_color.
private func decorateGroupEvent(_ ev: CalEvent) -> CalEvent {
// Prefer the server-decorated title (group icon + owner prefix) so web,
// iOS and Android render group events identically. `title` stays raw.
if let dt = ev.displayTitle, !dt.isEmpty {
var e = ev
e.title = dt
return e
}
// Fallback for older servers without display_title.
var e = ev
let me = UserDefaults.standard.integer(forKey: "userId")
// Use the group's own icon (set in group settings) so group events are
// recognisable; fall back to a generic people glyph.
let groupIcon = activeGroup?.icon ?? "👥"
func first(_ s: String) -> String { s.split(separator: " ").first.map(String.init) ?? s }
if ev.isGroupEvent {