TASK-042 follow-up: colored status badges on NotificationsScreen
Closes the known limitation from the previous commit: NotificationsScreen had the identical plain-text state-label gap, in a separate screen/enum (NotificationSubjectState, which also has an UNKNOWN case). Adds its own StatusBadge composable with the same color roles, mapping UNKNOWN to the neutral surfaceVariant treatment VisibilityBadge already uses for private. Live-verified on-device: notifications 전체 list shows all three real colors side by side (닫힘/병합됨/열림). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
471456258b
commit
ca999a7bb8
@ -11,11 +11,13 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Tab
|
import androidx.compose.material3.Tab
|
||||||
import androidx.compose.material3.TabRow
|
import androidx.compose.material3.TabRow
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@ -101,7 +103,7 @@ private fun NotificationRow(notification: NotificationSummary, onSelected: () ->
|
|||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
)
|
)
|
||||||
Text(stringResource(notification.subjectType.labelResource), style = MaterialTheme.typography.bodySmall)
|
Text(stringResource(notification.subjectType.labelResource), style = MaterialTheme.typography.bodySmall)
|
||||||
Text(stringResource(notification.subjectState.labelResource), style = MaterialTheme.typography.bodySmall)
|
StatusBadge(notification.subjectState)
|
||||||
}
|
}
|
||||||
Text(notification.title, style = MaterialTheme.typography.titleMedium, maxLines = 2)
|
Text(notification.title, style = MaterialTheme.typography.titleMedium, maxLines = 2)
|
||||||
}
|
}
|
||||||
@ -160,6 +162,30 @@ private val NotificationSubjectState.labelResource: Int
|
|||||||
NotificationSubjectState.UNKNOWN -> R.string.notifications_state_unknown
|
NotificationSubjectState.UNKNOWN -> R.string.notifications_state_unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same compact colored-Surface badge WorkItemsScreen's issue/PR rows use (see that file's own
|
||||||
|
// StatusBadge doc comment for the full rationale) -- kept as its own copy rather than a shared
|
||||||
|
// component since these are two different feature packages and the two state enums
|
||||||
|
// (NotificationSubjectState vs. IssueState/PullRequestState) don't share a type to unify over.
|
||||||
|
// UNKNOWN -- a real Gitea subject state this client doesn't recognize, not a state to visually
|
||||||
|
// emphasize -- gets the same neutral surfaceVariant treatment VisibilityBadge uses for "private"
|
||||||
|
// rather than either affirmative-state color.
|
||||||
|
@Composable
|
||||||
|
private fun StatusBadge(state: NotificationSubjectState) {
|
||||||
|
val (container, content) = when (state) {
|
||||||
|
NotificationSubjectState.OPEN -> MaterialTheme.colorScheme.primaryContainer to MaterialTheme.colorScheme.onPrimaryContainer
|
||||||
|
NotificationSubjectState.CLOSED -> MaterialTheme.colorScheme.errorContainer to MaterialTheme.colorScheme.onErrorContainer
|
||||||
|
NotificationSubjectState.MERGED -> MaterialTheme.colorScheme.tertiaryContainer to MaterialTheme.colorScheme.onTertiaryContainer
|
||||||
|
NotificationSubjectState.UNKNOWN -> MaterialTheme.colorScheme.surfaceVariant to MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
}
|
||||||
|
Surface(color = container, contentColor = content, shape = RoundedCornerShape(4.dp)) {
|
||||||
|
Text(
|
||||||
|
stringResource(state.labelResource),
|
||||||
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val NotificationsError.messageResource: Int
|
private val NotificationsError.messageResource: Int
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
NotificationsError.OFFLINE -> R.string.notifications_offline
|
NotificationsError.OFFLINE -> R.string.notifications_offline
|
||||||
|
|||||||
@ -887,3 +887,30 @@ This is the append-only implementation and handoff record shared by Codex and Cl
|
|||||||
yet reviewed this session), and consider extending today's status-badge fix to
|
yet reviewed this session), and consider extending today's status-badge fix to
|
||||||
`NotificationsScreen.kt` for consistency.
|
`NotificationsScreen.kt` for consistency.
|
||||||
- Next owner: Claude, continuing per the standing direction.
|
- Next owner: Claude, continuing per the standing direction.
|
||||||
|
|
||||||
|
## 2026-08-29 (continued) — TASK-042 follow-up: NotificationsScreen status badges
|
||||||
|
|
||||||
|
- Agent and role: Claude, direct continuation of the same live session, closing the known limitation
|
||||||
|
recorded in TASK-042's own task file immediately after landing it.
|
||||||
|
- Commit/diff: on `claude/task-015-notifications`; `feature/notifications/NotificationsScreen.kt`
|
||||||
|
gained its own `StatusBadge` composable for `NotificationSubjectState`;
|
||||||
|
`tasks/042-workitem-status-badges.md` updated to record the closure.
|
||||||
|
- How it was implemented: `NotificationSubjectState` is a different enum from `IssueState`/
|
||||||
|
`PullRequestState` (it also has an `UNKNOWN` case, for a subject state this client doesn't
|
||||||
|
recognize) and this is a different feature package from `WorkItemsScreen.kt`, so this is a second,
|
||||||
|
independent copy of the same badge treatment rather than a shared component — UNKNOWN maps to the
|
||||||
|
neutral `surfaceVariant` `VisibilityBadge` already uses for "private", since an unrecognized state
|
||||||
|
isn't one to visually emphasize either direction.
|
||||||
|
- Files changed: `feature/notifications/NotificationsScreen.kt`,
|
||||||
|
`tasks/042-workitem-status-badges.md`.
|
||||||
|
- Checks and results: `./gradlew compileDebugKotlin compileDebugUnitTestKotlin testDebugUnitTest assembleDebug lintDebug`
|
||||||
|
BUILD SUCCESSFUL, all existing tests passing unmodified, 0 lint errors.
|
||||||
|
- Live verification: installed over wireless `adb`. Notifications → 전체 tab: confirmed all three real
|
||||||
|
colors render side by side across the actual notification list — red "닫힘", teal "병합됨", green
|
||||||
|
"열림" (screenshot) — which also closes the earlier task's "never visually confirmed CLOSED red
|
||||||
|
live" gap, since it's the same `errorContainer` role used by both screens' badges.
|
||||||
|
- Review findings and resolutions: None from a separate review pass.
|
||||||
|
- Known limitations: None outstanding for TASK-042 or this follow-up.
|
||||||
|
- Next recommended task: continue the design-review pass — the text/image/CSV/PDF file viewers have
|
||||||
|
not yet been reviewed this session.
|
||||||
|
- Next owner: Claude, continuing per the standing direction.
|
||||||
|
|||||||
@ -83,14 +83,21 @@ with a compact colored badge, reusing the `VisibilityBadge` pattern TASK-039 alr
|
|||||||
|
|
||||||
## Known limitations
|
## Known limitations
|
||||||
|
|
||||||
- `NotificationsScreen.kt` still renders its own PR/이슈 상태 column as plain text — a second,
|
None outstanding for this task — see the follow-up below, which closed the one gap originally
|
||||||
separate location with the same visual gap this task fixed on the work-items screens. Not touched
|
recorded here.
|
||||||
here to keep this change scoped to what was actually being reviewed; worth a follow-up pass.
|
|
||||||
- Did not find a real CLOSED (닫힘) issue/PR with this fix installed to visually confirm the red badge
|
## Follow-up (same session): NotificationsScreen
|
||||||
live — the CLOSED branch was exercised only via the existing 닫힘 rows seen in `NotificationsScreen`
|
|
||||||
(a different, unfixed screen) prior to this change. The color mapping itself
|
`NotificationsScreen.kt`'s own PR/이슈 상태 column had the identical gap (plain-text state label) in a
|
||||||
(`errorContainer`/`onErrorContainer`) is the same theme role used unconditionally elsewhere in the
|
separate screen this task didn't originally touch. Added a second, independent `StatusBadge`
|
||||||
app, so this is a low-risk gap, not left silently assumed away.
|
composable there (for `NotificationSubjectState`, a different enum with its own `UNKNOWN` case —
|
||||||
|
mapped to the neutral `surfaceVariant`/`onSurfaceVariant` `VisibilityBadge` already uses for
|
||||||
|
"private", since an unrecognized state isn't one to visually emphasize either direction) rather than
|
||||||
|
sharing code across the two feature packages. Build/test/lint re-run clean; live-verified on-device:
|
||||||
|
the notifications 전체 list now shows all three real colors side by side — red "닫힘", teal "병합됨",
|
||||||
|
green "열림" — which also closes the "never visually confirmed the red CLOSED badge live" gap
|
||||||
|
originally recorded here, since these are the same `errorContainer`/`onErrorContainer` roles used by
|
||||||
|
the work-items screens' badge.
|
||||||
|
|
||||||
## Review findings
|
## Review findings
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user