Prints welcome

main
Ashelyn Dawn 2 years ago
parent 9632e8705e
commit a4ecded355

38
Cargo.lock generated

@ -32,9 +32,9 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.51"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
dependencies = [
"wasm-bindgen",
]
@ -100,7 +100,9 @@ name = "tildashe"
version = "0.1.0"
dependencies = [
"console_error_panic_hook",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wee_alloc",
]
@ -113,9 +115,9 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wasm-bindgen"
version = "0.2.74"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
@ -123,9 +125,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.74"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
dependencies = [
"bumpalo",
"lazy_static",
@ -136,11 +138,23 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.74"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -148,9 +162,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.74"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
dependencies = [
"proc-macro2",
"quote",
@ -161,9 +175,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.74"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
[[package]]
name = "web-sys"

@ -11,6 +11,8 @@ opt-level = 'z'
[dependencies]
console_error_panic_hook = "0.1"
web-sys = { version = "0.3", features = ["Window", "Document", "HtmlElement", "Node", "Text", "KeyboardEvent"] }
wasm-bindgen = "=0.2.74"
web-sys = { version = "0.3", features = ["Window", "Document", "HtmlElement", "KeyboardEvent"] }
wasm-bindgen = "0.2.78"
wee_alloc = "0.4.5"
wasm-bindgen-futures = "0.4.28"
js-sys = "0.3.55"

@ -6,37 +6,68 @@
<script src="https://unpkg.com/ansi_up@5.1.0/ansi_up.js"></script>
</head>
<body>
<div id="target"></div>
<div class="container">
<div id="target"></div>
</div>
<style>
html, body {
--background-color: rgb(37, 29, 51);
--foreground-color: white;
background: var(--background-color);
color: var(--foreground-color);
margin: 0;
padding: 0;
}
#target {
white-space: pre;
a {
color: currentColor!important;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background: black;
}
.container {
background: var(--background-color);
white-space: pre-wrap;
word-break: break-all;
font-family: 'Courier New', Courier, monospace;
height: 450px;
width: 600px;
position: relative;
overflow: hidden;
user-select: none;
}
#target {
position: absolute;
bottom: 0;
min-height: 100%;
}
#target::after {
content: '█';
display: inline-block;
/* animation: blink 2.4s infinite; */
animation: blink 2.4s infinite;
opacity: .8;
}
@keyframes blink {
0%, 49% {
color: var(--foreground-color);
border: solid 1px transparent;
border: none;
/* margin: .5px; */
}
50%, 99% {
color: transparent;
border: solid .5px var(--foreground-color);
/* border: solid .5px var(--foreground-color); */
margin: 0px;
}
}
</style>

@ -0,0 +1,15 @@
ashe@tilde.club's password:
Welcome to AsheOS 21.12.1 LTS (HRT/Estrix 6.25.21-wasm)
* Technical: https://tempest.dev
* Personal: https://ashe.gay
* Community: https://tilde.club
System information as of Sun Dec 12 01:20:23 UTC 2021
Usage of /: 83.0% of 128MB
Memory usage: 12%
Processes: 15
Users logged in: 1
Last login: Sat Dec 11 06:52:52 2021 from 142.44.150.184

@ -0,0 +1,122 @@
use wasm_bindgen::prelude::*;
use web_sys::KeyboardEvent;
use web_sys::Element;
use crate::State;
pub enum Key {
Letter(char),
Space,
Backspace,
Return,
Ctrl(Box<Key>)
}
pub fn parse_key_event(event : &KeyboardEvent, ignore_ctrl : bool) -> Option<Key> {
if event.ctrl_key() && !ignore_ctrl {
let base = parse_key_event(event, true)?;
return Some(Key::Ctrl(Box::new(base)))
}
let key = event.key();
// TODO: ^C
match key.as_str() {
"Space" => Some(Key::Space),
"Backspace" => Some(Key::Backspace),
"Enter" => Some(Key::Return),
_ => {
if key.len() != 1 {
None
} else {
Some(Key::Letter(key.chars().next().unwrap()))
}
}
}
}
pub fn update_state(state : &mut State, key : Key) {
match key {
Key::Return => {
let input = std::mem::replace(&mut state.input, String::new());
state.output.push_back(format!("{} {}", state.prompt, input));
if state.output.len() > state.max_rows {
state.output.pop_front();
}
// TODO - parse the command
},
Key::Backspace => {
if state.input.len() > 0 {
state.input.remove(state.input.len() - 1);
}
},
Key::Space => state.input += " ",
Key::Letter(letter) => {
let mut tmp = [0; 4];
state.input += letter.encode_utf8(&mut tmp)
}
Key::Ctrl(letter) =>
match letter.as_ref() {
Key::Letter(letter) => {
if *letter == 'c' {
let mut input = std::mem::replace(&mut state.input, String::new());
input += "^C";
state.output.push_back(format!("{}", input));
if state.output.len() > state.max_rows {
state.output.pop_front();
}
}
}
_ => ()
}
}
}
#[wasm_bindgen(inline_js = "const ansi_up = new AnsiUp; export function format_html(text) { return ansi_up.ansi_to_html(text).replace(/(https:[^ ]*)/g, '<a href=\"$1\" target=\"_blank\">$1</a>') }")]
extern "C" {
fn format_html(text : String) -> String;
}
pub fn print_state(target : &mut Element, state : &State) {
let mut output = state.output.iter().map(|s| (*s).clone()).collect::<Vec<String>>().join("\n");
if state.output.len() > 0 {
output += "\n";
}
if state.prompt.len() > 0 {
output += "\x1b[0;31m";
output += state.prompt.as_str();
output += " ";
}
// TODO: Line overflow
output += state.input.as_str();
output += "\x1b[0m";
let formatted = format_html(output);
target.set_inner_html(formatted.as_str());
}
pub fn build_prompt() -> String {
let mut prompt = String::new();
prompt += "\x1b[0;36m";
prompt += "ashe";
prompt += "\x1b[2;33m";
prompt += "@";
prompt += "tilde.club";
prompt += "\x1b[2;37m";
prompt += ":";
prompt += "\x1b[2;32m";
prompt += "~";
prompt += "\x1b[2;37m";
prompt += "$";
return prompt
}

@ -1,5 +1,8 @@
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsValue;
use js_sys::Promise;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
@ -10,5 +13,21 @@ extern "C" {
macro_rules! console_log {
// Note that this is using the `log` function imported above during
// `bare_bones`
($($t:tt)*) => (js::log(&format_args!($($t)*).to_string()))
($($t:tt)*) => (crate::js::log(&format_args!($($t)*).to_string()))
}
#[wasm_bindgen(inline_js = "export function _wait(ms) { return new Promise(res => setTimeout(res, ms)) }")]
extern "C" {
fn _wait(ms: i32) -> Promise;
}
pub async fn wait(milliseconds: i32) -> Result<(), JsValue> {
let promise;
promise = _wait(milliseconds);
wasm_bindgen_futures::JsFuture::from(promise).await?;
Ok(())
}

@ -1,57 +1,64 @@
extern crate console_error_panic_hook;
#[macro_use]
mod js;
mod io;
use std::collections::VecDeque;
use std::panic;
use std::str::FromStr;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::KeyboardEvent;
use wasm_bindgen_futures::spawn_local;
use web_sys::Document;
use web_sys::Element;
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
enum Key {
Letter(char),
Space,
Backspace,
Return,
Ctrl(Box<Key>)
}
struct State {
pub struct State {
// cwd : &Directory
input : String,
output : VecDeque<String>
output : VecDeque<String>,
prompt: String,
max_rows: usize
}
impl State {
pub fn new() -> Self {
State {
input : String::new(),
output : VecDeque::new()
output : VecDeque::new(),
prompt: String::new(),
max_rows: 24
}
}
}
fn main() {
panic::set_hook(Box::new(console_error_panic_hook::hook));
let mut state = State::new();
let window = web_sys::window().expect("should have a window in this context");
let document = window.document().expect("window should have a document");
let mut target = document
spawn_local(async {
init(document).await;
});
}
async fn init(document : Document) {
let mut state = State::new();
let mut render_target = document
.get_element_by_id("target")
.expect("should have #target on the page");
print_state(&mut target, &state);
print_welcome(&mut render_target, &mut state).await;
let closure = Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| {
let key = parse_key_event(&event, false);
let key = io::parse_key_event(&event, false);
if key.is_none() {
return
@ -59,8 +66,8 @@ fn main() {
let key = key.unwrap();
update_state(&mut state, key);
print_state(&mut target, &state);
io::update_state(&mut state, key);
io::print_state(&mut render_target, &state);
}) as Box<dyn FnMut(_)>);
@ -69,77 +76,34 @@ fn main() {
closure.forget();
}
fn parse_key_event(event : &KeyboardEvent, ignore_ctrl : bool) -> Option<Key> {
if event.ctrl_key() && !ignore_ctrl {
let base = parse_key_event(event, true)?;
pub async fn print_welcome(render_target : &mut Element, state : &mut State) {
let intro = include_str!("../res/welcome.txt");
let mut lines = intro.split("\n");
return Some(Key::Ctrl(Box::new(base)))
}
let first_line = lines.next().unwrap();
state.input = String::from_str(first_line).unwrap();
io::print_state(render_target, state);
let key = event.key();
// TODO: ^C
match key.as_str() {
"Space" => Some(Key::Space),
"Backspace" => Some(Key::Backspace),
"Enter" => Some(Key::Return),
_ => {
if key.len() != 1 {
None
} else {
Some(Key::Letter(key.chars().next().unwrap()))
}
}
}
}
js::wait(3000i32).await.unwrap();
fn update_state(state : &mut State, key : Key) {
match key {
Key::Return => {
let input = std::mem::replace(&mut state.input, String::new());
state.output.push_back(format!("> {}", input));
if state.output.len() > 10 {
state.output.pop_front();
}
// TODO - parse the command
},
Key::Backspace => {
if state.input.len() > 0 {
state.input.remove(state.input.len() - 1);
}
},
Key::Space => state.input += " ",
Key::Letter(letter) => {
let mut tmp = [0; 4];
state.input += letter.encode_utf8(&mut tmp)
state.output.push_back(String::from_str(first_line).unwrap());
state.input = String::new();
io::print_state(render_target, state);
js::wait(1000i32).await.unwrap();
for line in lines {
js::wait(30i32).await.unwrap();
state.output.push_back(String::from_str(line).unwrap());
if state.output.len() > state.max_rows {
state.output.pop_front();
}
Key::Ctrl(letter) =>
match letter.as_ref() {
Key::Letter(letter) => {
if *letter == 'c' {
let mut input = std::mem::replace(&mut state.input, String::new());
input += "^C";
state.output.push_back(format!("> {}", input));
if state.output.len() > 10 {
state.output.pop_front();
}
}
}
_ => ()
}
io::print_state(render_target, state);
}
}
fn print_state(target : &mut Element, state : &State) {
let mut output = state.output.iter().map(|s| (*s).clone()).collect::<Vec<String>>().join("\n");
if state.output.len() > 0 {
output += "\n";
}
// TODO: Line overflow
output += format!("> {}", state.input.as_str()).as_str();
js::wait(100i32).await.unwrap();
target.set_text_content(Some(output.as_str()));
state.prompt = io::build_prompt();
io::print_state(render_target, state);
}
Loading…
Cancel
Save