Integration: residence invite accept/decline APIs + wire notification actions
Adds acceptResidenceInvite / declineResidenceInvite to ResidenceApi
(POST /api/residences/{id}/invite/{accept|decline}) and exposes them via
APILayer. On accept success, myResidences is force-refreshed so the
newly-joined residence appears without a manual pull.
Wires NotificationActionReceiver's ACCEPT_INVITE / DECLINE_INVITE
handlers to the new APILayer calls, replacing the log-only TODOs left
behind by P4 Stream O. Notifications are now cleared only on API
success so a failed accept stays actionable.
Tests:
- ResidenceApiInviteTest covers correct HTTP method/path + error surfacing.
- NotificationActionReceiverTest invite cases updated to assert the new
APILayer calls (were previously asserting the log-only path).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -212,39 +212,39 @@ class NotificationActionReceiver : BroadcastReceiver() {
|
||||
|
||||
// ---------------- Accept / Decline invite ----------------
|
||||
|
||||
private fun handleAcceptInvite(context: Context, residenceId: Long?, notificationId: Int) {
|
||||
private suspend fun handleAcceptInvite(context: Context, residenceId: Long?, notificationId: Int) {
|
||||
if (residenceId == null) {
|
||||
Log.w(TAG, "ACCEPT_INVITE without residence_id — no-op")
|
||||
return
|
||||
}
|
||||
// APILayer.acceptResidenceInvite does not yet exist — see TODO below.
|
||||
// composeApp/src/commonMain/kotlin/com/tt/honeyDue/network/APILayer.kt
|
||||
// (add after createTaskCompletion at ~line 790). Backend endpoint
|
||||
// intended at POST /api/residences/{id}/invite/accept.
|
||||
Log.w(
|
||||
TAG,
|
||||
"TODO: APILayer.acceptResidenceInvite($residenceId) — implement in " +
|
||||
"composeApp/src/commonMain/kotlin/com/tt/honeyDue/network/APILayer.kt " +
|
||||
"(follow createTaskCompletion pattern; POST /api/residences/{id}/invite/accept)"
|
||||
)
|
||||
// Best-effort UX: cancel the notification so the user isn't stuck
|
||||
// on a button that does nothing visible. The invite will be picked
|
||||
// up on next app-open from /api/residences/pending.
|
||||
cancelNotification(context, notificationId)
|
||||
when (val result = APILayer.acceptResidenceInvite(residenceId.toInt())) {
|
||||
is ApiResult.Success -> {
|
||||
Log.d(TAG, "Residence invite $residenceId accepted")
|
||||
cancelNotification(context, notificationId)
|
||||
}
|
||||
is ApiResult.Error -> {
|
||||
// Leave the notification so the user can retry from the app.
|
||||
Log.e(TAG, "Accept invite failed: ${result.message}")
|
||||
}
|
||||
else -> Log.w(TAG, "Unexpected ApiResult from acceptResidenceInvite")
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDeclineInvite(context: Context, residenceId: Long?, notificationId: Int) {
|
||||
private suspend fun handleDeclineInvite(context: Context, residenceId: Long?, notificationId: Int) {
|
||||
if (residenceId == null) {
|
||||
Log.w(TAG, "DECLINE_INVITE without residence_id — no-op")
|
||||
return
|
||||
}
|
||||
Log.w(
|
||||
TAG,
|
||||
"TODO: APILayer.declineResidenceInvite($residenceId) — implement in " +
|
||||
"composeApp/src/commonMain/kotlin/com/tt/honeyDue/network/APILayer.kt " +
|
||||
"(follow createTaskCompletion pattern; POST /api/residences/{id}/invite/decline)"
|
||||
)
|
||||
cancelNotification(context, notificationId)
|
||||
when (val result = APILayer.declineResidenceInvite(residenceId.toInt())) {
|
||||
is ApiResult.Success -> {
|
||||
Log.d(TAG, "Residence invite $residenceId declined")
|
||||
cancelNotification(context, notificationId)
|
||||
}
|
||||
is ApiResult.Error -> {
|
||||
Log.e(TAG, "Decline invite failed: ${result.message}")
|
||||
}
|
||||
else -> Log.w(TAG, "Unexpected ApiResult from declineResidenceInvite")
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------- helpers ----------------
|
||||
|
||||
Reference in New Issue
Block a user