use std::{ops::Deref, rc::Rc}; use anyhow::Error; use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; use web_sys::{window, Node}; use yew::{ function_component, html, use_effect_with, use_node_ref, use_state_eq, AttrValue, Callback, Html, Properties, UseStateHandle, }; use crate::{FrameId, GlobalLayoutState, GlobalMemoCell, PanelDirection, SplitPanel}; #[derive(Properties, PartialEq, Clone)] pub struct EditorViewProps { pub frame: FrameId, pub global_memo: GlobalMemoCell, pub global_layout: UseStateHandle>, } fn close_editor(frame: &FrameId, global_layout: &UseStateHandle>) { let mut gl_new: GlobalLayoutState = global_layout.as_ref().clone(); gl_new.frame_views.remove(frame); global_layout.set(gl_new.into()); } #[derive(PartialEq, Clone)] pub struct EditorState { error_msg: Option, available_files: Vec, } fn fetch_initial_editor_state_or_fail() -> anyhow::Result { let win = window().ok_or_else(|| Error::msg("Can't get window"))?; win.local_storage() .map_err(|_| Error::msg("Error retrieving localStorage"))? .ok_or_else(|| Error::msg("Local storage not available"))?; Ok(EditorState { error_msg: None, available_files: vec![], }) } fn fetch_initial_editor_state() -> EditorState { match fetch_initial_editor_state_or_fail() { Ok(s) => s, Err(e) => EditorState { error_msg: Some(format!("Can't load editor data: {}", e.to_string()).into()), available_files: vec![], }, } } #[function_component(EditorNav)] fn editor_nav(props: &EditorViewProps) -> Html { let global_layout = props.global_layout.clone(); let frame = props.frame.clone(); html! {
} } #[wasm_bindgen(getter_with_clone)] struct EditorViewConfig { pub doc: String, pub extensions: Vec, pub parent: Node, } #[wasm_bindgen(module = codemirror)] extern "C" { type EditorView; #[derive(Clone)] type CMExtension; #[wasm_bindgen(constructor)] fn new(settings: EditorViewConfig) -> EditorView; #[wasm_bindgen(js_name = basicSetup, thread_local)] static BASIC_SETUP: CMExtension; } #[wasm_bindgen(module = "@codemirror/legacy-modes/mode/lua")] extern "C" { #[wasm_bindgen(js_name = lua, thread_local)] static LUA: StreamLanguage; } #[wasm_bindgen(module = "@codemirror/language")] extern "C" { #[derive(Clone)] type StreamLanguage; #[wasm_bindgen(js_namespace = StreamLanguage, js_name = define)] fn streamlanguage_define(input: StreamLanguage) -> CMExtension; } #[function_component(EditorArea)] fn editor_area(props: &EditorViewProps) -> Html { let node_ref = use_node_ref(); use_effect_with(node_ref.clone(), |node_ref| match node_ref.get() { None => {} Some(node) => { EditorView::new(EditorViewConfig { doc: "Hello World".to_owned(), extensions: vec![ BASIC_SETUP.with(CMExtension::clone), StreamLanguage::streamlanguage_define(LUA.with(StreamLanguage::clone)), ], parent: node, }); } }); html! {
} } #[derive(Properties, PartialEq, Clone)] pub struct ErrorBarProps { pub msg: AttrValue, pub dismiss: Callback<()>, } #[function_component(ErrorBar)] fn error_bar(props: &ErrorBarProps) -> Html { let props = props.clone(); html! { } } #[function_component(CodeEditorView)] pub fn editor_view(props: &EditorViewProps) -> Html { let editor_state: UseStateHandle = use_state_eq(fetch_initial_editor_state); html! { <> {match editor_state.error_msg.as_ref() { None => { html! { <> }} Some(msg) => html! { } }} }} second={html!{}} /> } }