Skip to content

Commit 262970d

Browse files
author
CatCast
committed
Merge branch 'main' of https://github.com/baloise/catcast
2 parents aeaa011 + ae49b31 commit 262970d

12 files changed

Lines changed: 445 additions & 147 deletions

File tree

AGENTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ for the full dev guide; this file is the short version for AI tooling.
1414
CI runs these on Ubuntu, Windows, and macOS — match all four locally
1515
before opening a PR.
1616

17+
## When you finish a task
18+
19+
Run `cargo fmt --all` before handing off (or committing). The
20+
`fmt --check` step above is the CI gate; running `--all` once at the end
21+
keeps subsequent diffs noise-free.
22+
1723
## Commit style
1824

1925
Conventional Commits (`feat:`, `fix:`, `refactor:`, `docs:`, `chore:`,

CONTRIBUTING.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,13 @@ cargo run -p catsocks
9090
**Terminal 2 — a stage:**
9191

9292
```bash
93-
cargo run -p catstage -- --socks ws://127.0.0.1:8787/r/dev --name kitchen
93+
cargo run -p catstage -- --socks ws://127.0.0.1:8787/r/dev --name kitchen --screen 2
9494
```
9595

96+
`--screen` is optional and 1-based (`--screen 2` means second monitor).
97+
If the selected monitor is unavailable, catstage falls back to the primary
98+
monitor.
99+
96100
Tauri opens a fullscreen window pointed at `catcast://about` — a
97101
**read-only** info page showing the stage's name, version, connection
98102
state, on-disk files, and autostart status. There are no buttons. Every

Cargo.lock

Lines changed: 13 additions & 61 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ members = [
99
]
1010

1111
[workspace.package]
12-
version = "0.0.2"
12+
version = "0.0.3"
1313
edition = "2021"
1414
license = "0BSD"
1515
repository = "https://github.com/baloise/catcast"
@@ -24,7 +24,7 @@ serde_json = "1"
2424
serde_yaml = "0.9"
2525
thiserror = "2"
2626
anyhow = "1"
27-
chrono = { version = "0.4", features = ["serde"] }
27+
chrono = { version = "0.4", default-features = false, features = ["clock", "std", "serde"] }
2828
cron = "0.15"
2929

3030
# crypto
@@ -35,8 +35,15 @@ base64 = "0.22"
3535
zeroize = "1"
3636

3737
# async / ws
38-
tokio = { version = "1", features = ["full"] }
39-
tokio-tungstenite = { version = "0.27", features = ["rustls-tls-webpki-roots"] }
38+
tokio = { version = "1", features = [
39+
"rt-multi-thread",
40+
"io-util",
41+
"net",
42+
"sync",
43+
"time",
44+
"macros",
45+
] }
46+
tokio-tungstenite = { version = "0.29", features = ["rustls-tls-webpki-roots"] }
4047
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12", "logging"] }
4148
futures-util = "0.3"
4249

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ cd crates/catsocks && wrangler deploy
2929
# -> wss://catsocks.<your-acct>.workers.dev/r/<your-room>
3030

3131
# 2. On each stage machine
32-
catstage.exe --install-autostart --socks wss://.../r/<room> --name kitchen
32+
catstage.exe --install-autostart --socks wss://.../r/<room> --name kitchen --screen 2
33+
# Optional: --screen is 1-based. If unavailable, catstage falls back to primary monitor.
3334

3435
# 3. On your laptop
3536
catc init --socks wss://.../r/<room>

crates/catc/Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,10 @@ catcast-proto = { workspace = true }
1616

1717
clap = { workspace = true }
1818
serde = { workspace = true }
19-
serde_json = { workspace = true }
2019
serde_yaml = { workspace = true }
2120
toml = { workspace = true }
2221
anyhow = { workspace = true }
23-
thiserror = { workspace = true }
2422
directories = { workspace = true }
25-
chrono = { workspace = true }
2623
humantime = { workspace = true }
2724

2825
tokio = { workspace = true }

crates/catcast-core/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ description = "Shared types: Config, LogicSource, State"
99
[dependencies]
1010
serde = { workspace = true }
1111
serde_yaml = { workspace = true }
12-
serde_json = { workspace = true }
1312
thiserror = { workspace = true }
1413
chrono = { workspace = true }
1514
cron = { workspace = true }

crates/catstage/Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ serde = { workspace = true }
2222
serde_json = { workspace = true }
2323
serde_yaml = { workspace = true }
2424
anyhow = { workspace = true }
25-
thiserror = { workspace = true }
2625
directories = { workspace = true }
2726
chrono = { workspace = true }
28-
cron = { workspace = true }
29-
humantime = { workspace = true }
3027

3128
tokio = { workspace = true }
3229
tokio-tungstenite = { workspace = true }

crates/catstage/src/about.rs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,24 @@ use tokio::sync::mpsc;
2323
use crate::scheduler;
2424
use crate::Shared as MainShared;
2525

26-
/// The URL the window loaded on first paint — captured in `main.rs`'s setup
27-
/// callback and used by the on_page_load script (`build_escape_script` in
28-
/// main.rs) to bring the operator back to about from any external page.
29-
/// Platform-specific: typically `tauri://localhost/` on Linux/macOS or
30-
/// `http://tauri.localhost/` on Windows.
31-
pub struct AboutUrl(pub tauri::Url);
26+
/// Canonical in-memory target for "go to about" actions. Updated by `main.rs`
27+
/// when it sees a finished load of the bundled about page, and used by both
28+
/// the injected F1 handler and Rust-side Idle transitions.
29+
pub struct AboutUrl(pub Mutex<tauri::Url>);
30+
31+
impl AboutUrl {
32+
pub fn new(url: tauri::Url) -> Self {
33+
Self(Mutex::new(url))
34+
}
35+
36+
pub fn get(&self) -> tauri::Url {
37+
self.0.lock().expect("AboutUrl poisoned").clone()
38+
}
39+
40+
pub fn set(&self, url: tauri::Url) {
41+
*self.0.lock().expect("AboutUrl poisoned") = url;
42+
}
43+
}
3244

3345
/// Shared runtime handles for the about page snapshot + the broker dispatch
3446
/// path. `make_snapshot` reads `shared`/`broker_url`/`stage_name`; the
@@ -37,9 +49,16 @@ pub struct AboutUrl(pub tauri::Url);
3749
/// wire the socks inbound dispatch closure.
3850
pub struct TauriCtx {
3951
pub shared: Arc<Mutex<MainShared>>,
52+
/// Human-readable broker location for the about-page snapshot. Online
53+
/// stages expose the actual `wss://...` URL; offline modes carry the
54+
/// sentinel `"(offline)"`.
4055
pub broker_url: String,
56+
/// True when catstage was started with `--offline` or `--url` — no broker
57+
/// task is spawned and the about page should make the operator aware.
58+
pub offline: bool,
4159
pub sched_tx: mpsc::Sender<scheduler::Cmd>,
4260
pub stage_name: String,
61+
pub screen: Option<u32>,
4362
}
4463

4564
#[derive(Debug, Clone, Serialize)]
@@ -53,6 +72,7 @@ pub struct FileEntry {
5372
pub struct Snapshot {
5473
pub state: State,
5574
pub broker_url: String,
75+
pub offline: bool,
5676
pub stage_name: String,
5777
pub files: Vec<FileEntry>,
5878
pub autostart_path: Option<String>,
@@ -63,6 +83,7 @@ pub fn make_snapshot(ctx: &TauriCtx) -> Snapshot {
6383
Snapshot {
6484
state,
6585
broker_url: ctx.broker_url.clone(),
86+
offline: ctx.offline,
6687
stage_name: ctx.stage_name.clone(),
6788
files: file_entries(),
6889
autostart_path: crate::autostart::is_installed().map(|p| p.display().to_string()),
@@ -136,6 +157,23 @@ pub async fn enter_idle(ctx: tauri::State<'_, TauriCtx>) -> Result<(), String> {
136157
.map_err(|e| e.to_string())
137158
}
138159

160+
/// Resume scheduler playback from the about page. Bound to the page-local
161+
/// F2 shortcut so an operator can leave Idle without needing a separate CLI.
162+
#[tauri::command]
163+
pub async fn enter_play(ctx: tauri::State<'_, TauriCtx>) -> Result<(), String> {
164+
ctx.sched_tx
165+
.send(scheduler::Cmd::Play)
166+
.await
167+
.map_err(|e| e.to_string())
168+
}
169+
170+
/// Exit the catstage process when confirmed by the about page.
171+
#[tauri::command]
172+
pub async fn request_exit(app: tauri::AppHandle) -> Result<(), String> {
173+
app.exit(0);
174+
Ok(())
175+
}
176+
139177
/// Push the latest snapshot to the about page (via Tauri event). Called
140178
/// from `SchedEvents` (and from broker dispatch handlers in `main.rs`)
141179
/// after state changes.

0 commit comments

Comments
 (0)