Bug fixes
This commit is contained in:
parent
7f533cc583
commit
bb118f6144
11 changed files with 123 additions and 82 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
|
@ -1356,6 +1356,25 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "h2"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-waker",
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"http",
|
||||||
|
"indexmap",
|
||||||
|
"slab",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "half"
|
name = "half"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
|
|
@ -1507,6 +1526,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"h2",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ members = [".", "migration"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
askama = { version = "0.13.0", features = ["serde_json"] }
|
askama = { version = "0.13.0", features = ["serde_json"] }
|
||||||
async-trait = "0.1.88"
|
async-trait = "0.1.88"
|
||||||
axum = { version = "0.8.3", features = ["multipart", "macros"] }
|
axum = { version = "0.8.3", features = ["http2", "multipart", "macros"] }
|
||||||
axum-extra = { version = "0.10.1", features = ["form"] }
|
axum-extra = { version = "0.10.1", features = ["form"] }
|
||||||
axum-login = "0.17.0"
|
axum-login = "0.17.0"
|
||||||
chrono = "0.4.40"
|
chrono = "0.4.40"
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,18 @@ Sam's small image board.
|
||||||
|
|
||||||
Still very much an early WIP.
|
Still very much an early WIP.
|
||||||
|
|
||||||
|
### Known issues
|
||||||
|
|
||||||
|
- [ ] No way to close tag autocompletion on mobile
|
||||||
|
|
||||||
### Roadmap
|
### Roadmap
|
||||||
|
|
||||||
|
- [ ] Favicon from post
|
||||||
- [ ] Logging
|
- [ ] Logging
|
||||||
- [ ] Improved error handling
|
- [ ] Improved error handling
|
||||||
|
- [ ] Bulk edit tag
|
||||||
- [ ] Caching
|
- [ ] Caching
|
||||||
- [ ] Lossless compression
|
- [ ] Lossless compression
|
||||||
- [ ] Bulk edit tags/Fix tag capitalization
|
|
||||||
- [ ] User management
|
- [ ] User management
|
||||||
- [ ] Cleanup/fixup background tasks
|
- [ ] Cleanup/fixup background tasks
|
||||||
- [ ] Text media
|
- [ ] Text media
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
services:
|
services:
|
||||||
samey:
|
samey:
|
||||||
image: badmanners/samey:latest
|
image: badmanners/samey:latest
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
container_name: samey
|
container_name: samey
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,15 @@
|
||||||
<form hx-put="/post_details/{{ post.id }}" hx-target="this" hx-swap="outerHTML">
|
<article id="post-details">
|
||||||
|
<form hx-put="/post_details/{{ post.id }}" hx-target="#post-details" hx-swap="outerHTML">
|
||||||
<div>
|
<div>
|
||||||
<label>Tags</label>
|
<label>Tags</label>
|
||||||
{% let tags_value = tags %} {% include "fragments/tags_input.html" %}
|
{% let tags_value = tags %} {% include "fragments/tags_input.html" %}
|
||||||
|
<div
|
||||||
|
hx-trigger="keyup[key=='Escape'] from:previous .tags"
|
||||||
|
hx-target="next .tags-autocomplete"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-delete="/remove"
|
||||||
|
hidden
|
||||||
|
></div>
|
||||||
<ul class="reset tags-autocomplete" id="search-autocomplete"></ul>
|
<ul class="reset tags-autocomplete" id="search-autocomplete"></ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -43,4 +51,5 @@
|
||||||
<button hx-get="/post_details/{{ post.id }}">Cancel</button>
|
<button hx-get="/post_details/{{ post.id }}">Cancel</button>
|
||||||
<button hx-confirm="Are you sure that you want to delete this post? This can't be undone!" hx-delete="/post/{{ post.id }}" hx-target="body" hx-replace-url="/">Delete post</button>
|
<button hx-confirm="Are you sure that you want to delete this post? This can't be undone!" hx-delete="/post/{{ post.id }}" hx-target="body" hx-replace-url="/">Delete post</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
|
</article>
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<article id="post-details" hx-target="this" hx-swap="outerHTML">
|
<article id="post-details">
|
||||||
<h2>
|
<h2>
|
||||||
{% if let Some(title) = post.title %}{{ title }}{% else %}Details{%
|
{% if let Some(title) = post.title %}{{ title }}{% else %}Details{% endif %}
|
||||||
endif %}
|
|
||||||
</h2>
|
</h2>
|
||||||
{% if let Some(description) = post.description %}
|
{% if let Some(description) = post.description %}
|
||||||
<div id="description">{{ description | markdown }}</div>
|
<div id="description">{{ description | markdown }}</div>
|
||||||
|
|
@ -9,16 +8,14 @@
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Is public post?</th>
|
<th>Is public post?</th>
|
||||||
<td>
|
<td>{% if post.is_public %}Yes{% else %}No{% endif %}</td>
|
||||||
{% if post.is_public %}Yes{% else %}No{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Rating</th>
|
<th>Rating</th>
|
||||||
<td>
|
<td>
|
||||||
{% match post.rating.as_ref() %} {% when "u" %} Unrated {% when "s" %} Safe
|
{% match post.rating.as_ref() %} {% when "u" %} Unrated {% when "s" %}
|
||||||
{% when "q" %} Questionable {% when "e" %} Explicit {% else %} Unknown {%
|
Safe {% when "q" %} Questionable {% when "e" %} Explicit {% else %}
|
||||||
endmatch %}
|
Unknown {% endmatch %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -54,6 +51,12 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
{% if can_edit %}
|
{% if can_edit %}
|
||||||
<button hx-get="/post_details/{{ post.id }}/edit">Edit post</button>
|
<button
|
||||||
|
hx-get="/post_details/{{ post.id }}/edit"
|
||||||
|
hx-target="#post-details"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
>
|
||||||
|
Edit post
|
||||||
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</article>
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@
|
||||||
name="tags"
|
name="tags"
|
||||||
placeholder="Tags"
|
placeholder="Tags"
|
||||||
hx-post="/search_tags"
|
hx-post="/search_tags"
|
||||||
hx-trigger="input changed"
|
hx-trigger="input changed delay:500ms"
|
||||||
hx-target="next .tags-autocomplete"
|
hx-target="next .tags-autocomplete"
|
||||||
hx-vals="js:{selection_end: event.target.selectionEnd}"
|
hx-swap="innerHTML"
|
||||||
hx-on::after-settle="this.focus(); this.setSelectionRange(-1, -1);"
|
hx-vals="js:{selection_end: document.querySelector('.tags').selectionEnd}"
|
||||||
|
hx-on::after-settle="document.querySelector('.tags').focus(); document.querySelector('.tags').setSelectionRange(-1, -1);"
|
||||||
value="{{ tags_value }}"
|
value="{{ tags_value }}"
|
||||||
aria-autocomplete="list"
|
aria-autocomplete="list"
|
||||||
aria-controls="search-autocomplete"
|
aria-controls="search-autocomplete"
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,13 @@
|
||||||
<h2>Search</h2>
|
<h2>Search</h2>
|
||||||
<form method="get" action="/posts/1">
|
<form method="get" action="/posts/1">
|
||||||
{% let tags_value = "" %} {% include "fragments/tags_input.html" %}
|
{% let tags_value = "" %} {% include "fragments/tags_input.html" %}
|
||||||
|
<div
|
||||||
|
hx-trigger="keyup[key=='Escape'] from:previous .tags"
|
||||||
|
hx-target="next .tags-autocomplete"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-delete="/remove"
|
||||||
|
hidden
|
||||||
|
></div>
|
||||||
<ul class="reset tags-autocomplete" id="search-autocomplete"></ul>
|
<ul class="reset tags-autocomplete" id="search-autocomplete"></ul>
|
||||||
<button type="submit">Search</button>
|
<button type="submit">Search</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,13 @@
|
||||||
<h2>Search</h2>
|
<h2>Search</h2>
|
||||||
<form method="get" action="/posts">
|
<form method="get" action="/posts">
|
||||||
{% let tags_value = tags_text.clone().unwrap_or("".into()) %} {% include "fragments/tags_input.html" %}
|
{% let tags_value = tags_text.clone().unwrap_or("".into()) %} {% include "fragments/tags_input.html" %}
|
||||||
|
<div
|
||||||
|
hx-trigger="keyup[key=='Escape'] from:previous .tags"
|
||||||
|
hx-target="next .tags-autocomplete"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-delete="/remove"
|
||||||
|
hidden
|
||||||
|
></div>
|
||||||
<ul class="reset tags-autocomplete" id="search-autocomplete"></ul>
|
<ul class="reset tags-autocomplete" id="search-autocomplete"></ul>
|
||||||
<button type="submit">Search</button>
|
<button type="submit">Search</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,13 @@
|
||||||
<h1>Upload media</h1>
|
<h1>Upload media</h1>
|
||||||
<form method="post" action="/upload" enctype="multipart/form-data">
|
<form method="post" action="/upload" enctype="multipart/form-data">
|
||||||
{% let tags_value = "" %} {% include "fragments/tags_input.html" %}
|
{% let tags_value = "" %} {% include "fragments/tags_input.html" %}
|
||||||
|
<div
|
||||||
|
hx-trigger="keyup[key=='Escape'] from:previous .tags"
|
||||||
|
hx-target="next .tags-autocomplete"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-delete="/remove"
|
||||||
|
hidden
|
||||||
|
></div>
|
||||||
<ul class="reset tags-autocomplete" id="upload-autocomplete"></ul>
|
<ul class="reset tags-autocomplete" id="upload-autocomplete"></ul>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
|
|
|
||||||
|
|
@ -29,26 +29,6 @@
|
||||||
{% if age_confirmation %}{% include "fragments/age_restricted_check.html"
|
{% if age_confirmation %}{% include "fragments/age_restricted_check.html"
|
||||||
%}{% endif %}
|
%}{% endif %}
|
||||||
<div><a href="{% if let Some(tags_text) = tags_text %}/posts/1?tags={{ tags_text.replace(' ', "+") }}{% else %}/posts/1{% endif %}">< To posts</a></div>
|
<div><a href="{% if let Some(tags_text) = tags_text %}/posts/1?tags={{ tags_text.replace(' ', "+") }}{% else %}/posts/1{% endif %}">< To posts</a></div>
|
||||||
<article>
|
|
||||||
<h2>Search</h2>
|
|
||||||
<form method="get" action="/posts">
|
|
||||||
<input
|
|
||||||
class="tags"
|
|
||||||
type="text"
|
|
||||||
id="search-tags"
|
|
||||||
name="tags"
|
|
||||||
placeholder="Tags"
|
|
||||||
hx-post="/search_tags"
|
|
||||||
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 %}"
|
|
||||||
/>
|
|
||||||
<ul class="reset tags-autocomplete" id="search-autocomplete"></ul>
|
|
||||||
<button type="submit">Search</button>
|
|
||||||
</form>
|
|
||||||
</article>
|
|
||||||
<article>
|
<article>
|
||||||
<table>
|
<table>
|
||||||
{% for item in pool_data %}
|
{% for item in pool_data %}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue