veilvoice-gui
egui/eframe front-end for VeilVoice: Tokyo Night, monospace, three modes.
reference · the same page on GitHub
The VeilVoice desktop application: an egui/eframe front-end, monospace throughout: anonymise a file, scramble a microphone live, watch what is listening, manage the app lock, choose how the app looks, and an about panel that states the honest scope.
The binary lives in main.rs; this library exists so the UI logic can be unit tested without opening a window.
That split is worth stating plainly, because it is the reason this crate has tests at all: a binary crate cannot be unit tested, so everything with logic in it -- the app lock's state machine, preference loading, palette resolution, the reduced-motion decision -- lives here where a test can reach it without a display server. main.rs holds only what genuinely needs a window.
The modules
| Module | What it owns | |---|---| | security | The unlock screen, the lock tab, and the at-rest controls | | prefs | Preferences, and recovering from a corrupt preferences file | | policy | Settings somebody has fixed, and the reason beside each one | | settings | The settings tab | | setup | Installing this copy, and the optional companions | | theme | The palette, shared with the command-line front end | | soundbar | The animated level meter | | reduced_motion | Whether to animate at all | | watchfeed | The device monitor, on a thread that is not this one |
Two rules this crate keeps
The user interface never softens a scope note. Where a control has a bound -- the app lock is a verifier and not disk encryption, tamper detection detects rather than prevents -- the interface says so next to the control, and tests fail the build if that text changes. Documentation nobody opens does not protect anybody.
Animation is a preference that is honoured, not a decoration. reduced_motion resolves the platform's own setting alongside the user's explicit choice, and the whole interface reads that answer rather than each widget deciding for itself.
In plain words
This is the window.
Tabs down the top for the things the program does: disguise a file, scramble a microphone as you talk, handle a recording with several people, watch for anything using your microphone, put the app behind a password, check a download, and change how it looks.
Nine colour schemes, and your own if you write one. It does the slow work on another thread, so the window keeps answering while it is busy.
HOW THE CRATE FITS TOGETHER
Every arrow is a crate:: or super:: path one module actually uses, read out of the source rather than drawn by hand.
The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
n_lib(["lib.rs<br/>136 lines"])
n_main(["main.rs<br/>231 lines"])
n_app["app.rs<br/>3584 lines"]
n_autolock["autolock.rs<br/>369 lines"]
n_avnotice["avnotice.rs<br/>298 lines"]
n_crashlog["crashlog.rs<br/>447 lines"]
n_crashreport["crashreport.rs<br/>289 lines"]
n_decoys["decoys.rs<br/>216 lines"]
n_dialog["dialog.rs<br/>425 lines"]
n_firstrun["firstrun.rs<br/>693 lines"]
n_graphics["graphics.rs<br/>214 lines"]
n_group["group.rs<br/>2110 lines"]
n_integrity["integrity.rs<br/>386 lines"]
n_layout["layout.rs<br/>473 lines"]
n_monitor["monitor.rs<br/>579 lines"]
n_notify["notify.rs<br/>460 lines"]
n_pace["pace.rs<br/>509 lines"]
n_palettes["palettes.rs<br/>700 lines"]
n_paths["paths.rs<br/>234 lines"]
n_policy["policy.rs<br/>320 lines"]
n_prefs["prefs.rs<br/>730 lines"]
n_reduced_motion["reduced_motion.rs<br/>348 lines"]
n_security["security.rs<br/>2403 lines"]
n_settings["settings.rs<br/>1434 lines"]
n_setup["setup.rs<br/>1038 lines"]
n_soundbar["soundbar.rs<br/>779 lines"]
n_storage["storage.rs<br/>659 lines"]
n_studio["studio.rs<br/>2406 lines"]
n_theme["theme.rs<br/>802 lines"]
n_tour["tour.rs<br/>299 lines"]
n_updates["updates.rs<br/>246 lines"]
n_vault_store["vault_store.rs<br/>589 lines"]
n_verify["verify.rs<br/>1651 lines"]
n_watchfeed["watchfeed.rs<br/>412 lines"]
n_window["window.rs<br/>244 lines"]
n_app --> n_avnotice
n_app --> n_crashlog
n_app --> n_crashreport
n_app --> n_dialog
n_app --> n_firstrun
n_app --> n_graphics
n_app --> n_group
n_app --> n_integrity
n_app --> n_layout
n_app --> n_monitor
n_app --> n_notify
n_app --> n_pace
n_app --> n_palettes
n_app --> n_paths
n_app --> n_policy
n_app --> n_prefs
n_app --> n_security
n_app --> n_settings
n_app --> n_setup
n_app --> n_soundbar
n_app --> n_storage
n_app --> n_studio
n_app --> n_theme
n_app --> n_tour
n_app --> n_updates
n_app --> n_vault_store
n_app --> n_verify
n_app --> n_watchfeed
n_app --> n_window
n_crashlog --> n_prefs
n_crashreport --> n_crashlog
n_crashreport --> n_theme
n_decoys --> n_studio
n_decoys --> n_theme
n_firstrun --> n_layout
n_firstrun --> n_security
n_firstrun --> n_settings
n_firstrun --> n_studio
n_firstrun --> n_theme
n_group --> n_dialog
n_group --> n_monitor
n_group --> n_settings
n_group --> n_theme
n_layout --> n_theme
n_monitor --> n_theme
n_notify --> n_palettes
n_notify --> n_theme
n_palettes --> n_prefs
n_palettes --> n_theme
n_paths --> n_crashlog
n_paths --> n_palettes
n_paths --> n_policy
n_paths --> n_prefs
n_paths --> n_studio
n_policy --> n_theme
n_prefs --> n_autolock
n_prefs --> n_monitor
n_prefs --> n_notify
n_prefs --> n_pace
n_prefs --> n_theme
n_security --> n_dialog
n_security --> n_layout
n_security --> n_prefs
n_security --> n_soundbar
n_security --> n_theme
n_settings --> n_autolock
n_settings --> n_layout
n_settings --> n_monitor
n_settings --> n_notify
n_settings --> n_pace
n_settings --> n_palettes
n_settings --> n_prefs
n_settings --> n_reduced_motion
n_settings --> n_soundbar
n_settings --> n_storage
n_settings --> n_theme
n_setup --> n_paths
n_setup --> n_prefs
n_setup --> n_theme
n_soundbar --> n_pace
n_soundbar --> n_prefs
n_soundbar --> n_theme
n_storage --> n_dialog
n_storage --> n_theme
n_studio --> n_decoys
n_studio --> n_dialog
n_studio --> n_monitor
n_studio --> n_theme
n_theme --> n_palettes
n_tour --> n_theme
n_updates --> n_theme
n_verify --> n_dialog
n_verify --> n_layout
n_verify --> n_theme
click n_lib href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/lib.rs" "open the source"
click n_main href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/main.rs" "open the source"
click n_app href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/app.rs" "open the source"
click n_autolock href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/autolock.rs" "open the source"
click n_avnotice href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/avnotice.rs" "open the source"
click n_crashlog href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/crashlog.rs" "open the source"
click n_crashreport href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/crashreport.rs" "open the source"
click n_decoys href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/decoys.rs" "open the source"
click n_dialog href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/dialog.rs" "open the source"
click n_firstrun href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/firstrun.rs" "open the source"
click n_graphics href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/graphics.rs" "open the source"
click n_group href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/group.rs" "open the source"
click n_integrity href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/integrity.rs" "open the source"
click n_layout href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/layout.rs" "open the source"
click n_monitor href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/monitor.rs" "open the source"
click n_notify href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/notify.rs" "open the source"
click n_pace href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/pace.rs" "open the source"
click n_palettes href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/palettes.rs" "open the source"
click n_paths href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/paths.rs" "open the source"
click n_policy href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/policy.rs" "open the source"
click n_prefs href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/prefs.rs" "open the source"
click n_reduced_motion href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/reduced_motion.rs" "open the source"
click n_security href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/security.rs" "open the source"
click n_settings href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/settings.rs" "open the source"
click n_setup href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/setup.rs" "open the source"
click n_soundbar href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/soundbar.rs" "open the source"
click n_storage href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/storage.rs" "open the source"
click n_studio href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/studio.rs" "open the source"
click n_theme href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/theme.rs" "open the source"
click n_tour href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/tour.rs" "open the source"
click n_updates href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/updates.rs" "open the source"
click n_vault_store href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/vault_store.rs" "open the source"
click n_verify href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/verify.rs" "open the source"
click n_watchfeed href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/watchfeed.rs" "open the source"
click n_window href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-gui/src/window.rs" "open the source"
This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.
THE FILES
| File | Lines | What it is |
|---|---|---|
app.rs | 3584 | The VeilVoice desktop application: seven tabs, one window, no menus. |
autolock.rs | 369 | Locking the window again after a period of no use. |
avnotice.rs | 298 | Noticing when antivirus software has closed VeilVoice, and saying so kindly. |
crashlog.rs | 447 | Make a failure that produces no output produce some. |
crashreport.rs | 289 | Offering the report from the last crash, on the run after it. |
decoys.rs | 216 | Decoy vaults: how many there is room for, and the panel that offers them. |
dialog.rs | 425 | Asking for a file without stopping the window. |
firstrun.rs | 693 | The first run: the four things worth deciding before anything else. |
graphics.rs | 214 | What the window is drawn with, asked for explicitly and then reported. |
group.rs | 2110 | Group mode: several people in one recording, each with a name and a colour. |
integrity.rs | 386 | The integrity record, taken and checked by the window rather than by hand. |
layout.rs | 473 | Centring a row of widgets, which egui does not do by nesting. |
lib.rs | 136 | The VeilVoice desktop application: an egui/eframe front-end, monospace throughout: anonymise a file, scramble a microphone live, watch what is listening, manage the app lock, choose how the app looks, and an about panel that states the honest scope. |
main.rs | 231 | Entry point for the desktop application: open a window, hand it to veilvoice_gui::VeilVoiceApp, and get out of the way. |
monitor.rs | 579 | The live monitor: what is going in, and what is coming out, wherever you are. |
notify.rs | 460 | How the application tells you something, and the three ways to be told. |
pace.rs | 509 | How often the window draws while something in it is moving, and what that actually came to. |
palettes.rs | 700 | User-defined colour schemes, and the contrast check that keeps them usable. |
paths.rs | 234 | Exactly where this copy of VeilVoice is keeping things. |
policy.rs | 320 | The policy in force, and what the interface does about it. |
prefs.rs | 730 | What the user has chosen about how the app looks and moves. |
reduced_motion.rs | 348 | Whether the operating system has been asked to reduce motion. |
security.rs | 2403 | The application lock, and the at-rest encryption of what VeilVoice writes. |
settings.rs | 1434 | The settings panel: a menu of pages, each a titled group of choices. |
setup.rs | 1038 | The setup tab: install this copy, undo that, and the optional companions. |
soundbar.rs | 779 | The animated mark: a row of bars that rise and fall. |
storage.rs | 659 | Where veiled recordings are written, and the encrypted volume that may hold them. |
studio.rs | 2406 | The Recording Studio and the Recording Browser. |
theme.rs | 802 | Colour schemes for the desktop app. |
tour.rs | 299 | The short tour on a first run, and after an upgrade. |
updates.rs | 246 | The manual update check, as the window shows it. |
vault_store.rs | 589 | Where the desktop application keeps its own files, and what the app lock buys for them. |
verify.rs | 1651 | The verify tab: drop a download on the window and be told what it is. |
watchfeed.rs | 412 | The device monitor, moved off the thread that paints. |
window.rs | 244 | How big the window opens, and why it is not a constant. |