Editor improvements (#486)
- Make it possible to insert new paragraphs in the article body - Make it impossible to copy formatted HTML (to make media insertion from markdown code work correctly) TODO: - [x] make it possible to escape draft mode - [x] display errors from the server - [x] button to go back to the "normal" editor - [x] Avoid publishing placeholders
This commit is contained in:
parent
38701c8a40
commit
1f7ff62c19
@ -84,10 +84,46 @@ fn init_widget(
|
|||||||
widget.focus();
|
widget.focus();
|
||||||
widget.blur();
|
widget.blur();
|
||||||
|
|
||||||
|
filter_paste(&widget);
|
||||||
|
|
||||||
Ok(widget)
|
Ok(widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn filter_paste(elt: &HtmlElement) {
|
||||||
|
// Only insert text when pasting something
|
||||||
|
js! {
|
||||||
|
@{&elt}.addEventListener("paste", function (evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
document.execCommand("insertText", false, evt.clipboardData.getData("text"));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init() -> Result<(), EditorError> {
|
pub fn init() -> Result<(), EditorError> {
|
||||||
|
// Check if the user wants to use the basic editor
|
||||||
|
if let Some(basic_editor) = window().local_storage().get("basic-editor") {
|
||||||
|
if basic_editor == "true" {
|
||||||
|
if let Some(editor) = document().get_element_by_id("plume-fallback-editor") {
|
||||||
|
if let Ok(Some(title_label)) = document().query_selector("label[for=title]") {
|
||||||
|
let editor_button = document().create_element("a")?;
|
||||||
|
js!{ @{&editor_button}.href = "#"; }
|
||||||
|
editor_button.add_event_listener(|_: ClickEvent| {
|
||||||
|
window().local_storage().remove("basic-editor");
|
||||||
|
window().history().go(0).ok(); // refresh
|
||||||
|
});
|
||||||
|
editor_button.append_child(&document().create_text_node(&i18n!(CATALOG, "Open the rich text editor")));
|
||||||
|
editor.insert_before(&editor_button, &title_label).ok();
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't returned above
|
||||||
|
init_editor()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_editor() -> Result<(), EditorError> {
|
||||||
if let Some(ed) = document().get_element_by_id("plume-editor") {
|
if let Some(ed) = document().get_element_by_id("plume-editor") {
|
||||||
// Show the editor
|
// Show the editor
|
||||||
js! { @{&ed}.style.display = "block"; };
|
js! { @{&ed}.style.display = "block"; };
|
||||||
@ -117,7 +153,7 @@ pub fn init() -> Result<(), EditorError> {
|
|||||||
"article",
|
"article",
|
||||||
i18n!(CATALOG, "Write your article here. Markdown is supported."),
|
i18n!(CATALOG, "Write your article here. Markdown is supported."),
|
||||||
content_val.clone(),
|
content_val.clone(),
|
||||||
true,
|
false,
|
||||||
)?;
|
)?;
|
||||||
js! { @{&content}.innerHTML = @{content_val}; };
|
js! { @{&content}.innerHTML = @{content_val}; };
|
||||||
|
|
||||||
@ -134,8 +170,7 @@ pub fn init() -> Result<(), EditorError> {
|
|||||||
}), 0);
|
}), 0);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
document().get_element_by_id("publish")?.add_event_listener(
|
document().get_element_by_id("publish")?.add_event_listener(mv!(title, subtitle, content, old_ed => move |_: ClickEvent| {
|
||||||
mv!(title, subtitle, content, old_ed => move |_: ClickEvent| {
|
|
||||||
let popup = document().get_element_by_id("publish-popup").or_else(||
|
let popup = document().get_element_by_id("publish-popup").or_else(||
|
||||||
init_popup(&title, &subtitle, &content, &old_ed).ok()
|
init_popup(&title, &subtitle, &content, &old_ed).ok()
|
||||||
).unwrap();
|
).unwrap();
|
||||||
@ -145,12 +180,35 @@ pub fn init() -> Result<(), EditorError> {
|
|||||||
|
|
||||||
popup.class_list().add("show").unwrap();
|
popup.class_list().add("show").unwrap();
|
||||||
bg.class_list().add("show").unwrap();
|
bg.class_list().add("show").unwrap();
|
||||||
}),
|
}));
|
||||||
);
|
|
||||||
|
show_errors();
|
||||||
|
setup_close_button();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup_close_button() {
|
||||||
|
if let Some(button) = document().get_element_by_id("close-editor") {
|
||||||
|
button.add_event_listener(|_: ClickEvent| {
|
||||||
|
window().local_storage().insert("basic-editor", "true").unwrap();
|
||||||
|
window().history().go(0).unwrap(); // Refresh the page
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_errors() {
|
||||||
|
if let Ok(Some(header)) = document().query_selector("header") {
|
||||||
|
let list = document().create_element("header").unwrap();
|
||||||
|
list.class_list().add("messages").unwrap();
|
||||||
|
for error in document().query_selector_all("p.error").unwrap() {
|
||||||
|
error.parent_element().unwrap().remove_child(&error).unwrap();
|
||||||
|
list.append_child(&error);
|
||||||
|
}
|
||||||
|
header.parent_element().unwrap().insert_before(&list, &header.next_sibling().unwrap()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn init_popup(
|
fn init_popup(
|
||||||
title: &HtmlElement,
|
title: &HtmlElement,
|
||||||
subtitle: &HtmlElement,
|
subtitle: &HtmlElement,
|
||||||
@ -178,6 +236,23 @@ fn init_popup(
|
|||||||
popup.append_child(&cover_label);
|
popup.append_child(&cover_label);
|
||||||
popup.append_child(&cover);
|
popup.append_child(&cover);
|
||||||
|
|
||||||
|
if let Some(draft_checkbox) = document().get_element_by_id("draft") {
|
||||||
|
let draft_label = document().create_element("label")?;
|
||||||
|
draft_label.set_attribute("for", "popup-draft")?;
|
||||||
|
|
||||||
|
let draft = document().create_element("input").unwrap();
|
||||||
|
js!{
|
||||||
|
@{&draft}.id = "popup-draft";
|
||||||
|
@{&draft}.name = "popup-draft";
|
||||||
|
@{&draft}.type = "checkbox";
|
||||||
|
@{&draft}.checked = @{&draft_checkbox}.checked;
|
||||||
|
};
|
||||||
|
|
||||||
|
draft_label.append_child(&draft);
|
||||||
|
draft_label.append_child(&document().create_text_node(&i18n!(CATALOG, "This is a draft")));
|
||||||
|
popup.append_child(&draft_label);
|
||||||
|
}
|
||||||
|
|
||||||
let button = document().create_element("input")?;
|
let button = document().create_element("input")?;
|
||||||
js! {
|
js! {
|
||||||
@{&button}.type = "submit";
|
@{&button}.type = "submit";
|
||||||
@ -185,10 +260,31 @@ fn init_popup(
|
|||||||
};
|
};
|
||||||
button.append_child(&document().create_text_node(&i18n!(CATALOG, "Publish")));
|
button.append_child(&document().create_text_node(&i18n!(CATALOG, "Publish")));
|
||||||
button.add_event_listener(mv!(title, subtitle, content, old_ed => move |_: ClickEvent| {
|
button.add_event_listener(mv!(title, subtitle, content, old_ed => move |_: ClickEvent| {
|
||||||
|
title.focus(); // Remove the placeholder before publishing
|
||||||
set_value("title", title.inner_text());
|
set_value("title", title.inner_text());
|
||||||
|
subtitle.focus();
|
||||||
set_value("subtitle", subtitle.inner_text());
|
set_value("subtitle", subtitle.inner_text());
|
||||||
set_value("editor-content", js!{ return @{&content}.innerHTML }.as_str().unwrap_or_default());
|
content.focus();
|
||||||
|
set_value("editor-content", content.child_nodes().iter().fold(String::new(), |md, ch| {
|
||||||
|
let to_append = match ch.node_type() {
|
||||||
|
NodeType::Element => {
|
||||||
|
if js!{ return @{&ch}.tagName; } == "DIV" {
|
||||||
|
(js!{ return @{&ch}.innerHTML; }).try_into().unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
(js!{ return @{&ch}.outerHTML; }).try_into().unwrap_or_default()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
NodeType::Text => ch.node_value().unwrap_or_default(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
format!("{}\n\n{}", md, to_append)
|
||||||
|
}));
|
||||||
set_value("tags", get_elt_value("popup-tags"));
|
set_value("tags", get_elt_value("popup-tags"));
|
||||||
|
if let Some(draft) = document().get_element_by_id("popup-draft") {
|
||||||
|
js!{
|
||||||
|
document.getElementById("draft").checked = @{draft}.checked;
|
||||||
|
};
|
||||||
|
}
|
||||||
let cover = document().get_element_by_id("cover").unwrap();
|
let cover = document().get_element_by_id("cover").unwrap();
|
||||||
cover.parent_element().unwrap().remove_child(&cover).ok();
|
cover.parent_element().unwrap().remove_child(&cover).ok();
|
||||||
old_ed.append_child(&cover);
|
old_ed.append_child(&cover);
|
||||||
|
@ -12,6 +12,10 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:110
|
||||||
|
msgid "Open the rich text editor"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:57
|
# plume-front/src/editor.rs:57
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Title"
|
msgstr "Title"
|
||||||
@ -40,6 +44,10 @@ msgstr ""
|
|||||||
msgid "Cover"
|
msgid "Cover"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:167
|
||||||
|
msgid "This is a draft"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:111
|
# plume-front/src/editor.rs:111
|
||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -12,6 +12,10 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:110
|
||||||
|
msgid "Open the rich text editor"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:57
|
# plume-front/src/editor.rs:57
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titre"
|
msgstr "Titre"
|
||||||
@ -40,6 +44,10 @@ msgstr ""
|
|||||||
msgid "Cover"
|
msgid "Cover"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:167
|
||||||
|
msgid "This is a draft"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:111
|
# plume-front/src/editor.rs:111
|
||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Publier"
|
msgstr "Publier"
|
||||||
|
@ -12,34 +12,42 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||||
|
|
||||||
# plume-front/src/editor.rs:103
|
# plume-front/src/editor.rs:114
|
||||||
msgid "Title"
|
msgid "Open the rich text editor"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# plume-front/src/editor.rs:104
|
|
||||||
msgid "Subtitle or summary"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# plume-front/src/editor.rs:105
|
|
||||||
msgid "Write your article here. Markdown is supported."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# plume-front/src/editor.rs:113
|
|
||||||
msgid "Around {} characters left"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:143
|
# plume-front/src/editor.rs:143
|
||||||
msgid "Tags"
|
msgid "Title"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
# plume-front/src/editor.rs:144
|
|
||||||
msgid "License"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:147
|
# plume-front/src/editor.rs:147
|
||||||
|
msgid "Subtitle or summary"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:154
|
||||||
|
msgid "Write your article here. Markdown is supported."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:165
|
||||||
|
msgid "Around {} characters left"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:228
|
||||||
|
msgid "Tags"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:229
|
||||||
|
msgid "License"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:232
|
||||||
msgid "Cover"
|
msgid "Cover"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:157
|
# plume-front/src/editor.rs:252
|
||||||
|
msgid "This is a draft"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:259
|
||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -568,6 +568,9 @@ msgstr "اسم المستخدم أو عنوان البريد الالكترون
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "انشر"
|
msgstr "انشر"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "العنوان الثانوي"
|
msgstr "العنوان الثانوي"
|
||||||
|
|
||||||
|
@ -571,6 +571,9 @@ msgstr "Nutzername oder E-Mail"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Veröffentlichen"
|
msgstr "Veröffentlichen"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "Untertitel"
|
msgstr "Untertitel"
|
||||||
|
|
||||||
|
@ -542,6 +542,9 @@ msgstr ""
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# src/template_utils.rs:144
|
# src/template_utils.rs:144
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -539,6 +539,9 @@ msgstr "Nombre de usuario o correo electrónico"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Publicar"
|
msgstr "Publicar"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -567,6 +567,9 @@ msgstr "Nom d’utilisateur ou adresse électronique"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Publier"
|
msgstr "Publier"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "Sous-titre"
|
msgstr "Sous-titre"
|
||||||
|
|
||||||
|
@ -567,6 +567,9 @@ msgstr "Usuaria ou correo-e"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Publicar"
|
msgstr "Publicar"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "Subtítulo"
|
msgstr "Subtítulo"
|
||||||
|
|
||||||
|
@ -570,6 +570,9 @@ msgstr "Nome utente o email"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Pubblica"
|
msgstr "Pubblica"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "Sottotitolo"
|
msgstr "Sottotitolo"
|
||||||
|
|
||||||
|
@ -574,6 +574,9 @@ msgstr "ユーザー名またはメールアドレス"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "公開"
|
msgstr "公開"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "サブタイトル"
|
msgstr "サブタイトル"
|
||||||
|
|
||||||
|
@ -594,6 +594,9 @@ msgstr "Brukernavn eller epost"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "Tittel"
|
msgstr "Tittel"
|
||||||
|
@ -549,6 +549,9 @@ msgstr "Nazwa użytkownika lub adres e-mail"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Opublikuj"
|
msgstr "Opublikuj"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "Podtytuł"
|
msgstr "Podtytuł"
|
||||||
|
|
||||||
|
@ -532,6 +532,9 @@ msgstr ""
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# src/template_utils.rs:217
|
# src/template_utils.rs:217
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -568,6 +568,9 @@ msgstr "Nome de usuário ou e-mail"
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Publicar"
|
msgstr "Publicar"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "Subtítulo"
|
msgstr "Subtítulo"
|
||||||
|
|
||||||
|
@ -574,6 +574,9 @@ msgstr "Имя пользователя или адрес электронной
|
|||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr "Опубликовать"
|
msgstr "Опубликовать"
|
||||||
|
|
||||||
|
msgid "Classic editor (any changes will be lost)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Subtitle"
|
msgid "Subtitle"
|
||||||
msgstr "Подзаголовок"
|
msgstr "Подзаголовок"
|
||||||
|
|
||||||
|
@ -273,6 +273,7 @@ main .article-meta {
|
|||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
button {
|
button {
|
||||||
flex: 0 0 10em;
|
flex: 0 0 10em;
|
||||||
font-size: 1.25em;
|
font-size: 1.25em;
|
||||||
|
@ -74,6 +74,19 @@ header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.messages {
|
||||||
|
& > * {
|
||||||
|
padding: 1em 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.error {
|
||||||
|
color: $red;
|
||||||
|
background: lighten($red, 40%);
|
||||||
|
margin: 0;
|
||||||
|
max-width: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only enable label animations on normal screens
|
// Only enable label animations on normal screens
|
||||||
@media screen and (min-width: 900px) {
|
@media screen and (min-width: 900px) {
|
||||||
header nav a {
|
header nav a {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<header>
|
<header>
|
||||||
<button id="publish" class="button">@i18n!(ctx.1, "Publish")</button>
|
<button id="publish" class="button">@i18n!(ctx.1, "Publish")</button>
|
||||||
<p id="char-count">@content_len</p>
|
<p id="char-count">@content_len</p>
|
||||||
|
<a href="#" id="close-editor">@i18n!(ctx.1, "Classic editor (any changes will be lost)")</a>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
@if let Some(article) = article {
|
@if let Some(article) = article {
|
||||||
|
Loading…
Reference in New Issue
Block a user