Initial cockpit commit
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Isaac Mills 2025-07-18 16:42:04 -06:00
parent 537774f120
commit 21d93f7073
Signed by: fnmain
GPG key ID: B67D7410F33A0F61
17 changed files with 177 additions and 22 deletions

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "thecockpit/ratzilla"]
path = thecockpit/ratzilla
url = https://github.com/StratusFearMe21/ratzilla
branch = resize_canvas

View file

@ -13,6 +13,7 @@
<link rel="apple-touch-icon" href="/assets/apple-touch-icon.png"> <link rel="apple-touch-icon" href="/assets/apple-touch-icon.png">
<stack name="head"></stack> <stack name="head"></stack>
<script type="module" src="index.js"></script> <script type="module" src="index.js"></script>
<script type="module" src="thecockpit.js"></script>
<meta name="htmx-config" content='{"responseHandling": [{"code":"204", "swap": false},{"code":"...", "swap": true}]}'> <meta name="htmx-config" content='{"responseHandling": [{"code":"204", "swap": false},{"code":"...", "swap": true}]}'>
</head> </head>

View file

@ -7,7 +7,8 @@
<x-tab.button page="projects.html" selected="{{ selected-- }}">Our Projects</x-tab.button> <x-tab.button page="projects.html" selected="{{ selected-- }}">Our Projects</x-tab.button>
<x-tab.button page="who_we_are.html" selected="{{ selected-- }}">Who we are</x-tab.button> <x-tab.button page="who_we_are.html" selected="{{ selected-- }}">Who we are</x-tab.button>
<x-tab.button page="interests.html" selected="{{ selected-- }}">Our Interests</x-tab.button> <x-tab.button page="interests.html" selected="{{ selected-- }}">Our Interests</x-tab.button>
<x-tab.button page="page_four.html" selected="{{ selected-- }}">Page Four</x-tab.button> <x-tab.button page="thecockpit.html" selected="{{ selected-- }}">The Cockpit</x-tab.button>
<x-tab.button page="page_five.html" selected="{{ selected-- }}">Page Five</x-tab.button>
</nav> </nav>
<hr id="tab-break"> <hr id="tab-break">
<div id="tab-content" role="tabpanel" class="tab-content"> <div id="tab-content" role="tabpanel" class="tab-content">

3
src/page_five.html Normal file
View file

@ -0,0 +1,3 @@
<x-head>
<include src="src/partials/page_five.html"></include>
</x-head>

View file

@ -1,3 +0,0 @@
<x-head>
<include src="src/partials/page_four.html"></include>
</x-head>

View file

@ -1,5 +1,5 @@
<x-tab.content selected="3"> <x-tab.content selected="4">
<x-section-head header="Page four"> <x-section-head header="Page five">
<x-blockquote cite="Josh Arbon (CEO of Tysontoucherinator)"> <x-blockquote cite="Josh Arbon (CEO of Tysontoucherinator)">
Who is this guy? Who is this guy?
</x-blockquote> </x-blockquote>
@ -20,7 +20,7 @@
```=html ```=html
<form hx-post="/api/page-idea" hx-target="#page-idea-result" hx-indicator="#page-idea-indicator"> <form hx-post="/api/page-idea" hx-target="#page-idea-result" hx-indicator="#page-idea-indicator">
<label for="page-idea"> <label for="page-idea">
What should we put on page 4 of The SANDWICH? What should we put on page 5 of The SANDWICH?
</label><br> </label><br>
<textarea name="page-idea" id="page-idea"></textarea> <textarea name="page-idea" id="page-idea"></textarea>
<input type="submit" value="Submit Idea!"> <input type="submit" value="Submit Idea!">

View file

@ -0,0 +1,18 @@
<x-tab.content selected="3">
<x-section-head header="The Cockpit">
<djot>
## Fact:
In Myrtle Beach South Carolina, Richard and Isaac counted 100 Chrysler Pacificas in the span of a week.
</djot>
</x-section-head>
<div id="cockpit-canvas" style="height: 80vh; margin: 8px"></div>
</x-tab.content>
<script>
var interval = setInterval(function () {
if (typeof window.run_cockpit === 'function') {
clearInterval(interval);
window.run_cockpit();
}
}, 100);
</script>

View file

@ -26,6 +26,16 @@ html {
justify-content: space-between; justify-content: space-between;
section {
padding: 32px;
text-align: center;
p {
text-align: center;
}
}
h1 { h1 {
font-size: 48pt; font-size: 48pt;
} }

3
src/thecockpit.html Normal file
View file

@ -0,0 +1,3 @@
<x-head>
<include src="src/partials/thecockpit.html"></include>
</x-head>

5
src/thecockpit.js Normal file
View file

@ -0,0 +1,5 @@
import { default as init, run } from 'thecockpit'
window.run_cockpit = async () => {
await init();
run("cockpit-canvas");
};

View file

@ -9,8 +9,17 @@ crate-type = ["cdylib", "rlib"]
[features] [features]
default = ["console_error_panic_hook"] default = ["console_error_panic_hook"]
console_error_panic_hook = ["dep:console_error_panic_hook"]
[dependencies] [[bin]]
name = "thecockpit"
path = "src/main.rs"
required-features = ["ratatui/default"]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
ratatui = { version = "0.29.0", default-features = false }
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.84" wasm-bindgen = "0.2.84"
# The `console_error_panic_hook` crate provides better debugging of panics by # The `console_error_panic_hook` crate provides better debugging of panics by
@ -18,10 +27,12 @@ wasm-bindgen = "0.2.84"
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying. # code size when deploying.
console_error_panic_hook = { version = "0.1.7", optional = true } console_error_panic_hook = { version = "0.1.7", optional = true }
ratzilla = { path = "./ratzilla" }
[dev-dependencies] [target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.3.34" wasm-bindgen-test = "0.3.34"
[profile.release] [profile.release]
# Tell `rustc` to optimize for small code size. # Tell `rustc` to optimize for small code size.
opt-level = "s" opt-level = "s"

1
thecockpit/ratzilla Submodule

@ -0,0 +1 @@
Subproject commit 3bcbd53bb0a57080740e3a71ef44b7ceb9b74403

50
thecockpit/src/app.rs Normal file
View file

@ -0,0 +1,50 @@
#[cfg(target_arch = "wasm32")]
use ratzilla::ratatui;
use ratatui::{
style::{Color, Stylize},
widgets::{Block, Borders, Paragraph},
Frame,
};
#[derive(Default)]
pub struct App {}
const SPLASH: &str = r#"
!~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
!~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
!!~~~~~~!J5PPPPPPPPPPP?^^^^7PPPPPPPPPPPPPPPPY~^^^^
!!!!!!~~~!JB&@@@@@@@@@5^^^^Y@@@@@@@@@@@@@@@@#~^^^^
!!!!!5?!~~~!JG&@@@@@@@5^^^^Y@@@@@@@@@@@@@@@@#~^^^^
!!!!7#&GJ!~~~!?G&@@@@@5^^^^Y@@@@@@@@@@@@@@@@#~^^^^
7!!!7#@@&BJ!~~~!?G&@@@5^^^^Y@@@@@@@@@@@@@@@@#~^^^^
7!!!7#@@@@@BY!~~~~?P&@5~^^^Y@@@@@@@@@@@@@@@@#~^^^^
777!7#@@@@@@@BY!~~~~7PY~~~^Y@@@@@@@@@@@@@@@@#~^^^^
7777?#@@@@@@@@@#Y7~~~~!~~~~Y@@@@@@@@@@@@@@@@#~^^^^
7777?#@@@@@@@@@@@#57~~~~~~~Y@@@@@@@@@@@@@@@@#~^^^^
?777?#@@@@@@@@@@@@@#57~~~~~?#@@@@@@@@@@@@@@@#~^^^^
?777?#@@@@@@@@@@@@@@@#J~~~~~!Y#@@@@@@@@@@@@@#~^^^^
???7?#@@@@@@@@@@@@@@@@P!!~~~~~!YB@@@@@@@@@@@#~^^^^
?????#@@@@@@@@@@@@@@@@P!!!!!!~~~!YB@@@@@@@@@#~^^^^
????J&@@@@@@@@@@@@@@@@P!!!!YG?!~~~!JB&@@@@@@#~^^^^
????J&@@@@@@@@@@@@@@@@P!!!!5@&G?!~~~!JG&@@@@#~^^^^
J???J&@@@@@@@@@@@@@@@@P!!!!5@@@&GJ!~~~!?G&@@#!^^^^
J???J&@@@@@@@@@@@@@@@@P7!!!5@@@@@&BJ!~~~!?G&#!^^^~
JJJ?J&@@@@@@@@@@@@@@@@P777!5@@@@@@@@BY!~~~~?5!~~^~
JJJJJ&@@@@@@@@@@@@@@@@P77775@@@@@@@@@@BY!~~~~~~~~~
JJJJJGBBGGGGGGGGGGGGGGY7777JGGGGGGGPPPPPY!~~~~~~~~
YJJJJJJJJJ????????????77777777777!!!!!!!!!!!~~~~~~
YJJJJJJJJJJJ???????????77777777777!!!!!!!!!!!~~~~~
"#;
impl App {
pub fn draw(&mut self, frame: &mut Frame) {
frame.render_widget(
Paragraph::new(SPLASH)
.alignment(ratatui::layout::Alignment::Center)
.fg(Color::Rgb(226, 190, 89))
.block(Block::new().borders(Borders::all()).title("Coming soon")),
frame.area(),
);
}
}

View file

@ -1,13 +1,3 @@
mod utils; pub mod app;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*; mod web;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet() {
alert("Hello, thecockpit!");
}

25
thecockpit/src/main.rs Normal file
View file

@ -0,0 +1,25 @@
use std::time::Duration;
use ratatui::crossterm::event;
use thecockpit::app::App;
fn main() {
let mut terminal = ratatui::init();
let mut app = App::default();
loop {
terminal.draw(|frame| app.draw(frame));
if event::poll(Duration::from_secs(0)).unwrap() {
match event::read().unwrap() {
event::Event::Key(event::KeyEvent {
code: event::KeyCode::Char('q'),
..
}) => break,
_ => {}
}
}
}
ratatui::restore();
}

36
thecockpit/src/web/mod.rs Normal file
View file

@ -0,0 +1,36 @@
use std::{cell::RefCell, rc::Rc};
use ratzilla::{
backend::canvas::CanvasBackendOptions,
ratatui::{
widgets::{Block, Borders},
Terminal,
},
web_sys, CanvasBackend, WebRenderer,
};
use wasm_bindgen::prelude::*;
mod utils;
use crate::app::App;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn run(grid_id: &str) {
console_error_panic_hook::set_once();
let backend =
CanvasBackend::new_with_options(CanvasBackendOptions::new().grid_id(grid_id)).unwrap();
let terminal = Terminal::new(backend).unwrap();
let app = Rc::new(RefCell::new(App::default()));
terminal.draw_web({
let app = Rc::clone(&app);
move |frame| app.borrow_mut().draw(frame)
})
}