| lang |
|---|
en |
Turn off your computer, Log your workOut
A simple, efficient and cross-platform workout logging application with 800+ exercises built-in, by Guilhem FaurΓ©.
- πͺ Easily log workout sessions with sets, reps, weights, distances, durations
- π Analytics panel with line charts to track progress over time
- ποΈ Browse the 870+ included exercises with search functionality
- Easily add your custom exercises or customize existing ones
- π± Mobile-first responsive design, bottom navigation bar, local-first
The project follows a modular Rust structure for a Dioxus application:
LogOut/
β src/
β β main.rs App entry point, routing (Dioxus Router), global state management
β β models/ Data models (Exercise, WorkoutSession, Enums) and unit-safe types
β β services/ Business logic and persistence layers
β β β storage.rs Unified storage interface (IndexedDB Web, SQLite native)
β β β exercise_db.rs Exercise library management and search logic
β β β exercise_loader.rs Logic for loading exercise data from JSON
β β β wake_lock.rs Keeps the screen on during active workout sessions
β β β service_worker.rs Integration logic for the PWA service worker
β β components/ Functional Dioxus UI components
β β β active_session.rs Complex "Active Session" view with timers and logging
β β β home.rs Main landing page with session history
β β β analytics.rs Progress tracking with interactive charts
β β β β¦ Other modular UI components (BottomNav, ExerciseCardβ¦)
β β utils.rs Pure, side-effect-free utility functions (format, timestampsβ¦)
β maestro/ Maestro end-to-end tests
β β web/ Web browser PWA tests (order-independent, each self-contained)
β β β _flows/ Reusable subflows (navigation, session setup, etc.)
β β android/ Android native app
β public/ PWA static assets required by the browser
β β manifest.json Web app manifest for PWA installation
β β sw.js JavaScript Service Worker for PWA
β β 404.html Fallback page for single-page app routing
β assets/ Application-wide static assets (SCSSβ¦)
β Cargo.toml Rust manifest (dependencies, features, targets)
β Dioxus.toml Configuration for Dioxus CLI (build, serve, platform options)
β flake.nix Nix flake for reproducible development environments
| Role | Library |
|---|---|
| Main UI framework for building reactive components with a Rust-native DSL | Dioxus |
| Serialization and deserialization framework for all data models and persistence | Serde |
| Local-first browser storage for workouts and custom exercises (via Rexie) | IndexedDB |
| Native-first storage for workout data on Android/Linux (via Rusqlite) | SQLite |
| Role | Library |
|---|---|
| Asynchronous HTTP client for loading exercise data and external assets | Reqwest |
| Type-safe date and time manipulation (UTC/Local offsets) | Time |
| Async runtime for the native application target. | Tokio |
| Low-level bindings to browser APIs (Service Worker, Notifications, Visibility) | Web-sys |
| Function | Tool |
|---|---|
| Rust compilation | rustc |
| Build system | Cargo |
| Dependencies and environment | Nix |
| Versionning and collaboration | Git hosted on GitHub |
| Unit tests | Cargo test |
| End-to-end tests (PWA) | Maestro (beta web) |
| End-to-end tests (Android) | Maestro |
| Code coverage | cargo-llvm-cov |
| Rust language assistance | rust-analyzer (LSP) |
| Documentation from code | rustdoc |
| Rust formatting | rustfmt |
| Rust quality control | Clippy |
| Rust debugging | lldb |
| Code edition | Helix, VS Code β¦ |
The project provides a Nix development shell with all required dependencies
(Rust, Dioxus CLI, Android SDKβ¦). With Nix installed, enter the shell with
nix develop. Preferably, with Direnv installed, allow the automatic
development shell loading with direnv allow.
To build for web as a PWA, run
dx build --web --releaseOutput is written to target/dx/log-out/release/web/public/.
To serve the PWA locally with hot-reload during development, run
dx serve # Serves at http://localhost:8080The PWA is deployed automatically on every push to main by
.github/workflows/cd.yml on https://gfauredev.github.io/LogOut.
To build for Android as APK, run
dx build --android --release --target aarch64-linux-androidDioxus 0.7 donβt yet supports signing (it does, but keys have to be in clear
in Dioxus.toml) the APK and adding icon(s) to it. So two scripts allow that.
Run scripts/android-icon.sh to add android/res icons to the app.
Run scripts/android-sign.sh to generate a signed release-signed.apk APK.
Ensure that all lints, end-to-end and unit tests pass before merging a pull
request, or .github/workflows/ci.yml will reject it.
| Job | Command | Requirement |
|---|---|---|
| Formatting | cargo fmt --check |
Code must match rustfmt style exactly |
| Linting | cargo clippy -- -D warnings |
Zero Clippy warnings |
| Unit tests | cargo llvm-cov β¦ |
All unit tests pass, covering more than 90% of the codebase |
| E2E (web) | maestro test --platform web β¦ |
All Maestro web tests pass |
| E2E (Android) | maestro test maestro/android/ |
All Maestro Android tests pass |
| PageSpeed | Lighthouse CLI | Performance scores posted as PR comment |
You can run them locally with the commands
cargo fmt --check # Formatting
cargo clippy -- -D warnings # Linting
cargo test # Unit tests
maestro test --platform web maestro/web/ # Web E2E tests (requires built PWA served on localhost:8080)
maestro test maestro/android/ # Android E2E tests (requires running emulator)Unit tests cover pure-Rust model functions (formatting, parsing, serialization), service stubs, and utility helpers. They compile and run on the native target β no browser or WASM toolchain required.
cargo testThe main branch must always pass 100% of unit tests, covering more than
90% of the codebase.
They can be run with cargo llvm-cov (might need to be installed).
cargo llvm-cov --bin log-out # Summary inlinecargo llvm-cov --bin log-out --lcov --output-path lcov.info # LCOV reportEnd-to-end tests exercise the full application using Maestro. All
user stories are covered with two test flows each: one for
the PWA and one for native Android. Tests are numbered 01β20 matching the
user story order, so each test can rely on state from the previous ones when run
as a full suite.
# Build and serve the PWA
dx serve --open false --interactive false --web --release
# In a second terminal, run all web E2E tests (order-independent)
maestro test maestro/web/
# Or run a single test file
maestro test maestro/web/full_workout_session.yaml
# Or run the tests headless
maestro test --headless maestro/web/Note
The first run of tests that touch the exercise browser may take up to 30 seconds while the exercise database is downloaded from the remote URL.
Replace web by android in the above commands to run the Android E2E tests.
An emulator must be running, or a physical device must be connected via ADB.
Tip
Each test is self-contained and independent β no specific run order is
required. Tests that need pre-existing state (e.g. a completed session) set it
up via reusable subflows in maestro/web/_flows/. Use maestro studio to
debug a failing test interactively.
The project uses rustdoc for code documentation. To generate and open the
documentation in your browser:
cargo doc --openThis generates HTML documentation for all internal modules, models, and services, providing a detailed view of the codebase's API.
- Simple, flat structures are always preffered, do not nest if not necessary
- Especially in HTML, a node with only one child can be replaced by it
- Keep the HTML structure as simple as possible
- Class-light styling mainly based on HTML semantic hierarchy
- Same CSS rules for similarly looking components, donβt overcomplicate
- Never hardcode values (except 0, 1, 100%), use clearly named constants
- Always ensure that all lints, end-to-end and unit tests pass.
- DRY E2E tests to only one par user story, they can still runFlow others
- Mock exercise database with public/exercises.json for E2E tests, so they can load faster and not rely on external network requests
- Harmonize Rest timer text color when background when rest is due
- Make layout harmonious but minimal, efficient, look at spacings, sizes
- Consider using Dioxus Components https://dioxuslabs.com/components