add: markdown emoji parsing

This commit is contained in:
trisua 2025-05-05 23:12:46 -04:00
parent d9234bf656
commit af67077ae7
8 changed files with 243 additions and 46 deletions

View file

@ -5,7 +5,7 @@ mod routes;
mod sanitize;
use assets::{init_dirs, write_assets};
use tetratto_core::model::permissions::FinePermission;
use tetratto_core::model::{permissions::FinePermission, uploads::CustomEmoji};
pub use tetratto_core::*;
use axum::{Extension, Router};
@ -24,7 +24,12 @@ use tokio::sync::RwLock;
pub(crate) type State = Arc<RwLock<(DataManager, Tera, Client)>>;
fn render_markdown(value: &Value, _: &HashMap<String, Value>) -> tera::Result<Value> {
Ok(tetratto_shared::markdown::render_markdown(value.as_str().unwrap()).into())
Ok(
CustomEmoji::replace(&tetratto_shared::markdown::render_markdown(
value.as_str().unwrap(),
))
.into(),
)
}
fn color_escape(value: &Value, _: &HashMap<String, Value>) -> tera::Result<Value> {

View file

@ -61,9 +61,14 @@
></textarea>
</div>
<button class="primary">
{{ text "communities:action.create" }}
</button>
<div class="flex gap-2">
{{ components::emoji_picker(element_id="content",
render_dialog=true) }}
<button class="primary">
{{ text "communities:action.create" }}
</button>
</div>
</form>
</div>

View file

@ -1112,4 +1112,75 @@ secondary=false) -%}
</div>
{% endif %}
</div>
{%- endmacro %}
{%- endmacro %} {% macro emoji_picker(element_id, render_dialog=false) -%}
<button
class="button small square quaternary"
onclick="window.EMOJI_PICKER_TEXT_ID = '{{ element_id }}'; document.getElementById('emoji_dialog').showModal()"
title="Emojis"
type="button"
>
{{ icon "smile-plus" }}
</button>
{% if render_dialog %}
<dialog id="emoji_dialog">
<div class="inner flex flex-col gap-2">
<script
type="module"
src="https://unpkg.com/emoji-picker-element@1.22.8/index.js"
></script>
<emoji-picker
style="
--border-radius: var(--radius);
--background: var(--color-super-raised);
--input-border-radiFus: var(--radius);
--input-border-color: var(--color-primary);
--indicator-color: var(--color-primary);
--emoji-padding: 0.25rem;
box-shadow: 0 0 4px var(--color-shadow);
"
class="w-full"
></emoji-picker>
<script>
document
.querySelector("emoji-picker")
.addEventListener("emoji-click", (event) => {
function gemoji() {
const use_first_shortcode = ["grinning squinting face"];
if (
use_first_shortcode.includes(
event.detail.emoji.annotation,
)
) {
return event.detail.emoji.shortcodes[0];
}
return event.detail.emoji.shortcodes[1];
}
document.getElementById(
window.EMOJI_PICKER_TEXT_ID,
).value += ` :${gemoji()}:`;
document.getElementById("emoji_dialog").close();
});
</script>
<div class="flex justify-between">
<div></div>
<div class="flex gap-2">
<button
class="bold red quaternary"
onclick="document.getElementById('emoji_dialog').close()"
type="button"
>
{{ icon "x" }} {{ text "dialog:action.close" }}
</button>
</div>
</div>
</div>
</dialog>
{% endif %} {%- endmacro %}

View file

@ -43,9 +43,14 @@
></textarea>
</div>
<button class="primary">
{{ text "communities:action.create" }}
</button>
<div class="flex gap-2">
{{ components::emoji_picker(element_id="content",
render_dialog=true) }}
<button class="primary">
{{ text "communities:action.create" }}
</button>
</div>
</form>
</div>
{% endif %}
@ -198,8 +203,8 @@
>
<textarea
type="text"
name="content"
id="content"
name="new_content"
id="new_content"
placeholder="content"
required
minlength="2"
@ -209,7 +214,14 @@
>
</div>
<button class="primary">{{ text "general:action.save" }}</button>
<div class="flex gap-2">
{{ components::emoji_picker(element_id="new_content",
render_dialog=false) }}
<button class="primary">
{{ text "general:action.save" }}
</button>
</div>
</form>
</div>
@ -223,7 +235,7 @@
"Content-Type": "application/json",
},
body: JSON.stringify({
content: e.target.content.value,
content: e.target.new_content.value,
}),
})
.then((res) => res.json())