diff --git a/README.md b/README.md index 441faf7..d95bb2b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,123 @@ -# Tauri + Vanilla +# WVU Medicine Help Alert Web Client -This template should help get you started developing with Tauri in vanilla HTML, CSS and Javascript. +A lightweight Tauri-based desktop wrapper for the WVU Medicine PinPoint HelpAlert duress alarm system. Built to replace the vendor's crashing desktop client with a stable, tray-resident application that brings alerts to the foreground automatically. -## Recommended IDE Setup +## Why This Exists -- [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) +The vendor's native desktop client crashes hospital workstations. The web version works but has two problems: users get logged out due to inactivity, and browser notifications don't reliably surface when the tab is backgrounded. This app solves both by wrapping the web client in a persistent Tauri window with native alert detection. + +## How It Works + +1. The app loads PinPoint's web login page in a native webview +2. After login, the user clicks "Alerts" to navigate to the HelpAlert GWT page +3. Injected JavaScript monitors the DOM every 2 seconds for new alerts (identified by "Claim" buttons and "Elapsed Time" markers) +4. When a new alert is detected, the app calls into the Rust backend which unminimizes, focuses, and temporarily pins the window on top +5. Closing the window minimizes to the system tray instead of exiting — the app stays running and monitoring + +## Architecture + +- **Frontend:** Vendor's HelpAlert web app loaded directly in the Tauri webview, no custom UI +- **Injection:** `src/inject.js` handles `window.open()` interception (alerts page opens in same window instead of a new tab) and DOM-based alert detection +- **Backend:** Rust/Tauri handles system tray, window management, and the `alert_detected` command that brings the window to the foreground +- **IPC:** JavaScript detects alerts → invokes Tauri command → Rust brings window to front + +## Prerequisites + +- Rust toolchain (`rustup`) +- Tauri CLI: `cargo install tauri-cli --version "^2"` +- For Windows cross-compilation from Linux: `x86_64-pc-windows-gnu` target +- WiX Toolset (for MSI installer generation) + +## WRY Fork Requirement + +This project requires a forked version of [wry](https://github.com/tauri-apps/wry) (Tauri's WebView library). The vendor's HelpAlert page uses GWT (Google Web Toolkit), which declares a global `ipc` variable. WRY also declares `window.ipc` for its IPC bridge, causing a collision that crashes the GWT page. + +The fork renames WRY's `ipc` to `__wry_ipc` in `src/webview2/mod.rs` (line 897), resolving the collision. + +The fork is referenced in `src-tauri/Cargo.toml`: + +```toml +[patch.crates-io] +wry = { path = "../../wry" } +``` + +Adjust the path to match your local wry fork location. + +## Building + +### Development + +```bash +cargo tauri dev +``` + +### Release (Windows cross-compile from Linux) + +```bash +cargo tauri build -- --target x86_64-pc-windows-gnu +``` + +The MSI installer will be in `src-tauri/target/x86_64-pc-windows-gnu/release/bundle/msi/`. + +The installer bundles the WebView2 runtime offline, so target machines don't need internet access. + +### Standalone EXE + +The raw `.exe` is also available at `src-tauri/target/x86_64-pc-windows-gnu/release/` but requires WebView2 to already be installed on the target machine. + +## Project Structure + +``` +duress/ +├── src/ +│ ├── index.html # Fallback loading page (shown briefly during startup) +│ └── inject.js # Injected JS: window.open intercept + alert detection +├── src-tauri/ +│ ├── Cargo.toml # Rust dependencies (includes wry fork patch) +│ ├── tauri.conf.json # App config: name, version, bundling, security +│ ├── capabilities/ +│ │ └── default.json # Tauri v2 permissions and remote domain IPC access +│ ├── permissions/ +│ │ └── alert-detected.toml # Custom command permission +│ ├── src/ +│ │ ├── main.rs # Windows entrypoint +│ │ └── lib.rs # App logic: tray, window management, alert_detected command +│ └── icons/ # App icons (generated via cargo tauri icon) +└── README.md +``` + +## Configuration + +### Adding the vendor URL + +The vendor URL is set in `lib.rs`: + +```rust +let url = WebviewUrl::External("https://helpalert.wvumedicine.org".parse().unwrap()); +``` + +### Alert detection tuning + +Alert detection in `inject.js` looks for lines preceding "Geo:" in the page text. If the vendor changes their alert format, update the detection logic in the `setInterval` callback. + +### Polling interval + +The DOM is checked every 2000ms (2 seconds). Adjust the `setInterval` delay in `inject.js` if needed. + +## Deployment Notes + +- Target machines need Windows 10 or 11 +- The MSI installer includes WebView2 runtime (offline) — no internet required +- The app installs per-machine by default +- Users should be instructed that closing the window minimizes to tray, and "Quit" in the tray menu is the actual exit + +## Known Limitations + +- Alert detection relies on DOM text parsing ("Geo:" pattern preceding alert names). If the vendor updates their GWT UI significantly, detection may need adjustment. +- GWT class names are obfuscated and change between builds, so selectors are text-based rather than class-based. +- Session keepalive has not been implemented yet — if the session times out, the user must re-authenticate manually. Testing suggests the session may persist indefinitely while the app is running. +- The wry fork must be kept in sync with upstream when updating Tauri. + +## License + +Internal use — WVU Medicine / Racoon City Technologies. \ No newline at end of file diff --git a/logo.png b/logo.png deleted file mode 100644 index 78829fc..0000000 Binary files a/logo.png and /dev/null differ diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 892b188..955a8d1 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "WVUMedicine_HelpAlert_WebClient" -version = "0.1.0" +version = "1.0.0" dependencies = [ "serde", "serde_json", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 4713e08..6bd5a43 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "WVUMedicine_HelpAlert_WebClient" -version = "0.1.0" -description = "A Tauri App" -authors = ["you"] +version = "1.0.0" +description = "Help Alert Web Client" +authors = ["James Brotosky