fix: require reactions to be unique for owner, asset

add: cut off really long text in posts
This commit is contained in:
trisua 2025-05-08 16:35:58 -04:00
parent a1c6beb664
commit d7a37809ba
9 changed files with 27 additions and 37 deletions

View file

@ -1048,17 +1048,14 @@ dialog::backdrop {
position: absolute;
left: 0;
top: 0;
background: linear-gradient(transparent 50%, var(--color-raised));
}
.hook\:long\.hidden_text\+lowered::before {
background: linear-gradient(transparent 50%, var(--color-lowered));
background: linear-gradient(transparent 20%, var(--color-surface));
border-radius: var(--radius);
}
.hook\:long\.hidden_text::after {
position: absolute;
content: "Show full content";
border-radius: calc(var(--radius) * 4);
border-radius: var(--radius);
padding: 0.25rem 0.75rem;
background: var(--color-primary);
font-weight: 600;

View file

@ -228,9 +228,13 @@ and show_community and community.id != config.town_square or question %}
</div>
{% if not post.context.content_warning %}
<span id="post-content:{{ post.id }}" class="no_p_margin"
>{{ post.content|markdown|safe }}</span
<span
id="post-content:{{ post.id }}"
class="no_p_margin"
hook="long"
>
{{ post.content|markdown|safe }}
</span>
{% else %}
<details>
<summary
@ -240,9 +244,13 @@ and show_community and community.id != config.town_square or question %}
<b>{{ post.context.content_warning }}</b>
</summary>
<span id="post-content:{{ post.id }}" class="no_p_margin"
>{{ post.content|markdown|safe }}</span
<span
id="post-content:{{ post.id }}"
class="no_p_margin"
hook="long"
>
{{ post.content|markdown|safe }}
</span>
</details>
{% endif %}
</div>

View file

@ -111,7 +111,6 @@ macros -%}
atto["hooks::ips"]();
atto["hooks::check_reactions"]();
atto["hooks::tabs"]();
atto["hooks::partial_embeds"]();
atto["hooks::spotify_time_text"](); // spotify durations
if (document.getElementById("tokens")) {

View file

@ -349,7 +349,7 @@ media_theme_pref();
for (const element of Array.from(
document.querySelectorAll("[hook=long]") || [],
)) {
const is_long = element.innerText.length >= 64 * 16;
const is_long = element.innerText.length >= 64 * 8;
if (!is_long) {
continue;
@ -362,12 +362,12 @@ media_theme_pref();
}
const html = element.innerHTML;
const short = html.slice(0, 64 * 16);
const short = html.slice(0, 64 * 8);
element.innerHTML = `${short}...`;
// event
const listener = () => {
app["hooks::long"](element, html);
self["hooks::long"](element, html);
element.removeEventListener("click", listener);
};
@ -508,7 +508,7 @@ media_theme_pref();
})
.then((res) => res.json())
.then((res) => {
trigger("app::toast", [
trigger("atto::toast", [
res.success ? "success" : "error",
res.message,
]);
@ -560,7 +560,7 @@ media_theme_pref();
wrapper.scrollTop + wrapper.offsetHeight + 100 >
attach.offsetHeight
) {
self.debounce("app::partials")
self.debounce("atto::partials")
.then(async () => {
if (document.getElementById("initial_loader")) {
console.log("partial blocked");
@ -570,7 +570,6 @@ media_theme_pref();
// biome-ignore lint/style/noParameterAssign: no it isn't
page += 1;
await load_partial();
await $["hooks::partial_embeds"]();
})
.catch(() => {
console.log("partial stuck");
@ -583,25 +582,6 @@ media_theme_pref();
},
);
self.define("hooks::partial_embeds", (_) => {
for (const paragraph of Array.from(
document.querySelectorAll("span[class] p"),
)) {
const groups = /(\/\+r\/)([\w]+)/.exec(paragraph.innerText);
if (groups === null) {
continue;
}
// add embed
paragraph.innerText = paragraph.innerText.replace(groups[0], "");
paragraph.parentElement.innerHTML += `<include-partial
src="/_app/components/response.html?id=${groups[2]}&do_render_nested=false"
uses="app::clean_date_codes,app::link_filter,app::hooks::alt"
></include-partial>`;
}
});
self.define("hooks::check_reactions", async ({ $ }) => {
const observer = $.offload_work_to_client_when_in_view(
async (element) => {

View file

@ -54,6 +54,7 @@
});
self.define("react", async (_, element, asset, asset_type, is_like) => {
await trigger("atto::debounce", ["reactions::toggle"]);
fetch("/api/v1/reactions", {
method: "POST",
headers: {

View file

@ -653,6 +653,7 @@ impl DataManager {
auto_method!(get_user_by_stripe_id(&str)@get_user_from_row -> "SELECT * FROM users WHERE stripe_id = $1" --name="user" --returns=User);
auto_method!(update_user_stripe_id(&str)@get_user_by_id -> "UPDATE users SET stripe_id = $1 WHERE id = $2" --cache-key-tmpl=cache_clear_user);
auto_method!(update_user_notification_count(i32)@get_user_by_id -> "UPDATE users SET notification_count = $1 WHERE id = $2" --cache-key-tmpl=cache_clear_user);
auto_method!(incr_user_notifications()@get_user_by_id -> "UPDATE users SET notification_count = notification_count + 1 WHERE id = $1" --cache-key-tmpl=cache_clear_user --incr);
auto_method!(decr_user_notifications()@get_user_by_id -> "UPDATE users SET notification_count = notification_count - 1 WHERE id = $1" --cache-key-tmpl=cache_clear_user --decr=notification_count);

View file

@ -4,5 +4,6 @@ CREATE TABLE IF NOT EXISTS reactions (
owner BIGINT NOT NULL,
asset BIGINT NOT NULL,
asset_type TEXT NOT NULL,
is_like INT NOT NULL
is_like INT NOT NULL,
UNIQUE (owner, asset)
)

View file

@ -187,6 +187,8 @@ impl DataManager {
self.delete_notification(notification.id, user).await?
}
self.update_user_notification_count(user.id, 0).await?;
Ok(())
}

View file

@ -0,0 +1 @@
ALTER TABLE reactions ADD CONSTRAINT uq_reactions UNIQUE (owner, asset);