mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 13:21:09 +00:00
Merge branch 'master' into tailwind-css
This commit is contained in:
commit
52864a6e5c
6 changed files with 77 additions and 70 deletions
42
src/frontend/components/editor.rs
Normal file
42
src/frontend/components/editor.rs
Normal 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>
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -26,17 +26,27 @@ pub fn ListArticles() -> impl IntoView {
|
||||||
<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
|
||||||
|
.target()
|
||||||
|
.unwrap()
|
||||||
|
.unchecked_into::<web_sys::HtmlInputElement>()
|
||||||
|
.id();
|
||||||
let is_local_only = val == "only-local";
|
let is_local_only = val == "only-local";
|
||||||
set_only_local.update(|p| *p = is_local_only);
|
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">
|
||||||
|
|
Loading…
Reference in a new issue