add: circle stacks

This commit is contained in:
trisua 2025-06-15 16:09:02 -04:00
parent 50704d27a9
commit 56cea83933
27 changed files with 419 additions and 107 deletions

View file

@ -97,6 +97,13 @@
("value" "{{ community.id }}")
("selected" "{% if selected_community == community.id -%}true{% else %}false{%- endif %}")
(text "{% if community.context.display_name -%} {{ community.context.display_name }} {% else %} {{ community.title }} {%- endif %}"))
(text "{% endfor %}")
(text "{% for stack in stacks %}")
(option
("value" "{{ stack.id }}")
("selected" "{% if selected_stack == stack.id -%}true{% else %}false{%- endif %}")
("is_stack" "true")
(text "{{ stack.name }} (circle)"))
(text "{% endfor %}")))
(form
("class" "card flex flex-col gap-2")
@ -184,13 +191,19 @@
}
}
const is_selected_stack = document.getElementById(
\"community_to_post_to\",
).selectedOptions[0].getAttribute(\"is_stack\") === \"true\";
const selected_community = document.getElementById(
\"community_to_post_to\",
).selectedOptions[0].value;
body.append(
\"body\",
JSON.stringify({
content: e.target.content.value,
community: document.getElementById(
\"community_to_post_to\",
).selectedOptions[0].value,
community: !is_selected_stack ? selected_community : \"0\",
stack: is_selected_stack ? selected_community : \"0\",
poll: poll_data[1],
title: e.target.title.value,
}),
@ -316,12 +329,15 @@
(text "{% else %}")
(script
(text "async function create_post_from_form(e) {
e.preventDefault();
const id = await trigger(\"me::repost\", [
\"{{ quoting[1].id }}\",
e.target.content.value,
document.getElementById(\"community_to_post_to\")
.selectedOptions[0].value,
false,
document.getElementById(\"community_to_post_to\")
.selectedOptions[0].getAttribute(\"is_stack\") === \"true\",
]);
// update settings
@ -394,27 +410,34 @@
(text "{%- endif %}"))
(script
(text "const town_square = \"{{ config.town_square }}\";
(text "(() => {const town_square = \"{{ config.town_square }}\";
const user_id = \"{{ user.id }}\";
function update_community_avatar(e) {
window.update_community_avatar = (e) => {
const element = e.target.parentElement.querySelector(\".avatar\");
const is_stack = e.target.selectedOptions[0].getAttribute(\"is_stack\") === \"true\";
const id = e.target.selectedOptions[0].value;
element.setAttribute(\"title\", id);
element.setAttribute(\"alt\", `${id}'s avatar`);
if (id === town_square) {
if (id === town_square || is_stack) {
element.src = `/api/v1/auth/user/${user_id}/avatar?selector_type=id`;
} else {
element.src = `/api/v1/communities/${id}/avatar`;
}
}
function check_community_supports_title(e) {
window.check_community_supports_title = async (e) => {
const element = document.getElementById(\"title_field\");
const is_stack = e.target.selectedOptions[0].getAttribute(\"is_stack\") === \"true\";
const id = e.target.selectedOptions[0].value;
if (is_stack) {
element.classList.add(\"hidden\");
return;
}
fetch(`/api/v1/communities/${id}/supports_titles`)
.then((res) => res.json())
.then((res) => {
@ -436,7 +459,7 @@
});
}, 150);
async function cancel_create_post() {
window.cancel_create_post = async () => {
if (
!(await trigger(\"atto::confirm\", [
\"Are you sure you would like to do this? Your post content will be lost.\",
@ -446,6 +469,6 @@
}
window.history.back();
}"))
}})();"))
(text "{% endblock %}")

View file

@ -173,8 +173,13 @@
("class" "flex items-center")
("style" "color: var(--color-primary)")
(text "{{ icon \"square-asterisk\" }}"))
(text "{%- endif %}")
(text "{% if community and community.is_forge -%} {% if post.is_open -%}")
(text "{%- endif %} {% if post.stack -%}")
(span
("title" "Posted to a stack you're in")
("class" "flex items-center")
("style" "color: var(--color-primary)")
(text "{{ icon \"layers\" }}"))
(text "{%- endif %} {% if community and community.is_forge -%} {% if post.is_open -%}")
(span
("title" "Open")
("class" "flex items-center green")

View file

@ -298,6 +298,7 @@
JSON.stringify({
content: e.target.content.value,
community: \"{{ community.id }}\",
stack: \"{{ post.stack }}\",
replying_to: \"{{ post.id }}\",
poll: poll_data[1],
}),

View file

@ -581,7 +581,9 @@
(li
(text "Ability to create more than 1 app"))
(li
(text "Create up to 10 stack blocks")))
(text "Create up to 10 stack blocks"))
(li
(text "Add unlimited users to stacks")))
(a
("href" "{{ config.stripe.payment_link }}?client_reference_id={{ user.id }}")
("class" "button")

View file

@ -17,14 +17,27 @@
(text "{{ components::avatar(username=stack.owner, selector_type=\"id\") }}"))
(span
(text "{{ stack.name }}")))
(text "{% if user and user.id == stack.owner -%}")
(a
("href" "/stacks/{{ stack.id }}/manage")
("class" "button lowered small")
(text "{{ icon \"pencil\" }}")
(span
(text "{{ text \"general:action.manage\" }}")))
(text "{%- endif %}"))
(div
("class" "flex gap-2")
(text "{% if stack.mode == 'Circle' -%}")
; post button for circle stacks
(a
("href" "/communities/intents/post?stack={{ stack.id }}")
("class" "button lowered small")
(text "{{ icon \"plus\" }}")
(span
(text "{{ text \"general:action.post\" }}")))
(text "{%- endif %}")
(text "{% if user and user.id == stack.owner -%}")
; manage button for stack owner only
(a
("href" "/stacks/{{ stack.id }}/manage")
("class" "button lowered small")
(text "{{ icon \"pencil\" }}")
(span
(text "{{ text \"general:action.manage\" }}")))
(text "{%- endif %}")))
(div
("class" "card w-full flex flex-col gap-2")
(text "{% if list|length == 0 -%}")
@ -37,6 +50,7 @@
(text "{%- endif %}")
(text "{% if stack.mode == 'BlockList' -%}")
; block button + user list for blocklist only
(text "{% if not is_blocked -%}")
(button
("onclick" "block_all()")
@ -50,6 +64,12 @@
("class" "flex gap-2 flex-wrap w-full")
(text "{% for user in list %} {{ components::user_plate(user=user, secondary=true) }} {% endfor %}"))
(text "{% else %}")
; user icons for circle stack
(text "{% if stack.mode == 'Circle' -%} {% for user in stack.users %}")
(text "{{ components::avatar(username=user, selector_type=\"id\", size=\"24px\") }}")
(text "{% endfor %} {%- endif %}")
; posts for all stacks except blocklist
(text "{% for post in list %}
{% if post[2].read_access == \"Everybody\" -%}
{% if post[0].context.repost and post[0].context.repost.reposting -%}

View file

@ -67,7 +67,11 @@
(option
("value" "BlockList")
("selected" "{% if stack.mode == 'BlockList' -%}true{% else %}false{%- endif %}")
(text "Block list")))))
(text "Block list"))
(option
("value" "Circle")
("selected" "{% if stack.mode == 'Circle' -%}true{% else %}false{%- endif %}")
(text "Circle")))))
(div
("class" "card-nest")
("ui_ident" "sort")

View file

@ -259,7 +259,14 @@
self.define(
"repost",
(_, id, content, community, do_not_redirect = false) => {
(
_,
id,
content,
community,
do_not_redirect = false,
is_stack = false,
) => {
return new Promise((resolve, _) => {
fetch(`/api/v1/posts/${id}/repost`, {
method: "POST",
@ -268,7 +275,8 @@
},
body: JSON.stringify({
content,
community,
community: !is_stack ? community : "0",
stack: is_stack ? community : "0",
}),
})
.then((res) => res.json())