feat(sharing): let share recipients recolour a shared calendar

The colour dot for a shared (non-owned) local calendar was disabled, and the
colour write hit the owner-only PUT /calendars/{id} (404 for recipients). Now
the dot is always editable and colour changes go through the dedicated
PUT /calendars/{id}/color endpoint, which stores a recipient's own per-user
colour server-side (synced across devices) without granting write or rename.
Renaming stays owner-only (no rename UI for shared calendars).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Guido Schmit
2026-07-06 20:49:29 +02:00
parent 993d5d83e1
commit bd3c92aa86
3 changed files with 12 additions and 3 deletions

View File

@@ -222,9 +222,11 @@ class CalendarRepository @Inject constructor(
suspend fun deleteHomeAssistantAccount(id: Int) =
guarded { api.deleteHomeAssistantAccount(id).ensureSuccess() }
/** Change a local calendar's colour. */
/** Change a local calendar's colour. Uses the colour-only endpoint so share
* recipients can recolour their view (own per-user colour) without needing
* write access or being able to rename the calendar. */
suspend fun updateLocalCalendarColor(id: Int, color: String) = guarded {
api.updateLocalCalendar(id, jsonBody("color" to color)).ensureSuccess()
api.setLocalCalendarColor(id, jsonBody("color" to color)).ensureSuccess()
}
/** Change an iCal subscription's colour. */

View File

@@ -155,6 +155,11 @@ interface CalendarrApi {
@PUT("api/local/calendars/{id}")
suspend fun updateLocalCalendar(@Path("id") id: Int, @Body body: RequestBody): Response<ResponseBody>
// Colour-only update that works for owners AND share recipients (recipients
// get their own per-user colour; owners change the calendar's colour).
@PUT("api/local/calendars/{id}/color")
suspend fun setLocalCalendarColor(@Path("id") id: Int, @Body body: RequestBody): Response<ResponseBody>
@DELETE("api/local/calendars/{id}")
suspend fun deleteLocalCalendar(@Path("id") id: Int): Response<ResponseBody>

View File

@@ -380,7 +380,9 @@ private fun LocalCalendarRow(
) {
var menu by remember { mutableStateOf(false) }
Row(Modifier.fillMaxWidth().padding(vertical = 6.dp), verticalAlignment = Alignment.CenterVertically) {
ColorDot(cal.color, editable = cal.owned, onClick = onColor)
// Recipients of a shared calendar may recolour it (their own per-user
// colour); only renaming/other management stays owner-only.
ColorDot(cal.color, editable = true, onClick = onColor)
Column(Modifier.weight(1f).padding(start = 12.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(cal.name, style = MaterialTheme.typography.bodyLarge)