Files
pluriwave/openspec/changes/notification-visual-polish/tasks.md
T
FreeTLab bccc5c48b8
Build & Deploy PluriWave / Análisis de código (push) Successful in 38s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m30s
docs(openspec): add SDD artifact trail for recent alarm and EQ changes
Persist the exploration, proposal, spec, design, tasks, and
verify/archive reports produced during the multi-device EQ,
alarm-countdown, and notification-visual-polish SDD cycles.
2026-07-04 12:42:11 +02:00

5.7 KiB

Tasks: Notification Visual Polish

Review Workload Forecast

Field Value
Estimated changed lines ~90-120 (1 new XML ~6 lines, 1 new Kotlin object ~6 lines, 3x 2-line Kotlin edits, 2-line Dart edit, ~8-line Dart test)
400-line budget risk Low
Chained PRs recommended No
Suggested split Single PR
Delivery strategy ask-on-risk
Chain strategy pending

Decision needed before apply: No Chained PRs recommended: No Chain strategy: pending 400-line budget risk: Low

Suggested Work Units

Unit Goal Likely PR Notes
1 Full change (drawable + brand const + 3 Kotlin wire-ups + Dart wire-up + Dart test + QA) PR 1 Single PR, well under 400-line budget; presentation-only, low blast radius

Phase 1: Foundation (drawable + brand constant)

  • 1.1 Create android/app/src/main/res/drawable/ic_stat_pluriwave.xml — 24x24dp <vector>, Material graphic_eq pathData, #FFFFFF fill (exact content per design doc). Satisfies: proposal "New monochrome vector drawable"; design File Changes.
  • 1.2 Create android/app/src/main/kotlin/es/freetimelab/pluriwave/NotificationBrand.ktobject NotificationBrand { @ColorInt const val CYAN: Int = 0xFF21D4D9.toInt() }, package es.freetimelab.pluriwave, import androidx.annotation.ColorInt. Satisfies: design "Kotlin color constant" decision; proposal ".setColor() cyan #21D4D9".

Phase 2: Dart Wiring (TDD — RED-GREEN-REFACTOR)

  • 2.1 RED: Add test to test/tema/notification_color_test.dart asserting configuracionAudioService.androidNotificationIcon == 'drawable/ic_stat_pluriwave', mirroring existing notificationColor test style. Run flutter test test/tema/notification_color_test.dart — confirm it fails (field doesn't exist yet). Satisfies: spec Scenario "Audio notification config declares the branded monochrome icon".
  • 2.2 GREEN: In lib/main.dart, add const androidNotificationIconResource = 'drawable/ic_stat_pluriwave'; near configuracionAudioService (L13-17 region), then add androidNotificationIcon: androidNotificationIconResource, field to the AudioServiceConfig(...) constant (L17-23). Run flutter test test/tema/notification_color_test.dart — confirm it passes. Satisfies: spec Requirement "Audio Notification Icon Resource".
  • 2.3 REFACTOR: Run flutter analyze — confirm clean, no unused-const or formatting warnings on the touched lines.
  • 2.4 Add second assertion to the same test verifying androidNotificationIcon differs from 'mipmap/ic_launcher'. Run full test file again — confirm both assertions pass. Satisfies: spec Scenario "Audio notification icon is distinct from the default launcher fallback".

Phase 3: Kotlin Wiring (code-inspection only — no test harness)

No JVM/Robolectric/instrumented test infra exists in this repo for NotificationCompat.Builder chains. These tasks are verified by code inspection + Kotlin compile, NOT by automated tests. Functional correctness is confirmed exclusively in Phase 4 (manual/on-device QA).

  • 3.1 In PluriWaveAlarmReceiver.kt:184, replace .setSmallIcon(android.R.drawable.ic_dialog_info) with .setSmallIcon(R.drawable.ic_stat_pluriwave); add .setColor(NotificationBrand.CYAN) immediately after. Satisfies: design "MODIFY PluriWaveAlarmReceiver.kt L184".
  • 3.2 In AlarmScheduler.kt:580, replace .setSmallIcon(android.R.drawable.ic_lock_idle_alarm) with .setSmallIcon(R.drawable.ic_stat_pluriwave); add .setColor(NotificationBrand.CYAN) immediately after. Satisfies: design "MODIFY AlarmScheduler.kt L580".
  • 3.3 In PluriWaveAlarmService.kt:390, replace .setSmallIcon(android.R.drawable.ic_lock_idle_alarm) with .setSmallIcon(R.drawable.ic_stat_pluriwave); add .setColor(NotificationBrand.CYAN) immediately after. Satisfies: design "MODIFY PluriWaveAlarmService.kt L390".
  • 3.4 Code-inspect all 3 edits: confirm no new imports needed (same-package unqualified R access, NotificationBrand same-package), confirm each builder chain still compiles logically (no dangling . chain breaks). Run ./gradlew :app:compileDebugKotlin (or project's Kotlin compile task) — confirm success.

Phase 4: Manual / On-Device QA (mandatory — no automated coverage for Kotlin builders)

  • 4.1 Build and install debug APK on a physical device or emulator (Android 8.0+ recommended, matches setColor advisory behavior range).
  • 4.2 Trigger pre-notice alarm notification (PluriWaveAlarmReceiver, channel pluriwave_alarm_pre_notice) — confirm status bar icon renders as legible equalizer glyph, NOT a solid blob/silhouette.
  • 4.3 Trigger snooze countdown notification (AlarmScheduler, same channel) — confirm same icon + cyan tint where OS honors setColor.
  • 4.4 Trigger alarm-fire/ringing notification (PluriWaveAlarmService, channel pluriwave_alarm_fire_v2) — confirm same icon + cyan tint.
  • 4.5 Start radio playback to trigger the audio/media notification — confirm drawable/ic_stat_pluriwave renders (not mipmap/ic_launcher silhouette) and cyan brand color is applied.
  • 4.6 Cross-check all 4 notifications side-by-side in the notification shade — confirm consistent icon glyph and consistent cyan #21D4D9 across all of them.
  • 4.7 Record QA result (pass/fail + device/OS version) in the PR description before merge.

Phase 5: Verification

  • 5.1 Run full Dart test suite (flutter test) — confirm no regressions outside the 2 new assertions.
  • 5.2 Run flutter analyze on the full project — confirm clean.
  • 5.3 Confirm all 4 success criteria from the proposal are checked off: valid vector XML, all 4 builders reference the drawable, 3 Kotlin builders apply cyan, Dart test passes.