Skip to content

Commit

Permalink
Add highlights
Browse files Browse the repository at this point in the history
  • Loading branch information
kitallis committed Nov 6, 2022
1 parent b470447 commit 9988e6a
Show file tree
Hide file tree
Showing 9 changed files with 574 additions and 112 deletions.
442 changes: 423 additions & 19 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 5 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@ version = "1.0.0"
edition = "2021"

[dependencies]
yew = "0.19"
yew = { git = "https://github.com/yewstack/yew.git", features = ["csr"] }
yew-hooks = { git = "https://github.com/jetli/yew-hooks" }
gloo-utils = { version = "0.1.5", features = ["serde"] }
wasm-bindgen = "0.2.83"
strum = "0.24.1"
strum_macros = "0.24.1"
serde = "1.0.147"
serde_derive = "1.0.147"
log = "0.4.6"
wasm-logger = "0.2.0"

[dependencies.web-sys]
version = "0.3.60"
features = [
"HtmlSelectElement",
"Navigator",
"Window",
"Clipboard"
]
web-sys = { version = "0.3.60", features = ["HtmlSelectElement", "HtmlElement"]}
wasm-logger = "0.2.0"
11 changes: 3 additions & 8 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>congo</title>
<title>cong</title>
<base data-trunk-public-url />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.css">
<link rel="stylesheet" href="/public/simple.min.css">
<link rel="stylesheet" href="/public/androidstudio.min.css">
<link data-trunk rel="copy-dir" href="public/" />
<link rel="stylesheet" href="public/style.css">
<link rel="apple-touch-icon" sizes="57x57" href="public/apple-icon-57x57.png">
Expand All @@ -25,13 +26,7 @@
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="public/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">

<script>
/* to prevent Firefox FOUC, this must be here */
let FF_FOUC_FIX;
</script>
</head>

<body>
</body>
</html>
1 change: 1 addition & 0 deletions public/androidstudio.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions public/simple.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 3 additions & 7 deletions public/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ select:focus {
}

pre {
background: #333;
background: #282b2e;
white-space: pre;
word-wrap: break-word;
overflow: auto;
}

pre.code {
border-radius: 4px;
border: 1px solid #292929;
border: 1px solid #282b2e;
position: relative;
clear: both;
}
Expand Down Expand Up @@ -85,13 +85,9 @@ pre.code code {
color: #ddd;
}

pre.code-html code {
color: #aed581;
}

.pickers {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-columns: repeat(6, 1fr);
grid-column-gap: 0.5em;
column-gap: 0.5em;
}
Expand Down
27 changes: 27 additions & 0 deletions src/bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use serde::{Deserialize, Serialize};
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};

#[derive(Serialize, Deserialize)]
pub struct HighlightOptions {
pub language: String,
#[serde(rename(serialize = "ignoreIllegals"))]
pub ignore_illegals: bool,
}

#[wasm_bindgen(module = "https://unpkg.com/@highlightjs/cdn-assets@11.6.0/es/highlight.min.js")]
extern "C" {
#[wasm_bindgen(js_name = "default")]
pub type Hljs;

#[wasm_bindgen]
pub type HighlightResult;

#[wasm_bindgen(static_method_of = Hljs, js_name = "highlightAll", js_class = "default")]
pub fn highlight_all();

#[wasm_bindgen(method, getter)]
pub fn value(this: &HighlightResult) -> String;

#[wasm_bindgen(static_method_of = Hljs, js_class = "default")]
pub fn highlight(code: &str, options: &JsValue) -> HighlightResult;
}
172 changes: 108 additions & 64 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,92 @@
mod bindings;
mod code;
mod state;
use gloo_utils::format::JsValueSerdeExt;
use state::{BuildType, Platform, State, SDK};
use std::fmt;
use std::str::FromStr;
use strum::IntoEnumIterator;
use web_sys::HtmlSelectElement;
use wasm_bindgen::JsValue;
use web_sys::{HtmlElement, HtmlSelectElement};
use yew::prelude::*;
use yew::{events::InputEvent, html, Component, Context, Html};
use yew::{events::InputEvent, function_component, html, Component, Context, Html};
use yew_hooks::prelude::*;

#[function_component]
fn Header() -> Html {
html! {
<header>
<h1>{ "Cong" }<img src="public/controller.svg" class="logo" /></h1>
<p class="p-1">{ "quickly generate template CI workflow files for mobile apps" }</p>
</header>
}
}

#[function_component]
fn Footer() -> Html {
html! {
<footer>
<p>{ "Built in Rust " }<img src="/public/tram.svg" width="16" />{ " by " }<a href="https://tramline.app">{ "Tramline" }</a></p>
</footer>
}
}

#[derive(Properties, PartialEq)]
pub struct CopyToClipboardProps {
pub code: String,
}

#[function_component]
fn CopyToClipboardButton(props: &CopyToClipboardProps) -> Html {
let clipboard = use_clipboard();

let on_click = {
let code = props.code.clone();
let clipboard = clipboard.clone();

Callback::from(move |e: MouseEvent| {
e.prevent_default();
Some(clipboard.write_text(code.to_owned()));
})
};

html! {
<>
<button class="copy" onclick={on_click}>
<img src="/public/clipboard-text.svg" width="24" />
</button>
</>
}
}

#[derive(Properties, PartialEq)]
pub struct DisplaySnippetProps {
pub code: String,
}

#[function_component]
fn DisplaySnippet(props: &DisplaySnippetProps) -> Html {
let code_ref = use_node_ref();

let options = bindings::HighlightOptions {
language: "yaml".to_string(),
ignore_illegals: true,
};

let highlighted: bindings::HighlightResult =
bindings::Hljs::highlight(&props.code.clone(), &JsValue::from_serde(&options).unwrap());

if let Some(code_el) = code_ref.cast::<HtmlElement>() {
code_el.set_inner_html(&highlighted.value());
}

html! {
<pre class="code"><label>{ "YAML" }</label><code ref={code_ref}></code></pre>
}
}

enum Msg {
Generate,
CopyToClipboard,
UpdatePlatform(String),
UpdateSDK(String),
UpdateBuildType(String),
Expand Down Expand Up @@ -39,65 +116,24 @@ impl Component for App {
Msg::Generate => {
self.state.code =
code::generate(self.state.platform, self.state.sdk, self.state.build_type);
true
}
Msg::CopyToClipboard => {
let window = web_sys::window().expect("Missing Window!");
window
.navigator()
.clipboard()
.expect("Missing Clipboard!")
.write_text(&self.state.code);
true
}
Msg::UpdatePlatform(selected) => {
self.state.platform = Platform::from_str(&selected).unwrap();
true
}
Msg::UpdateSDK(selected) => {
self.state.sdk = SDK::from_str(&selected).unwrap();
true
}
Msg::UpdateBuildType(selected) => {
self.state.build_type = BuildType::from_str(&selected).unwrap();
true
}
}

true
}

fn view(&self, ctx: &Context<Self>) -> Html {
let link = ctx.link();

let _platform_options = Platform::iter().map(|platform| {
let is_selected = platform == self.state.platform;

html! {
<option selected={is_selected} value={ platform.to_string() }>
{ platform.to_string() }
</option>
}
});

let _sdk_options = SDK::iter().map(|sdk| {
let is_selected = sdk == self.state.sdk;

html! {
<option selected={is_selected} value={ sdk.to_string() }>
{ sdk.to_string() }
</option>
}
});

let _build_type_options = BuildType::iter().map(|build_type| {
let is_selected = build_type == self.state.build_type;

html! {
<option selected={is_selected} value={ build_type.to_string() }>
{ build_type.to_string() }
</option>
}
});

let _on_platform_change = link.batch_callback(|e: InputEvent| {
e.prevent_default();
let input: HtmlSelectElement = e.target_unchecked_into();
Expand All @@ -118,35 +154,43 @@ impl Component for App {

html! {
<>
<header>
<h1>{ "Cong" }<img src="public/controller.svg" class="logo" /></h1>
<p class="p-1">{ "quickly generate template CI workflow files for mobile apps" }</p>
</header>
<Header />

<main>
<div class="pickers">
<select oninput={_on_platform_change} value={ self.state.platform.to_string() }>{ for _platform_options }</select>
<select class="picker-wide" oninput={_on_sdk_change} value={ self.state.sdk.to_string() }>{ for _sdk_options }</select>
<select class="picker-wide" oninput={_on_build_type_change} value={ self.state.build_type.to_string() }>{ for _build_type_options }</select>
</div>

<div class="pickers">
<select class="picker-wide" oninput={_on_platform_change} value={ self.state.platform.to_string() }>{ for self.to_options(self.state.platform) }</select>
<select class="picker-wide" oninput={_on_sdk_change} value={ self.state.sdk.to_string() }>{ for self.to_options(self.state.sdk) }</select>
<select class="picker-wide" oninput={_on_build_type_change} value={ self.state.build_type.to_string() }>{ for self.to_options(self.state.build_type) }</select>
</div>
<div><button class="cta" onclick={link.callback(|_| Msg::Generate)}>{ "Can I have it?" }</button></div>

<div>
<button class="copy hint--top" data-hint="Copied!" onclick={link.callback(|_| Msg::CopyToClipboard)}>
<img src="/public/clipboard-text.svg" width="24" />
</button>
<pre class="code code-html"><label>{ "YAML" }</label><code>{ self.state.code.to_string() }</code></pre>
</div>
<div><CopyToClipboardButton code={self.state.code.to_string()} /><DisplaySnippet code={ self.state.code.to_string() } /></div>
</main>

<footer><p>{ "Built with Rust " }<img src="/public/tram.svg" width="16" />{ " by " }<a href="https://tramline.app">{ "Tramline" }</a></p></footer>
<Footer />
</>
}
}
}

impl App {
fn to_options<E: fmt::Display + Eq + IntoEnumIterator>(
&self,
cur: E,
) -> impl Iterator<Item = Html> {
E::iter().map(move |val| {
let is_selected = val == cur;

html! {
<option selected={is_selected} value={ val.to_string() }>
{ val.to_string() }
</option>
}
})
}
}

fn main() {
wasm_logger::init(wasm_logger::Config::default());
yew::start_app::<App>();
yew::Renderer::<App>::new().render();
}
6 changes: 3 additions & 3 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct State {
Clone, Copy, Debug, EnumIter, EnumString, Display, PartialEq, Serialize, Deserialize, Eq,
)]
pub enum Platform {
#[strum(serialize = "GitHub")]
#[strum(serialize = "GitHub Actions")]
GitHub,
}

Expand All @@ -33,8 +33,8 @@ pub enum SDK {
Clone, Copy, Debug, EnumIter, EnumString, Display, PartialEq, Serialize, Deserialize, Eq,
)]
pub enum BuildType {
#[strum(serialize = "Debug Build (unsigned)")]
#[strum(serialize = "Debug (unsigned)")]
Unsigned,
#[strum(serialize = "Release Build (signed)")]
#[strum(serialize = "Release (signed)")]
Signed,
}

0 comments on commit 9988e6a

Please sign in to comment.