mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-24 14:45:56 +00:00
Improve command line and web interface
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -376,7 +376,7 @@ version = "0.6.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -578,7 +578,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "humantime"
|
name = "humantime"
|
||||||
version = "1.2.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1458,6 +1458,7 @@ dependencies = [
|
|||||||
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1476,6 +1477,7 @@ dependencies = [
|
|||||||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2194,7 +2196,7 @@ dependencies = [
|
|||||||
"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4"
|
"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4"
|
||||||
"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
|
"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
|
||||||
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
|
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
|
||||||
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
|
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||||
"checksum hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)" = "7cb44cbce9d8ee4fb36e4c0ad7b794ac44ebaad924b9c8291a63215bb44c2c8f"
|
"checksum hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)" = "7cb44cbce9d8ee4fb36e4c0ad7b794ac44ebaad924b9c8291a63215bb44c2c8f"
|
||||||
"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f"
|
"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f"
|
||||||
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
|
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ csv = "1.0"
|
|||||||
env_logger = "0.6"
|
env_logger = "0.6"
|
||||||
failure = "0.1.3"
|
failure = "0.1.3"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
|
humantime = "1.3.0"
|
||||||
hyper = "0.12"
|
hyper = "0.12"
|
||||||
reqwest = "0.9.20"
|
|
||||||
jod-thread = "0.1.0"
|
jod-thread = "0.1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
maplit = "1.0.1"
|
maplit = "1.0.1"
|
||||||
@@ -48,9 +48,11 @@ rbx_dom_weak = "1.9.0"
|
|||||||
rbx_reflection = "3.1.388"
|
rbx_reflection = "3.1.388"
|
||||||
rbx_xml = "0.11.0"
|
rbx_xml = "0.11.0"
|
||||||
regex = "1.0"
|
regex = "1.0"
|
||||||
|
reqwest = "0.9.20"
|
||||||
ritz = "0.1.0"
|
ritz = "0.1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
termcolor = "1.0.5"
|
||||||
uuid = { version = "0.7", features = ["v4", "serde"] }
|
uuid = { version = "0.7", features = ["v4", "serde"] }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
|||||||
BIN
assets/icon-32.png
Normal file
BIN
assets/icon-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 975 B |
@@ -1,11 +1,17 @@
|
|||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
text-decoration: inherit;
|
||||||
|
color: inherit;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
|
box-sizing: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
box-sizing: border-box;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
text-decoration: none;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,27 +23,54 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
|
flex: 0 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
text-align: center;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 60rem;
|
max-width: 50rem;
|
||||||
background-color: #efefef;
|
background-color: #efefef;
|
||||||
border: 1px solid #666;
|
border: 1px solid #666;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.header {
|
||||||
font-size: 2rem;
|
flex: 0 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-logo {
|
||||||
|
flex: 0 0;
|
||||||
|
width: 20rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
|
flex: 0 0 20rem;
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-name {
|
||||||
|
display: inline;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.button-list {
|
||||||
font-size: 1.5rem;
|
flex: 0 0;
|
||||||
font-weight: bold;
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
}
|
}
|
||||||
|
|
||||||
.docs {
|
.button {
|
||||||
font-size: 1.3rem;
|
display: inline-block;
|
||||||
font-weight: bold;
|
border: 1px solid #666;
|
||||||
|
padding: 0.3em 1em;
|
||||||
|
margin: 0 0.2rem;
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
use std::{collections::HashMap, path::PathBuf, sync::Arc};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
io::{self, Write},
|
||||||
|
path::PathBuf,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use failure::Fail;
|
use failure::Fail;
|
||||||
use rbx_dom_weak::RbxInstanceProperties;
|
use rbx_dom_weak::RbxInstanceProperties;
|
||||||
|
use termcolor::{BufferWriter, Color, ColorChoice, ColorSpec, WriteColor};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
imfs::{Imfs, RealFetcher, WatchMode},
|
imfs::{Imfs, RealFetcher, WatchMode},
|
||||||
@@ -46,7 +52,7 @@ pub fn serve(options: &ServeOptions) -> Result<(), ServeError> {
|
|||||||
})
|
})
|
||||||
.unwrap_or(DEFAULT_PORT);
|
.unwrap_or(DEFAULT_PORT);
|
||||||
|
|
||||||
println!("Rojo server listening on port {}", port);
|
let _ = show_start_message(port);
|
||||||
|
|
||||||
let mut tree = RojoTree::new(InstancePropertiesWithMeta {
|
let mut tree = RojoTree::new(InstancePropertiesWithMeta {
|
||||||
properties: RbxInstanceProperties {
|
properties: RbxInstanceProperties {
|
||||||
@@ -75,20 +81,36 @@ pub fn serve(options: &ServeOptions) -> Result<(), ServeError> {
|
|||||||
|
|
||||||
server.start(port);
|
server.start(port);
|
||||||
|
|
||||||
// let receiver = imfs.change_receiver();
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// while let Ok(change) = receiver.recv() {
|
fn show_start_message(port: u16) -> io::Result<()> {
|
||||||
// imfs.commit_change(&change)
|
let mut writer = BufferWriter::stderr(ColorChoice::Auto);
|
||||||
// .expect("Failed to commit Imfs change");
|
let mut buffer = writer.buffer();
|
||||||
|
|
||||||
// use notify::DebouncedEvent;
|
writeln!(&mut buffer, "Rojo server listening:")?;
|
||||||
// if let DebouncedEvent::Write(path) = change {
|
|
||||||
// let contents = imfs.get_contents(path)
|
|
||||||
// .expect("Failed to read changed path");
|
|
||||||
|
|
||||||
// println!("{:?}", std::str::from_utf8(contents));
|
write!(&mut buffer, " Address: ")?;
|
||||||
// }
|
buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
|
||||||
// }
|
writeln!(&mut buffer, "localhost")?;
|
||||||
|
|
||||||
|
buffer.set_color(&ColorSpec::new())?;
|
||||||
|
write!(&mut buffer, " Port: ")?;
|
||||||
|
buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
|
||||||
|
writeln!(&mut buffer, "{}", port)?;
|
||||||
|
|
||||||
|
writeln!(&mut buffer, "")?;
|
||||||
|
|
||||||
|
buffer.set_color(&ColorSpec::new())?;
|
||||||
|
write!(&mut buffer, "Visit ")?;
|
||||||
|
|
||||||
|
buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?;
|
||||||
|
write!(&mut buffer, "http://localhost:{}/", port)?;
|
||||||
|
|
||||||
|
buffer.set_color(&ColorSpec::new())?;
|
||||||
|
writeln!(&mut buffer, " in your browser for more information.")?;
|
||||||
|
|
||||||
|
writer.print(&buffer)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Recursion limit bump is to support Ritz, a JSX-like proc macro used for
|
// Recursion limit bump is to support Ritz, a JSX-like proc macro used for
|
||||||
// Rojo's web UI currently.
|
// Rojo's web UI currently.
|
||||||
#![recursion_limit = "128"]
|
#![recursion_limit = "1024"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod impl_from;
|
mod impl_from;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
sync::{Arc, Mutex, MutexGuard},
|
sync::{Arc, Mutex, MutexGuard},
|
||||||
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -20,6 +21,10 @@ use crate::{
|
|||||||
/// future. `ServeSession` would be roughly the right interface to expose for
|
/// future. `ServeSession` would be roughly the right interface to expose for
|
||||||
/// those cases.
|
/// those cases.
|
||||||
pub struct ServeSession<F> {
|
pub struct ServeSession<F> {
|
||||||
|
/// When the serve session was started. Used only for user-facing
|
||||||
|
/// diagnostics.
|
||||||
|
start_time: Instant,
|
||||||
|
|
||||||
/// The root project for the serve session, if there was one defined.
|
/// The root project for the serve session, if there was one defined.
|
||||||
///
|
///
|
||||||
/// This will be defined if a folder with a `default.project.json` file was
|
/// This will be defined if a folder with a `default.project.json` file was
|
||||||
@@ -66,6 +71,8 @@ pub struct ServeSession<F> {
|
|||||||
/// that handles ServeSession.
|
/// that handles ServeSession.
|
||||||
impl<F: ImfsFetcher + Send + 'static> ServeSession<F> {
|
impl<F: ImfsFetcher + Send + 'static> ServeSession<F> {
|
||||||
pub fn new(imfs: Imfs<F>, tree: RojoTree, root_project: Option<Project>) -> Self {
|
pub fn new(imfs: Imfs<F>, tree: RojoTree, root_project: Option<Project>) -> Self {
|
||||||
|
let start_time = Instant::now();
|
||||||
|
|
||||||
let session_id = SessionId::new();
|
let session_id = SessionId::new();
|
||||||
let message_queue = MessageQueue::new();
|
let message_queue = MessageQueue::new();
|
||||||
|
|
||||||
@@ -80,6 +87,7 @@ impl<F: ImfsFetcher + Send + 'static> ServeSession<F> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
start_time,
|
||||||
session_id,
|
session_id,
|
||||||
root_project,
|
root_project,
|
||||||
tree,
|
tree,
|
||||||
@@ -107,6 +115,16 @@ impl<F: ImfsFetcher> ServeSession<F> {
|
|||||||
self.session_id
|
self.session_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn project_name(&self) -> Option<&str> {
|
||||||
|
self.root_project
|
||||||
|
.as_ref()
|
||||||
|
.map(|project| project.name.as_str())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_time(&self) -> Instant {
|
||||||
|
self.start_time
|
||||||
|
}
|
||||||
|
|
||||||
pub fn serve_place_ids(&self) -> Option<&HashSet<u64>> {
|
pub fn serve_place_ids(&self) -> Option<&HashSet<u64>> {
|
||||||
self.root_project
|
self.root_project
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! Defines the HTTP-based UI. These endpoints generally return HTML and SVG.
|
//! Defines the HTTP-based UI. These endpoints generally return HTML and SVG.
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
use futures::{future, Future};
|
use futures::{future, Future};
|
||||||
use hyper::{header, service::Service, Body, Method, Request, Response, StatusCode};
|
use hyper::{header, service::Service, Body, Method, Request, Response, StatusCode};
|
||||||
@@ -15,10 +15,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static LOGO: &[u8] = include_bytes!("../../assets/logo-512.png");
|
||||||
|
static ICON: &[u8] = include_bytes!("../../assets/icon-32.png");
|
||||||
static HOME_CSS: &str = include_str!("../../assets/index.css");
|
static HOME_CSS: &str = include_str!("../../assets/index.css");
|
||||||
|
|
||||||
pub struct UiService<F> {
|
pub struct UiService<F> {
|
||||||
#[allow(unused)] // TODO: Fill out interface service
|
|
||||||
serve_session: Arc<ServeSession<F>>,
|
serve_session: Arc<ServeSession<F>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ impl<F: ImfsFetcher> Service for UiService<F> {
|
|||||||
fn call(&mut self, request: Request<Self::ReqBody>) -> Self::Future {
|
fn call(&mut self, request: Request<Self::ReqBody>) -> Self::Future {
|
||||||
let response = match (request.method(), request.uri().path()) {
|
let response = match (request.method(), request.uri().path()) {
|
||||||
(&Method::GET, "/") => self.handle_home(),
|
(&Method::GET, "/") => self.handle_home(),
|
||||||
|
(&Method::GET, "/logo.png") => self.handle_logo(),
|
||||||
|
(&Method::GET, "/icon.png") => self.handle_icon(),
|
||||||
(&Method::GET, "/visualize/rbx") => self.handle_visualize_rbx(),
|
(&Method::GET, "/visualize/rbx") => self.handle_visualize_rbx(),
|
||||||
(&Method::GET, "/visualize/imfs") => self.handle_visualize_imfs(),
|
(&Method::GET, "/visualize/imfs") => self.handle_visualize_imfs(),
|
||||||
(_method, path) => {
|
(_method, path) => {
|
||||||
@@ -50,28 +53,74 @@ impl<F: ImfsFetcher> UiService<F> {
|
|||||||
UiService { serve_session }
|
UiService { serve_session }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_logo(&self) -> Response<Body> {
|
||||||
|
Response::builder()
|
||||||
|
.header(header::CONTENT_TYPE, "image/png")
|
||||||
|
.body(Body::from(LOGO))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_icon(&self) -> Response<Body> {
|
||||||
|
Response::builder()
|
||||||
|
.header(header::CONTENT_TYPE, "image/png")
|
||||||
|
.body(Body::from(ICON))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_home(&self) -> Response<Body> {
|
fn handle_home(&self) -> Response<Body> {
|
||||||
|
let project_name = self.serve_session.project_name().unwrap_or("<unnamed>");
|
||||||
|
let uptime = {
|
||||||
|
let elapsed = self.serve_session.start_time().elapsed();
|
||||||
|
|
||||||
|
// Round off all of our sub-second precision to make timestamps
|
||||||
|
// nicer.
|
||||||
|
let just_nanos = Duration::from_nanos(elapsed.subsec_nanos() as u64);
|
||||||
|
let elapsed = elapsed - just_nanos;
|
||||||
|
|
||||||
|
humantime::format_duration(elapsed).to_string()
|
||||||
|
};
|
||||||
|
|
||||||
let page = html! {
|
let page = html! {
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>"Rojo"</title>
|
<title>"Rojo Live Server"</title>
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/icon.png" />
|
||||||
<style>
|
<style>
|
||||||
{ ritz::UnescapedText::new(HOME_CSS) }
|
{ ritz::UnescapedText::new(HOME_CSS) }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="main">
|
<main class="main">
|
||||||
<h1 class="title">
|
<header class="header">
|
||||||
"Rojo Live Sync is up and running!"
|
<img class="main-logo" src="/logo.png" />
|
||||||
</h1>
|
<div class="stats">
|
||||||
<h2 class="subtitle">
|
<span class="stat">
|
||||||
"Version " { SERVER_VERSION }
|
<span class="stat-name">"Server Version: "</span>
|
||||||
</h2>
|
<span class="stat-value">{ SERVER_VERSION }</span>
|
||||||
<a class="docs" href="https://rojo.space/docs">
|
</span>
|
||||||
"Rojo Documentation"
|
<span class="stat">
|
||||||
</a>
|
<span class="stat-name">"Project: "</span>
|
||||||
</div>
|
<span class="stat-value">{ project_name }</span>
|
||||||
|
</span>
|
||||||
|
<span class="stat">
|
||||||
|
<span class="stat-name">"Server Uptime: "</span>
|
||||||
|
<span class="stat-value">{ uptime.to_string() }</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="button-list">
|
||||||
|
<a class="button" href="https://rojo.space/docs">
|
||||||
|
"Rojo Documentation"
|
||||||
|
</a>
|
||||||
|
<a class="button" href="/visualize/imfs">
|
||||||
|
"View in-memory filesystem state"
|
||||||
|
</a>
|
||||||
|
<a class="button" href="/visualize/rbx">
|
||||||
|
"View instance tree state"
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user