Login now persists properly rather than through the JSON file the test
harness was using.
dr-plat SecretStore trait plus a Secret Service backend.
Verified against the live GNOME Keyring: store,
retrieve, delete, confirm-gone all round-trip.
Session/SessionStore splits credentials from settings — the app
password goes to the keyring (FR-NC-2), while
server, login, chosen root and format selection are
ordinary config. A test asserts the credential never
appears in the config file.
LaunchModel the launch-screen state machine, testable without a
display server: sign in, approve in browser, choose
folder, tick formats, sign out.
launch.slint the screen itself, in its own file.
Absence of a secrets daemon is an explicit degraded mode, not a silent
fallback to plaintext — the screen says sign-in will not persist rather
than letting the user find out next launch. Android's Keystore backend
fails loudly for the same reason: a no-op store would look like it
worked and then lose the credential.
Two bugs caught by tests rather than by running it:
- fail() after busy() signed the user out, because busy() had already
discarded the session. A failed *scan* would have logged you out.
Busy now carries the session.
- normalise_server upgrades http:// to https:// rather than accepting
it. NFR-SEC-3 requires TLS, and silently sending a credential in the
clear is not a decision to make on the user's behalf.
launch.slint is not yet wired into app.slint. Calling slint_build::compile
twice replaces the generated module rather than adding to it, which broke
the other in-flight work on dr-ui; I reverted that immediately. Wiring it
needs an import inside app.slint, which is that work's file to change.
419 tests passing across ten crates.
33 lines
1.1 KiB
Plaintext
33 lines
1.1 KiB
Plaintext
// Darkroom safelight palette. Warm neutrals, single red accent.
|
|
// Committed to a dark ground — this is a photo editor, and a light UI
|
|
// surrounding an image biases how that image is judged.
|
|
|
|
export global Theme {
|
|
out property <color> ground: #14120F;
|
|
out property <color> surface: #1D1A16;
|
|
out property <color> surface-raised: #262119;
|
|
out property <color> rule: #332C24;
|
|
|
|
out property <color> ink: #F0EAE0;
|
|
out property <color> ink-dim: #A79E91;
|
|
out property <color> ink-faint: #7C7367;
|
|
|
|
out property <color> accent: #D9543C;
|
|
out property <color> accent-dim: #8F2E1E;
|
|
|
|
// Semantic, distinct from the accent: a caution is not an action.
|
|
out property <color> warn-ink: #C99A4A;
|
|
|
|
out property <length> gap-sm: 6px;
|
|
out property <length> gap: 12px;
|
|
out property <length> gap-lg: 20px;
|
|
|
|
out property <length> text-sm: 11px;
|
|
out property <length> text: 13px;
|
|
out property <length> text-lg: 17px;
|
|
out property <length> text-xl: 24px;
|
|
|
|
// FR-UI-3: minimum 44pt hit target under touch.
|
|
out property <length> touch-target: 44px;
|
|
}
|