feat: server-side display_title for the group combined view
The group-event icon + owner-name prefix was being done per-client (iOS only),
so web/Android were inconsistent. The /groups/{id}/combined endpoint now emits
a decorated `display_title` per event (group's own icon for group-calendar
events, owner first-name for other members' events) while keeping the raw
`title` for editing. All clients can render this identically. 18 tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -319,6 +319,28 @@ def _strip_busy(event: dict) -> dict:
|
|||||||
return event
|
return event
|
||||||
|
|
||||||
|
|
||||||
|
def _first_name(name: Optional[str]) -> str:
|
||||||
|
if not name:
|
||||||
|
return ""
|
||||||
|
return name.split(" ", 1)[0]
|
||||||
|
|
||||||
|
|
||||||
|
def _decorate_title(title: str, *, is_group: bool, creator: Optional[dict],
|
||||||
|
owner: Optional[dict], me_id: int, group_icon: Optional[str]) -> str:
|
||||||
|
"""Server-side display title for the combined view so every client (web,
|
||||||
|
iOS, Android) renders group events identically: the group's own icon for
|
||||||
|
group-calendar events, the owner's first name for other members' events.
|
||||||
|
The raw `title` is left untouched for editing."""
|
||||||
|
icon = group_icon or "👥"
|
||||||
|
if is_group:
|
||||||
|
if creator and creator.get("id") is not None and creator.get("id") != me_id:
|
||||||
|
return f"{icon} {_first_name(creator.get('display_name'))}: {title}"
|
||||||
|
return f"{icon} {title}"
|
||||||
|
if owner and owner.get("id") is not None and owner.get("id") != me_id:
|
||||||
|
return f"{_first_name(owner.get('display_name'))}: {title}"
|
||||||
|
return title
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{group_id}/combined")
|
@router.get("/{group_id}/combined")
|
||||||
def combined_events(
|
def combined_events(
|
||||||
group_id: int,
|
group_id: int,
|
||||||
@@ -397,6 +419,12 @@ def combined_events(
|
|||||||
# Colour to render with: the group calendar's colour for group
|
# Colour to render with: the group calendar's colour for group
|
||||||
# events, otherwise the owning member's group colour.
|
# events, otherwise the owning member's group colour.
|
||||||
b["display_color"] = group_cal_color if is_group else member_color.get(owner_id)
|
b["display_color"] = group_cal_color if is_group else member_color.get(owner_id)
|
||||||
|
# Decorated title (group icon / owner name) computed server-side
|
||||||
|
# so all clients render identically; raw `title` kept for editing.
|
||||||
|
b["display_title"] = _decorate_title(
|
||||||
|
b.get("title", ""), is_group=is_group, creator=b.get("creator"),
|
||||||
|
owner=owner, me_id=current_user.id, group_icon=group.icon,
|
||||||
|
)
|
||||||
all_events.append(b)
|
all_events.append(b)
|
||||||
|
|
||||||
# Each member shares exactly one calendar into their groups, chosen in their
|
# Each member shares exactly one calendar into their groups, chosen in their
|
||||||
|
|||||||
Reference in New Issue
Block a user