fix: green brand theme, iOS launcher icon, password reveal, real login error

- Theme primary now the iOS brand green (#20A050), fixed app-wide (was tied
  to the server's blue primary_color)
- Launcher icon generated from the iOS AppIcon across all densities;
  dropped the placeholder adaptive icon
- PasswordField: eye toggle + brief last-character reveal; used on login,
  profile and CalDAV password inputs
- Login now surfaces the server's actual error detail (verified the JSON
  contract against the live server; a 401 is a genuine credential mismatch)
- CLAUDE.md: correct prod base URL to calendar.scarriffle.com

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Guido Schmit
2026-05-31 12:48:53 +02:00
parent aff6cef493
commit a1c36a8a03
22 changed files with 113 additions and 64 deletions

View File

@@ -79,7 +79,7 @@ class CalendarRepository @Inject constructor(
JSONObject(resp.errorBody()?.string() ?: "").optString("detail")
}.getOrNull()
if (detail == "2fa_required") throw TwoFactorRequiredException()
throw UnauthorizedException()
throw UnauthorizedException(detail?.takeIf { it.isNotBlank() } ?: "Benutzername oder Passwort falsch")
}
if (!resp.isSuccessful) throw ApiException(errorDetail(resp.errorBody(), resp.code()))

View File

@@ -7,8 +7,8 @@ import retrofit2.Response
/** Generic server error carrying the `detail` message when available. */
open class ApiException(message: String) : Exception(message)
/** Credentials rejected (HTTP 401, not a 2FA prompt). */
class UnauthorizedException : ApiException("Benutzername oder Passwort falsch")
/** Credentials rejected (HTTP 401, not a 2FA prompt). Carries the server detail. */
class UnauthorizedException(message: String = "Benutzername oder Passwort falsch") : ApiException(message)
/** Server requires a TOTP code to finish login (HTTP 401, detail "2fa_required"). */
class TwoFactorRequiredException : ApiException("2FA-Code erforderlich")