tane/apps/app_seeds/lib/services
vjrj 5fe0f4540e feat(messages): unread badges + OS notification for private messages
Private messages (NIP-17) arrived in the foreground with no signal: no
unread count, no badge, no OS notification. Hook both into the single
InboxService.ingest choke point.

- UnreadService: per-peer "last read" in the keystore (timestamps+pubkey
  only, no message text), live count via a changes stream, active-peer
  suppression so the open chat never badges or notifies.
- UnreadBadge: reusable, RTL-aware (Flutter Badge) — on the home hamburger,
  the drawer "Chat" item, and per-conversation in the messages list.
- Mark-read on chat open (ChatScreen).
- NotificationService over flutter_local_notifications: generic
  "New message from <name>" (no message text, for privacy), payload = pubkey,
  tap opens /chat/:pubkey. No-op on web/Windows; Android POST_NOTIFICATIONS.
- i18n notifications.newMessageFrom (en/es/pt/ast).

Background/push stays out of scope (foreground-only by design).

Tests: UnreadService, NotificationService (mock plugin), InboxService hooks
(new peer notifies/counts; duplicate, own, and open-chat do not), and a
UnreadBadge widget test. dart analyze clean; commons_core green.
2026-07-10 21:12:00 +02:00
..
ocr style: dart format reflow (no behavior change) 2026-07-09 22:19:43 +02:00
auto_backup_service.dart feat(backup): tap automatic-backups to make a copy now 2026-07-10 11:05:36 +02:00
auto_backup_store.dart feat(backup): add automatic weekly encrypted backups 2026-07-10 10:17:36 +02:00
coarse_location.dart fix(block2): sharing config UX + discovery + labels (raw feedback batch) 2026-07-10 13:32:11 +02:00
discovery_area.dart fix(market): search your zone by a coarse prefix, not the exact cell 2026-07-10 16:12:38 +02:00
export_import_service.dart feat(backup): add automatic weekly encrypted backups 2026-07-10 10:17:36 +02:00
file_picker_file_service.dart feat(inventory): CSV/JSON export and JSON import with LWW reconciliation 2026-07-09 12:46:53 +02:00
file_service.dart feat(inventory): CSV/JSON export and JSON import with LWW reconciliation 2026-07-09 12:46:53 +02:00
inbox_service.dart feat(messages): unread badges + OS notification for private messages 2026-07-10 21:12:00 +02:00
label_sheet_service.dart feat(labels): print seed labels with QR from an inventory selection 2026-07-10 19:14:04 +02:00
locale_store.dart feat(i18n): add Asturian (asturianu) as a language 2026-07-10 15:43:33 +02:00
message_store.dart feat(chat): app-wide inbox listener so messages arrive without opening the chat 2026-07-10 16:53:03 +02:00
notification_service.dart feat(messages): unread badges + OS notification for private messages 2026-07-10 21:12:00 +02:00
offer_mapper.dart feat(market): fix publish-duplicates, add offer detail page + filters 2026-07-10 19:10:40 +02:00
offer_outbox.dart feat(block2): offline outbox — share now, publish when connected 2026-07-10 10:45:53 +02:00
onboarding_store.dart feat(inventory): photo-first drafts + on-device OCR (digitization R2+R4) 2026-07-09 21:23:46 +02:00
profile_cache.dart feat(block2): show contact names (resolve peers' published profiles) 2026-07-10 12:47:48 +02:00
profile_store.dart feat(block2): Ğ1 — publish a Ğ1 address + 'Pay in Ğ1' in chat (levels 1-2) 2026-07-10 13:06:38 +02:00
recovery_sheet_service.dart feat(backup): sealed backups + printable recovery sheet 2026-07-09 22:32:13 +02:00
share_catalog_service.dart feat(inventory): local sharing — per-lot share terms, filter and printable catalog 2026-07-09 22:19:55 +02:00
social_service.dart feat(block2): profiles — your identity card + name/about (NIP-01 kind:0) 2026-07-10 12:37:07 +02:00
social_settings.dart fix(market): search your zone by a coarse prefix, not the exact cell 2026-07-10 16:12:38 +02:00
unread_service.dart feat(messages): unread badges + OS notification for private messages 2026-07-10 21:12:00 +02:00