Files
haos-hacs-immich-album-watcher/plans/phase-11-snackbar-notifications.md
alexei.dolgolyov e6ff0a423a
All checks were successful
Validate / Hassfest (push) Successful in 3s
Phase 10: Telegram bot commands + Phase 11: Snackbar notifications
Phase 10 — Telegram Bot Commands:
- Add commands_config JSON field to TelegramBot model (enabled cmds,
  default count, response mode, rate limits, locale)
- Create command handler with 14 commands: /status, /albums, /events,
  /summary, /latest, /memory, /random, /search, /find, /person,
  /place, /favorites, /people, /help
- Add search_smart, search_metadata, search_by_person, get_random,
  download_asset, get_asset_thumbnail to ImmichClient
- Auto-register commands with Telegram setMyCommands API (EN+RU)
- Rate limiting per chat per command category
- Media mode: download thumbnails and send as photos to Telegram
- Webhook handler routes /commands before falling through to AI chat
- Frontend: expandable Commands section per bot with checkboxes,
  count/mode/locale settings, rate limit inputs, sync button

Phase 11 — Snackbar Notifications:
- Create snackbar store (snackbar.svelte.ts) with $state rune
- Create Snackbar component with fly/fade transitions, typed colors
- Mount globally in +layout.svelte
- Replace all alert() calls with typed snackbar notifications
- Add success snacks to all CRUD operations across all pages
- 4 types: success (3s), error (5s), info (3s), warning (4s)
- Max 3 visible, auto-dismiss, manual dismiss via X button

Both: Add ~30 i18n keys (EN+RU) for commands UI and snack messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 21:39:05 +03:00

3.8 KiB

Phase 11: Snackbar Notifications

Status: Done Parent: primary-plan.md


Goal

Replace browser alert() calls, silent failures, and inconsistent error handling with a unified snackbar/toast notification system. Every user-triggered action (save, delete, test, etc.) should provide clear visual feedback via a dismissable snackbar that appears at the bottom of the screen.


Design

Snackbar Types

Type Color Icon Auto-dismiss Use Case
success Green mdiCheckCircle 3s Save, delete, test passed
error Red mdiAlertCircle 5s (or manual) API errors, validation failures
info Blue mdiInformation 3s Status updates, copy-to-clipboard
warning Amber mdiAlert 4s Non-critical issues, deprecation notices

Behavior

  • Appears at bottom-center of viewport, above the mobile nav bar
  • Stacks vertically (newest on top, max 3 visible)
  • Slide-up entrance, fade-out exit animation
  • Manual dismiss via X button on all types
  • Errors with detail: expandable to show full error message
  • position: fixed with inline styles (per project convention)

Implementation Plan

Task 1: Create Snackbar Store + Component

Files to create:

  • frontend/src/lib/stores/snackbar.svelte.ts — reactive store using $state

    • addSnack(type, message, options?) — push notification
    • removeSnack(id) — dismiss
    • snacks — reactive array of active notifications
    • Auto-dismiss timer per snack
  • frontend/src/lib/components/Snackbar.svelte — renders snack stack

    • Fixed position at bottom-center
    • Svelte transitions (fly + fade)
    • Icon per type, dismiss button, optional detail expand
    • Responsive: full-width on mobile, max-width on desktop

Task 2: Mount Snackbar in Layout

Files to modify:

  • frontend/src/routes/+layout.svelte — add <Snackbar /> component (renders globally)

Task 3: Replace All Alert/Silent Patterns

Files to modify (each page):

Page Current Pattern Replace With
servers/+page.svelte alert() on error, silent success snack.success('Server saved'), snack.error(err.message)
trackers/+page.svelte alert() on error, silent success snack.success('Tracker created'), etc.
targets/+page.svelte alert() on error, silent success snack.success('Target saved'), snack.error(...)
template-configs/+page.svelte alert() on error, silent success snack.success('Template saved'), etc.
tracking-configs/+page.svelte alert() on error, silent success snack.success('Config saved'), etc.
telegram-bots/+page.svelte alert() on error, silent success snack.success('Bot registered'), etc.
users/+page.svelte alert() on error, silent success snack.success('User updated'), etc.
login/+page.svelte alert() on error snack.error('Invalid credentials')

Task 4: Add i18n Keys

Files to modify:

  • frontend/src/lib/i18n/en.json — add snack.* keys for all messages
  • frontend/src/lib/i18n/ru.json — Russian translations

Task 5: Add Snackbar to API Helper

Files to create/modify:

  • Consider a shared api.ts helper that wraps fetch() and auto-shows error snackbars on non-2xx responses, reducing boilerplate in each page.

Acceptance Criteria

  • Every create/update/delete action shows a success snackbar
  • Every API error shows an error snackbar with the server's message
  • No remaining alert() calls in the codebase
  • Snackbars auto-dismiss (success: 3s, error: 5s)
  • Snackbars are accessible (role="alert", aria-live)
  • Stacking works correctly (max 3, newest on top)
  • Animations are smooth (slide-up in, fade out)
  • Mobile: snackbar appears above bottom nav bar
  • All snackbar messages are i18n'd (EN + RU)