From fe7edb93adcf877761d6da6f2fa9da23be989adb Mon Sep 17 00:00:00 2001 From: Bad Manners Date: Wed, 9 Apr 2025 20:33:26 -0300 Subject: [PATCH] Edit tags in the middle of input --- Cargo.toml | 2 +- README.md | 2 -- src/lib.rs | 2 +- src/views.rs | 34 +++++++++++++++++++++++++++------- templates/index.html | 3 ++- templates/posts.html | 7 ++++--- templates/search_tags.html | 3 ++- templates/select_tag.html | 6 ++++-- templates/view_post.html | 2 +- 9 files changed, 42 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d1402b6..069801b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" members = [".", "migration"] [dependencies] -askama = "0.13.0" +askama = { version = "0.13.0", features = ["serde_json"] } async-trait = "0.1.88" axum = { version = "0.8.3", features = ["multipart", "macros"] } axum-extra = { version = "0.10.1", features = ["form"] } diff --git a/README.md b/README.md index 0e06eeb..aee8c30 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ Sam's small image board. Currently a WIP. ## TODO -- [ ] Parent posts (including tags and stuff) -- [ ] Edit tags in the middle of input - [ ] Pools - [ ] Video support - [ ] Cleanup/fixup background tasks diff --git a/src/lib.rs b/src/lib.rs index a73bcb5..4c73604 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,7 +74,7 @@ pub async fn get_router(db: DatabaseConnection, files_dir: &str) -> Result, + selection_end: usize, } #[derive(Debug, Deserialize)] pub(crate) struct SearchTagsForm { tags: String, + selection_end: usize, } pub(crate) async fn search_tags( State(AppState { db, .. }): State, Form(body): Form, ) -> Result { - let tags = match body.tags.split(' ').last() { - Some(tag) => { - if tag.starts_with(NEGATIVE_PREFIX) { + let tags = match body.tags[..body.selection_end].split(' ').last() { + Some(mut tag) => { + tag = tag.trim(); + if tag.is_empty() { + vec![] + } else if tag.starts_with(NEGATIVE_PREFIX) { if tag[NEGATIVE_PREFIX.len()..].starts_with(RATING_PREFIX) { [ format!("{}u", RATING_PREFIX), @@ -269,6 +274,7 @@ pub(crate) async fn search_tags( "LOWER(\"samey_tag\".\"name\") LIKE CONCAT(?, '%')", tag[NEGATIVE_PREFIX.len()..].to_lowercase(), )) + .limit(10) .all(&db) .await? .into_iter() @@ -298,6 +304,7 @@ pub(crate) async fn search_tags( "LOWER(\"samey_tag\".\"name\") LIKE CONCAT(?, '%')", tag.to_lowercase(), )) + .limit(10) .all(&db) .await? .into_iter() @@ -310,7 +317,13 @@ pub(crate) async fn search_tags( } _ => vec![], }; - Ok(Html(SearchTagsTemplate { tags }.render()?)) + Ok(Html( + SearchTagsTemplate { + tags, + selection_end: body.selection_end, + } + .render()?, + )) } #[derive(Template)] @@ -322,14 +335,15 @@ struct SelectTagTemplate { #[derive(Debug, Deserialize)] pub(crate) struct SelectTagForm { tags: String, + new_tag: String, + selection_end: usize, } pub(crate) async fn select_tag( - Path(new_tag): Path, Form(body): Form, ) -> Result { let mut tags = String::new(); - for (tag, _) in body.tags.split_whitespace().tuple_windows() { + for (tag, _) in body.tags[..body.selection_end].split(' ').tuple_windows() { if !tags.is_empty() { tags.push(' '); } @@ -338,7 +352,13 @@ pub(crate) async fn select_tag( if !tags.is_empty() { tags.push(' '); } - tags.push_str(&new_tag); + tags.push_str(&body.new_tag); + for tag in body.tags[body.selection_end..].split(' ') { + if !tags.is_empty() { + tags.push(' '); + } + tags.push_str(tag); + } tags.push(' '); Ok(Html(SelectTagTemplate { tags }.render()?)) } diff --git a/templates/index.html b/templates/index.html index f2f5649..0e60297 100644 --- a/templates/index.html +++ b/templates/index.html @@ -17,8 +17,9 @@ id="search-tags" name="tags" hx-post="/search_tags" - hx-trigger="input changed delay:400ms" + hx-trigger="input changed" hx-target="next .tags-autocomplete" + hx-vals="js:{selection_end: event.target.selectionEnd}" hx-on::after-settle="this.focus(); this.setSelectionRange(-1, -1);" autofocus /> diff --git a/templates/posts.html b/templates/posts.html index 150070e..f35e07e 100644 --- a/templates/posts.html +++ b/templates/posts.html @@ -16,10 +16,11 @@ id="search-tags" name="tags" hx-post="/search_tags" - hx-trigger="input changed delay:400ms" + hx-trigger="input changed" hx-target="next .tags-autocomplete" + hx-vals="js:{selection_end: event.target.selectionEnd}" hx-on::after-settle="this.focus(); this.setSelectionRange(-1, -1);" - value="{% if let Some(tags_text) = tags_text %}{{ tags_text }}{% endif %}" + autofocus />
    @@ -46,7 +47,7 @@ title="{{ post.tags }}" > -
    {{ post.rating }}
    +
    {{ post.rating | upper }}
    {% endfor %} diff --git a/templates/search_tags.html b/templates/search_tags.html index 79f4b63..c01593f 100644 --- a/templates/search_tags.html +++ b/templates/search_tags.html @@ -1,9 +1,10 @@ {% for tag in tags %}
  • diff --git a/templates/select_tag.html b/templates/select_tag.html index 721012b..d3fbaee 100644 --- a/templates/select_tag.html +++ b/templates/select_tag.html @@ -1,12 +1,14 @@
      diff --git a/templates/view_post.html b/templates/view_post.html index 720ad0c..7a2a934 100644 --- a/templates/view_post.html +++ b/templates/view_post.html @@ -52,7 +52,7 @@
    • -
      {{ child_post.rating }}
      +
      {{ child_post.rating | upper }}
    • {% endfor %}