diff --git a/assets/index.css b/assets/index.css index 8b96697b..b501f6a7 100644 --- a/assets/index.css +++ b/assets/index.css @@ -11,22 +11,29 @@ html { box-sizing: border-box; font-family: sans-serif; + font-size: 18px; text-decoration: none; height: 100%; } body { - height: 100%; + min-height: 100%; display: flex; flex-direction: column; justify-content: center; } +img { + max-width:100%; + max-height:100%; + height: auto; +} + .root { flex: 0 0; display: flex; flex-direction: column; - margin: 0 auto; + margin: 0.5rem auto; width: 100%; max-width: 50rem; background-color: #efefef; @@ -48,8 +55,7 @@ body { } .main-logo { - flex: 0 0; - width: 10rem; + flex: 0 0 10rem; margin: 1rem; } @@ -71,7 +77,8 @@ body { flex: 0 0; display: flex; flex-wrap: wrap; - justify-content: center; + justify-content: space-around; + margin: -1rem; } .button { @@ -79,4 +86,25 @@ body { border: 1px solid #666; padding: 0.3em 1em; margin: 1rem; +} + +.instance { + border: 1px solid #666; + border-right-style: none; + border-bottom-style: none; + background-color: #fff; + margin-bottom: 0.5rem; +} + +.instance-title { + font-size: 1.5rem; + padding: 0.5rem; +} + +.instance-properties { + padding: 0.5rem; +} + +.instance-children { + padding: 0.5rem 0 0.5rem 1rem; } \ No newline at end of file diff --git a/src/web/assets.rs b/src/web/assets.rs index 2832f768..3a8a5b4d 100644 --- a/src/web/assets.rs +++ b/src/web/assets.rs @@ -1,5 +1,3 @@ -use std::{fs, path::Path}; - 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"); @@ -8,12 +6,14 @@ macro_rules! declare_asset { ($name: ident, $path: expr) => { pub fn $name() -> &'static str { if cfg!(feature = "dev-live-assets") { + use std::{fs::read_to_string, path::Path}; + let file_path = Path::new(file!()); let asset_path = file_path.parent().unwrap().join($path); println!("Reloading {}", asset_path.display()); - let content = fs::read_to_string(asset_path) + let content = read_to_string(asset_path) .expect("Couldn't read dev live asset") .into_boxed_str(); diff --git a/src/web/ui.rs b/src/web/ui.rs index fca27849..b29f44ad 100644 --- a/src/web/ui.rs +++ b/src/web/ui.rs @@ -4,11 +4,13 @@ use std::{sync::Arc, time::Duration}; use futures::{future, Future}; use hyper::{header, service::Service, Body, Method, Request, Response, StatusCode}; -use ritz::{html, HtmlContent}; +use rbx_dom_weak::{RbxId, RbxValue}; +use ritz::{html, Fragment, HtmlContent}; use crate::{ imfs::ImfsFetcher, serve_session::ServeSession, + snapshot::RojoTree, web::{ assets, interface::{ErrorResponse, SERVER_VERSION}, @@ -80,19 +82,103 @@ impl UiService { } fn handle_show_instances(&self) -> Response { + let tree = self.serve_session.tree(); + let root_id = tree.get_root_id(); + + let page = self.normal_page(html! { + { Self::instance(&tree, root_id) } + }); + Response::builder() - .header(header::CONTENT_TYPE, "text/plain") - .body(Body::from("TODO: /show-instances")) + .header(header::CONTENT_TYPE, "text/html") + .body(Body::from(format!("{}", page))) .unwrap() } fn handle_show_imfs(&self) -> Response { + let page = self.normal_page(html! { + "TODO /show/imfs" + }); + Response::builder() - .header(header::CONTENT_TYPE, "text/plain") - .body(Body::from("TODO: /show-imfs")) + .header(header::CONTENT_TYPE, "text/html") + .body(Body::from(format!("{}", page))) .unwrap() } + fn instance(tree: &RojoTree, id: RbxId) -> HtmlContent<'_> { + let instance = tree.get_instance(id).unwrap(); + let children_list: Vec<_> = instance + .children() + .iter() + .copied() + .map(|id| Self::instance(tree, id)) + .collect(); + + let children_container = if children_list.is_empty() { + HtmlContent::None + } else { + html! { +
+ { Fragment::new(children_list) } +
+ } + }; + + let mut properties: Vec<_> = instance.properties().iter().collect(); + properties.sort_by_key(|pair| pair.0); + + let property_list: Vec<_> = properties + .into_iter() + .map(|(key, value)| { + html! { +
+ { key.clone() } ": " { format!("{:?}", value.get_type()) } +
+ } + }) + .collect(); + + let property_container = if property_list.is_empty() { + HtmlContent::None + } else { + html! { +
+ { Fragment::new(property_list) } +
+ } + }; + + let class_name_specifier = if instance.name() == instance.class_name() { + HtmlContent::None + } else { + html! { + + " (" { instance.class_name().to_owned() } ")" + + } + }; + + html! { +
+
+ { instance.name().to_owned() } + { class_name_specifier } +
+ { property_container } + { children_container } +
+ } + } + + fn display_value(value: &RbxValue) -> String { + match value { + RbxValue::String { value } => value.clone(), + RbxValue::Bool { value } => value.to_string(), + _ => format!("{:?}", value), + } + } + fn stat_item>(name: &str, value: S) -> HtmlContent<'_> { html! { @@ -124,7 +210,9 @@ impl UiService { Self::page(html! {
- +
{ Self::stat_item("Server Version", SERVER_VERSION) } { Self::stat_item("Project", project_name) }