1
0
Fork 0
mirror of https://github.com/Nutomic/ibis.git synced 2024-11-22 07:11:08 +00:00

Merge branch 'master' into tailwind-css

This commit is contained in:
Felix Ableitner 2024-10-30 11:33:30 +01:00
commit 52864a6e5c
6 changed files with 77 additions and 70 deletions

View file

@ -0,0 +1,42 @@
use crate::frontend::markdown::render_markdown;
use html::Textarea;
use leptos::*;
#[component]
pub fn EditorView(
// this param gives a false warning about being unused, ignore that
#[allow(unused)] textarea_ref: NodeRef<Textarea>,
content: Signal<String>,
set_content: WriteSignal<String>,
) -> impl IntoView {
let (preview, set_preview) = create_signal(render_markdown(&content.get()));
let (show_preview, set_show_preview) = create_signal(false);
view! {
<textarea
value=content
placeholder="Article text..."
class="textarea textarea-bordered textarea-primary min-w-full"
on:input=move |evt| {
let val = event_target_value(&evt);
set_preview.set(render_markdown(&val));
set_content.set(val);
}
node_ref=textarea_ref
>
{content.get()}
</textarea>
<button class="btn" on:click=move |_| { set_show_preview.update(|s| *s = !*s) }>
Preview
</button>
<Show when=move || { show_preview.get() }>
<div id="preview" inner_html=move || preview.get()></div>
</Show>
<div>
<a href="https://commonmark.org/help/" target="blank_">
Markdown
</a>
" formatting is supported"
</div>
}
}

View file

@ -1,4 +1,5 @@
pub mod article_nav; pub mod article_nav;
pub mod credentials; pub mod credentials;
pub mod editor;
pub mod instance_follow_button; pub mod instance_follow_button;
pub mod nav; pub mod nav;

View file

@ -15,7 +15,7 @@ pub fn hydrate() {
use crate::frontend::app::App; use crate::frontend::app::App;
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
leptos::mount_to_body(App); leptos::mount_to_body(App);
// set theme // set theme
// https://daisyui.com/docs/themes/ // https://daisyui.com/docs/themes/
let document = web_sys::window().unwrap().document().unwrap(); let document = web_sys::window().unwrap().document().unwrap();

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
common::CreateArticleForm, common::CreateArticleForm,
frontend::{app::GlobalState, markdown::render_markdown}, frontend::{app::GlobalState, components::editor::EditorView},
}; };
use html::Textarea; use html::Textarea;
use leptos::*; use leptos::*;
@ -10,15 +10,13 @@ use leptos_use::{use_textarea_autosize, UseTextareaAutosizeReturn};
#[component] #[component]
pub fn CreateArticle() -> impl IntoView { pub fn CreateArticle() -> impl IntoView {
let (title, set_title) = create_signal(String::new()); let (title, set_title) = create_signal(String::new());
let textarea = create_node_ref::<Textarea>(); let textarea_ref = create_node_ref::<Textarea>();
let UseTextareaAutosizeReturn { let UseTextareaAutosizeReturn {
content, content,
set_content, set_content,
trigger_resize: _, trigger_resize: _,
} = use_textarea_autosize(textarea); } = use_textarea_autosize(textarea_ref);
let (summary, set_summary) = create_signal(String::new()); let (summary, set_summary) = create_signal(String::new());
let (show_preview, set_show_preview) = create_signal(false);
let (preview, set_preview) = create_signal(String::new());
let (create_response, set_create_response) = create_signal(None::<()>); let (create_response, set_create_response) = create_signal(None::<()>);
let (create_error, set_create_error) = create_signal(None::<String>); let (create_error, set_create_error) = create_signal(None::<String>);
let (wait_for_response, set_wait_for_response) = create_signal(false); let (wait_for_response, set_wait_for_response) = create_signal(false);
@ -69,28 +67,8 @@ pub fn CreateArticle() -> impl IntoView {
} }
/> />
<textarea <EditorView textarea_ref content set_content />
value=content
placeholder="Article text..."
on:input=move |evt| {
let val = event_target_value(&evt);
set_preview.set(render_markdown(&val));
set_content.set(val);
}
node_ref=textarea
></textarea>
<button on:click=move |_| {
set_show_preview.update(|s| *s = !*s)
}>Preview</button>
<Show when=move || { show_preview.get() }>
<div id="preview" inner_html=move || preview.get()></div>
</Show>
<div>
<a href="https://commonmark.org/help/" target="blank_">
Markdown
</a>
" formatting is supported"
</div>
{move || { {move || {
create_error create_error
.get() .get()

View file

@ -2,8 +2,10 @@ use crate::{
common::{ApiConflict, ArticleView, EditArticleForm}, common::{ApiConflict, ArticleView, EditArticleForm},
frontend::{ frontend::{
app::GlobalState, app::GlobalState,
components::article_nav::{ActiveTab, ArticleNav}, components::{
markdown::render_markdown, article_nav::{ActiveTab, ArticleNav},
editor::EditorView,
},
pages::article_resource, pages::article_resource,
}, },
}; };
@ -27,7 +29,7 @@ pub fn EditArticle() -> impl IntoView {
let (edit_response, set_edit_response) = create_signal(EditResponse::None); let (edit_response, set_edit_response) = create_signal(EditResponse::None);
let (edit_error, set_edit_error) = create_signal(None::<String>); let (edit_error, set_edit_error) = create_signal(None::<String>);
let conflict_id = move || use_params_map().get().get("conflict_id").cloned(); let conflict_id = move || use_params_map().get_untracked().get("conflict_id").cloned();
if let Some(conflict_id) = conflict_id() { if let Some(conflict_id) = conflict_id() {
create_action(move |conflict_id: &String| { create_action(move |conflict_id: &String| {
let conflict_id: i32 = conflict_id.parse().unwrap(); let conflict_id: i32 = conflict_id.parse().unwrap();
@ -46,15 +48,13 @@ pub fn EditArticle() -> impl IntoView {
.dispatch(conflict_id); .dispatch(conflict_id);
} }
let textarea = create_node_ref::<Textarea>(); let textarea_ref = create_node_ref::<Textarea>();
let UseTextareaAutosizeReturn { let UseTextareaAutosizeReturn {
content, content,
set_content, set_content,
trigger_resize: _, trigger_resize: _,
} = use_textarea_autosize(textarea); } = use_textarea_autosize(textarea_ref);
let (summary, set_summary) = create_signal(String::new()); let (summary, set_summary) = create_signal(String::new());
let (show_preview, set_show_preview) = create_signal(false);
let (preview, set_preview) = create_signal(String::new());
let (wait_for_response, set_wait_for_response) = create_signal(false); let (wait_for_response, set_wait_for_response) = create_signal(false);
let button_is_disabled = let button_is_disabled =
Signal::derive(move || wait_for_response.get() || summary.get().is_empty()); Signal::derive(move || wait_for_response.get() || summary.get().is_empty());
@ -126,7 +126,6 @@ pub fn EditArticle() -> impl IntoView {
set_summary.set(conflict.summary); set_summary.set(conflict.summary);
} }
set_content.set(article.article.text.clone()); set_content.set(article.article.text.clone());
set_preview.set(render_markdown(&article.article.text));
let article_ = article.clone(); let article_ = article.clone();
view! { view! {
// set initial text, otherwise submit with no changes results in empty text // set initial text, otherwise submit with no changes results in empty text
@ -138,32 +137,9 @@ pub fn EditArticle() -> impl IntoView {
view! { <p style="color:red;">{err}</p> } view! { <p style="color:red;">{err}</p> }
}) })
}} }}
<textarea <EditorView textarea_ref content set_content />
value=content
id="edit-article-textarea" <div class="inputs">
class="textarea textarea-bordered textarea-primary min-w-full"
on:input=move |evt| {
let val = event_target_value(&evt);
set_preview.set(render_markdown(&val));
set_content.set(val);
}
node_ref=textarea
>
{article.article.text.clone()}
</textarea>
<button
class="btn"
on:click=move |_| { set_show_preview.update(|s| *s = !*s) }
>
Preview
</button> <Show when=move || { show_preview.get() }>
<div class="preview" inner_html=move || preview.get()></div>
</Show> <div>
<a href="https://commonmark.org/help/" target="blank_">
Markdown
</a>
" formatting is supported"
</div> <div class="inputs">
<input <input
type="text" type="text"
class="input input-secondary" class="input input-secondary"

View file

@ -23,20 +23,30 @@ pub fn ListArticles() -> impl IntoView {
view! { view! {
<h1 class="text-4xl font-bold font-serif my-4">Most recently edited Articles</h1> <h1 class="text-4xl font-bold font-serif my-4">Most recently edited Articles</h1>
<Suspense fallback=|| view! { "Loading..." }> <Suspense fallback=|| view! { "Loading..." }>
<fieldset <fieldset
class="flex flex-row" class="flex flex-row"
on:input=move |ev| { on:input=move |ev| {
let val = ev.target().unwrap().unchecked_into::<web_sys::HtmlInputElement>().id(); let val = ev
let is_local_only = val == "only-local"; .target()
set_only_local.update(|p| *p = is_local_only); .unwrap()
}> .unchecked_into::<web_sys::HtmlInputElement>()
.id();
let is_local_only = val == "only-local";
set_only_local.update(|p| *p = is_local_only);
}
>
<label class="label cursor-pointer max-w-32"> <label class="label cursor-pointer max-w-32">
<span>Only Local</span> <span>Only Local</span>
<input type="radio" name="listing-type" class="radio checked:bg-primary" /> <input type="radio" name="listing-type" class="radio checked:bg-primary" />
</label> </label>
<label class="label cursor-pointer max-w-32"> <label class="label cursor-pointer max-w-32">
<span>All</span> <span>All</span>
<input type="radio" name="listing-type" class="radio checked:bg-primary" checked="checked" /> <input
type="radio"
name="listing-type"
class="radio checked:bg-primary"
checked="checked"
/>
</label> </label>
</fieldset> </fieldset>
<ul class="list-disc"> <ul class="list-disc">