README.md: - Node prerequisite: v12+ → v22+ - Real-Time Updates: describe SSE push, remove polling/refresh-selector wording - On-demand mode: update for SSE connect triggering poll - API Endpoints: add /stream, /me, /csrf, /user-summary, /status, /cover-art - Remove stale /api/qbittorrent proxy entry - Docker tags: update to 1.0.x SECURITY.md: - Supported versions: add 1.0.x, retire 0.2.x - CSP header: add style-src-attr 'unsafe-inline' - Nginx example: add proxy_buffering off / proxy_read_timeout for SSE Diagrams: - seq-dashboard.puml: rewrite as SSE stream sequence (connect, initial payload, pushed updates, heartbeat, disconnect) - seq-polling.puml: add SSE subscriber notification step after cache population - state-ui.puml: replace Refresh Rate sub-state with SSE Connection state machine; update splash loading and logout transitions - state-poller.puml: add Notifying SSE subscribers step in Polling state package.json: bump to 1.0.0
74 lines
1.7 KiB
Plaintext
74 lines
1.7 KiB
Plaintext
@startuml state-ui
|
||
!theme plain
|
||
title sofarr — Frontend UI State Diagram
|
||
|
||
[*] --> SplashScreen : Page load
|
||
|
||
state SplashScreen {
|
||
state "Showing splash\n(min 1.2s)" as showing
|
||
}
|
||
|
||
SplashScreen --> CheckAuth : checkAuthentication()
|
||
|
||
state CheckAuth <<choice>>
|
||
CheckAuth --> LoginForm : No session cookie
|
||
CheckAuth --> Dashboard : Valid session
|
||
|
||
state LoginForm {
|
||
state "Idle" as lf_idle
|
||
state "Submitting" as lf_submit
|
||
state "Error" as lf_error
|
||
|
||
lf_idle --> lf_submit : Submit form
|
||
lf_submit --> lf_error : Auth failed
|
||
lf_error --> lf_submit : Re-submit
|
||
lf_submit --> FadeOutLogin : Auth success
|
||
}
|
||
|
||
state FadeOutLogin {
|
||
state "CSS transition\n(opacity → 0)" as fade
|
||
}
|
||
|
||
FadeOutLogin --> SplashScreen2 : Show splash\nwhile loading
|
||
|
||
state SplashScreen2 as "Splash (loading data)" {
|
||
state "startSSE() — awaiting\nfirst SSE message" as fetching
|
||
}
|
||
|
||
SplashScreen2 --> Dashboard : Data loaded\ndismissSplash()
|
||
|
||
state Dashboard {
|
||
state "Rendering Cards" as rendering
|
||
state "Status Panel Open" as status_open
|
||
state "Status Panel Closed" as status_closed
|
||
|
||
[*] --> rendering
|
||
rendering --> rendering : SSE message received
|
||
→ renderDownloads()
|
||
rendering --> rendering : Theme change
|
||
|
||
status_closed --> status_open : Click "Status" btn
|
||
(admin only)
|
||
status_open --> status_closed : Click close (×)
|
||
status_open --> status_open : 5s timer
|
||
→ renderStatusPanel()
|
||
|
||
[*] --> status_closed
|
||
|
||
state "SSE Connection" as sse {
|
||
state "Connecting" as sc
|
||
state "Connected" as scon
|
||
state "Reconnecting" as srec
|
||
sc --> scon : First message received
|
||
scon --> srec : Connection lost
|
||
srec --> scon : Browser auto-reconnects
|
||
scon --> sc : showAll toggle changed
|
||
}
|
||
}
|
||
|
||
Dashboard --> LoginForm : Logout
|
||
(stopSSE,
|
||
clear state)
|
||
|
||
@enduml
|