add: expand infinite scrolling to stacks and profiles
This commit is contained in:
parent
2b253c811c
commit
3027b679db
16 changed files with 226 additions and 288 deletions
|
@ -38,6 +38,9 @@ version = "1.0.0"
|
||||||
"general:label.account_banned" = "Account banned"
|
"general:label.account_banned" = "Account banned"
|
||||||
"general:label.account_banned_body" = "Your account has been banned for violating our policies."
|
"general:label.account_banned_body" = "Your account has been banned for violating our policies."
|
||||||
"general:label.better_with_account" = "It's better with an account! Login or sign up to explore more."
|
"general:label.better_with_account" = "It's better with an account! Login or sign up to explore more."
|
||||||
|
"general:label.could_not_find_post" = "Could not find original post..."
|
||||||
|
"general:label.timeline_end" = "That's a wrap!"
|
||||||
|
"general:label.loading" = "Working on it!"
|
||||||
|
|
||||||
"general:label.supporter_motivation" = "Become a supporter!"
|
"general:label.supporter_motivation" = "Become a supporter!"
|
||||||
"general:action.become_supporter" = "Become supporter"
|
"general:action.become_supporter" = "Become supporter"
|
||||||
|
|
|
@ -213,6 +213,14 @@ ol {
|
||||||
margin-left: var(--pad-4);
|
margin-left: var(--pad-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
padding: var(--pad-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: var(--pad-1);
|
||||||
|
}
|
||||||
|
|
||||||
pre,
|
pre,
|
||||||
code {
|
code {
|
||||||
font-family: "Jetbrains Mono", "Fire Code", monospace;
|
font-family: "Jetbrains Mono", "Fire Code", monospace;
|
||||||
|
@ -221,18 +229,12 @@ code {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background: var(--color-lowered);
|
background: var(--color-lowered);
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
padding: var(--pad-1);
|
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
|
||||||
padding: var(--pad-4);
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.icon {
|
svg.icon {
|
||||||
stroke: currentColor;
|
stroke: currentColor;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +265,6 @@ code {
|
||||||
overflow-wrap: normal;
|
overflow-wrap: normal;
|
||||||
text-wrap: pretty;
|
text-wrap: pretty;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
overflow-wrap: anywhere;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,
|
h1,
|
||||||
|
@ -275,7 +276,6 @@ h6 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
width: -moz-max-content;
|
width: -moz-max-content;
|
||||||
width: max-content;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -350,3 +350,42 @@ blockquote {
|
||||||
border-left: solid 5px var(--color-super-lowered);
|
border-left: solid 5px var(--color-super-lowered);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.skel {
|
||||||
|
display: block;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
background: var(--color-raised);
|
||||||
|
animation: skel ease-in-out infinite 2s forwards running;
|
||||||
|
transition: opacity 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes skel {
|
||||||
|
from {
|
||||||
|
background: var(--color-raised);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background: var(--color-lowered);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
background: var(--color-raised);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
animation: spin linear infinite 2s forwards running;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
from {
|
||||||
|
transform: rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -565,11 +565,9 @@ select:focus {
|
||||||
nav {
|
nav {
|
||||||
background: var(--color-primary);
|
background: var(--color-primary);
|
||||||
color: var(--color-text-primary) !important;
|
color: var(--color-text-primary) !important;
|
||||||
color: inherit;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
color: var(--color-text);
|
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 6374;
|
z-index: 6374;
|
||||||
|
@ -722,13 +720,12 @@ dialog {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
display: flex;
|
display: none;
|
||||||
background: var(--color-surface);
|
background: var(--color-surface);
|
||||||
border: solid 1px var(--color-super-lowered) !important;
|
border: solid 1px var(--color-super-lowered) !important;
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
border-style: none;
|
border-style: none;
|
||||||
display: none;
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
animation: popin ease-in-out 1 0.1s forwards running;
|
animation: popin ease-in-out 1 0.1s forwards running;
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
(div ("id" "toast_zone"))
|
(div ("id" "toast_zone"))
|
||||||
|
|
||||||
|
; templates
|
||||||
|
(template
|
||||||
|
("id" "loading_skeleton")
|
||||||
|
(div
|
||||||
|
("class" "flex flex-col gap-2")
|
||||||
|
("ui_ident" "loading_skel")
|
||||||
|
(div
|
||||||
|
("class" "card lowered green flex items-center gap-2")
|
||||||
|
(div ("class" "loader") (icon (text "loader-circle")))
|
||||||
|
(span (str (text "general:label.loading"))))
|
||||||
|
(div
|
||||||
|
("class" "card secondary flex gap-2")
|
||||||
|
(div ("class" "skel avatar"))
|
||||||
|
(div
|
||||||
|
("class" "flex flex-col gap-2 w-full")
|
||||||
|
(div ("class" "skel") ("style" "width: 25%; height: 25px;"))
|
||||||
|
(div ("class" "skel") ("style" "width: 100%; height: 150px"))))))
|
||||||
|
|
||||||
; random js
|
; random js
|
||||||
(text "<script data-turbo-permanent=\"true\" id=\"init-script\">
|
(text "<script data-turbo-permanent=\"true\" id=\"init-script\">
|
||||||
document.documentElement.addEventListener(\"turbo:load\", () => {
|
document.documentElement.addEventListener(\"turbo:load\", () => {
|
||||||
|
|
|
@ -240,7 +240,7 @@
|
||||||
("class" "card lowered red flex items-center gap-2")
|
("class" "card lowered red flex items-center gap-2")
|
||||||
(text "{{ icon \"frown\" }}")
|
(text "{{ icon \"frown\" }}")
|
||||||
(span
|
(span
|
||||||
(text "Could not find original post...")))
|
(str (text "general:label.could_not_find_post"))))
|
||||||
(text "{%- endif %} {%- endif %}"))
|
(text "{%- endif %} {%- endif %}"))
|
||||||
(text "{{ self::post_media(upload_ids=post.uploads) }} {% else %}")
|
(text "{{ self::post_media(upload_ids=post.uploads) }} {% else %}")
|
||||||
(details
|
(details
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
(text "{{ text \"auth:label.recent_posts\" }}"))
|
(text "{{ text \"auth:label.recent_posts\" }}"))
|
||||||
(text "{% else %} {{ icon \"tag\" }}")
|
(text "{% else %} {{ icon \"tag\" }}")
|
||||||
(span
|
(span
|
||||||
(text "{{ text \"auth:label.recent_with_tag\" }}:")
|
(text "{{ text \"auth:label.recent_with_tag\" }}: ")
|
||||||
(b
|
(b
|
||||||
(text "{{ tag }}")))
|
(text "{{ tag }}")))
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
|
@ -40,7 +40,13 @@
|
||||||
(text "{{ text \"general:link.search\" }}")))
|
(text "{{ text \"general:link.search\" }}")))
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
(div
|
(div
|
||||||
("class" "card flex flex-col gap-4")
|
("class" "card w-full flex flex-col gap-2")
|
||||||
(text "{% for post in posts %} {% if post[2].read_access == \"Everybody\" -%} {% if post[0].context.repost and post[0].context.repost.reposting -%} {{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true, can_manage_post=is_self) }} {% else %} {{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self, poll=post[5]) }} {%- endif %} {%- endif %} {% endfor %} {{ components::pagination(page=page, items=posts|length, key=\"&tag=\", value=tag) }}")))
|
("ui_ident" "io_data_load")
|
||||||
|
(div ("ui_ident" "io_data_marker"))))
|
||||||
|
|
||||||
|
(script
|
||||||
|
(text "setTimeout(() => {
|
||||||
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?user_id={{ profile.id }}&tag={{ tag }}&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
||||||
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -40,9 +40,9 @@
|
||||||
(text "{%- endif %}")))
|
(text "{%- endif %}")))
|
||||||
(div
|
(div
|
||||||
("class" "card w-full flex flex-col gap-2")
|
("class" "card w-full flex flex-col gap-2")
|
||||||
(text "{% if list|length == 0 -%}")
|
(text "{% if stack.users|length == 0 -%}")
|
||||||
(p
|
(p
|
||||||
(text "No items yet! Maybe ")
|
(text "No users included yet! Maybe ")
|
||||||
(a
|
(a
|
||||||
("href" "/stacks/{{ stack.id }}/manage#/users")
|
("href" "/stacks/{{ stack.id }}/manage#/users")
|
||||||
(text "add a user to this stack"))
|
(text "add a user to this stack"))
|
||||||
|
@ -63,6 +63,7 @@
|
||||||
(div
|
(div
|
||||||
("class" "flex gap-2 flex-wrap w-full")
|
("class" "flex gap-2 flex-wrap w-full")
|
||||||
(text "{% for user in list %} {{ components::user_plate(user=user, secondary=true) }} {% endfor %}"))
|
(text "{% for user in list %} {{ components::user_plate(user=user, secondary=true) }} {% endfor %}"))
|
||||||
|
(text "{{ components::pagination(page=page, items=list|length) }}")
|
||||||
(text "{% else %}")
|
(text "{% else %}")
|
||||||
; user icons for circle stack
|
; user icons for circle stack
|
||||||
(text "{% if stack.mode == 'Circle' -%}")
|
(text "{% if stack.mode == 'Circle' -%}")
|
||||||
|
@ -77,14 +78,16 @@
|
||||||
(text "{%- endif %}")
|
(text "{%- endif %}")
|
||||||
|
|
||||||
; posts for all stacks except blocklist
|
; posts for all stacks except blocklist
|
||||||
(text "{% for post in list %}
|
(div
|
||||||
{% if post[2].read_access == \"Everybody\" -%}
|
("class" "w-full flex flex-col gap-2")
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting -%}
|
("ui_ident" "io_data_load")
|
||||||
{{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }}
|
(div ("ui_ident" "io_data_marker")))
|
||||||
{% else %}
|
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], poll=post[5]) }}
|
(script
|
||||||
{%- endif %} {%- endif %} {% endfor %}")
|
(text "setTimeout(() => {
|
||||||
(text "{%- endif %} {{ components::pagination(page=page, items=list|length) }}"))))
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?stack_id={{ stack.id }}&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
||||||
|
});"))
|
||||||
|
(text "{%- endif %}"))))
|
||||||
|
|
||||||
(script
|
(script
|
||||||
(text "async function block_all(block = true) {
|
(text "async function block_all(block = true) {
|
||||||
|
|
|
@ -31,12 +31,11 @@
|
||||||
(div
|
(div
|
||||||
("class" "card w-full flex flex-col gap-2")
|
("class" "card w-full flex flex-col gap-2")
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(text "{% for post in list %} {% if post[2].read_access == \"Everybody\" -%} {% if post[0].context.repost and post[0].context.repost.reposting -%} {{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }} {% else %} {{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], poll=post[5]) }} {%- endif %} {%- endif %} {% endfor %}")
|
|
||||||
(div ("ui_ident" "io_data_marker"))))
|
(div ("ui_ident" "io_data_marker"))))
|
||||||
|
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=AllPosts&page=\", Number.parseInt(\"{{ page }}\")]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=AllPosts&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -9,12 +9,11 @@
|
||||||
(div
|
(div
|
||||||
("class" "card w-full flex flex-col gap-2")
|
("class" "card w-full flex flex-col gap-2")
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(text "{% for post in list %} {% if post[2].read_access == \"Everybody\" -%} {% if post[0].context.repost and post[0].context.repost.reposting -%} {{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }} {% else %} {{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], poll=post[5]) }} {%- endif %} {%- endif %} {% endfor %}")
|
|
||||||
(div ("ui_ident" "io_data_marker"))))
|
(div ("ui_ident" "io_data_marker"))))
|
||||||
|
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=FollowingPosts&page=\", Number.parseInt(\"{{ page }}\")]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=FollowingPosts&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -28,13 +28,12 @@
|
||||||
(div
|
(div
|
||||||
("class" "card w-full flex flex-col gap-2")
|
("class" "card w-full flex flex-col gap-2")
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(text "{% for post in list %} {% if post[0].context.repost and post[0].context.repost.reposting -%} {{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }} {% else %} {{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], poll=post[5]) }} {%- endif %} {% endfor %}")
|
|
||||||
(div ("ui_ident" "io_data_marker")))
|
(div ("ui_ident" "io_data_marker")))
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
|
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=MyCommunities&page=\", Number.parseInt(\"{{ page }}\")]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=MyCommunities&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -9,12 +9,11 @@
|
||||||
(div
|
(div
|
||||||
("class" "card w-full flex flex-col gap-2")
|
("class" "card w-full flex flex-col gap-2")
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(text "{% for post in list %} {% if post[2].read_access == \"Everybody\" -%} {% if post[0].context.repost and post[0].context.repost.reposting -%} {{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }} {% else %} {{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], poll=post[5]) }} {%- endif %} {%- endif %} {% endfor %}")
|
|
||||||
(div ("ui_ident" "io_data_marker"))))
|
(div ("ui_ident" "io_data_marker"))))
|
||||||
|
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=PopularPosts&page=\", Number.parseInt(\"{{ page }}\")]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=PopularPosts&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -20,10 +20,13 @@
|
||||||
("class" "flex items-center gap-2")
|
("class" "flex items-center gap-2")
|
||||||
(text "{{ icon \"shell\" }}")
|
(text "{{ icon \"shell\" }}")
|
||||||
(span
|
(span
|
||||||
(text "That's a wrap!<!-- observer_disconnect_{{ random_cache_breaker }} -->")))
|
(str (text "general:label.timeline_end"))
|
||||||
|
(text "<!-- observer_disconnect_{{ random_cache_breaker }} -->")))
|
||||||
|
(text "{% if page > 0 -%}")
|
||||||
(a
|
(a
|
||||||
("class" "button")
|
("class" "button")
|
||||||
("href" "?page=0")
|
("href" "?page=0")
|
||||||
(icon (text "arrow-up"))
|
(icon (text "arrow-up"))
|
||||||
(str (text "chats:label.go_back"))))
|
(str (text "chats:label.go_back")))
|
||||||
|
(text "{%- endif %}"))
|
||||||
(text "{%- endif %}")
|
(text "{%- endif %}")
|
||||||
|
|
|
@ -25,10 +25,10 @@ function media_theme_pref() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_theme(theme) {
|
window.set_theme = (theme) => {
|
||||||
window.localStorage.setItem("tetratto:theme", theme);
|
window.localStorage.setItem("tetratto:theme", theme);
|
||||||
document.documentElement.className = theme;
|
document.documentElement.className = theme;
|
||||||
}
|
};
|
||||||
|
|
||||||
media_theme_pref();
|
media_theme_pref();
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ media_theme_pref();
|
||||||
|
|
||||||
self.define("rel_date", (_, date) => {
|
self.define("rel_date", (_, date) => {
|
||||||
// stolen and slightly modified because js dates suck
|
// stolen and slightly modified because js dates suck
|
||||||
const diff = Math.abs((new Date().getTime() - date.getTime()) / 1000);
|
const diff = Math.abs((Date.now() - date.getTime()) / 1000);
|
||||||
const day_diff = Math.floor(diff / 86400);
|
const day_diff = Math.floor(diff / 86400);
|
||||||
|
|
||||||
if (Number.isNaN(day_diff) || day_diff < 0 || day_diff >= 31) {
|
if (Number.isNaN(day_diff) || day_diff < 0 || day_diff >= 31) {
|
||||||
|
@ -396,7 +396,7 @@ media_theme_pref();
|
||||||
counter.innerText = `${target.value.length}/${target.getAttribute("maxlength")}`;
|
counter.innerText = `${target.value.length}/${target.getAttribute("maxlength")}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
self.define("hooks::character_counter.init", (_, event) => {
|
self.define("hooks::character_counter.init", (_) => {
|
||||||
for (const element of Array.from(
|
for (const element of Array.from(
|
||||||
document.querySelectorAll("[hook=counter]") || [],
|
document.querySelectorAll("[hook=counter]") || [],
|
||||||
)) {
|
)) {
|
||||||
|
@ -413,7 +413,7 @@ media_theme_pref();
|
||||||
element.innerHTML = full_text;
|
element.innerHTML = full_text;
|
||||||
});
|
});
|
||||||
|
|
||||||
self.define("hooks::long_text.init", (_, event) => {
|
self.define("hooks::long_text.init", (_) => {
|
||||||
for (const element of Array.from(
|
for (const element of Array.from(
|
||||||
document.querySelectorAll("[hook=long]") || [],
|
document.querySelectorAll("[hook=long]") || [],
|
||||||
)) {
|
)) {
|
||||||
|
@ -493,13 +493,13 @@ media_theme_pref();
|
||||||
});
|
});
|
||||||
|
|
||||||
self.define("last_seen_just_now", (_, last_seen) => {
|
self.define("last_seen_just_now", (_, last_seen) => {
|
||||||
const now = new Date().getTime();
|
const now = Date.now();
|
||||||
const maximum_time_to_be_considered_online = 60000 * 2; // 2 minutes
|
const maximum_time_to_be_considered_online = 60000 * 2; // 2 minutes
|
||||||
return now - last_seen <= maximum_time_to_be_considered_online;
|
return now - last_seen <= maximum_time_to_be_considered_online;
|
||||||
});
|
});
|
||||||
|
|
||||||
self.define("last_seen_recently", (_, last_seen) => {
|
self.define("last_seen_recently", (_, last_seen) => {
|
||||||
const now = new Date().getTime();
|
const now = Date.now();
|
||||||
const maximum_time_to_be_considered_idle = 60000 * 5; // 5 minutes
|
const maximum_time_to_be_considered_idle = 60000 * 5; // 5 minutes
|
||||||
return now - last_seen <= maximum_time_to_be_considered_idle;
|
return now - last_seen <= maximum_time_to_be_considered_idle;
|
||||||
});
|
});
|
||||||
|
@ -585,8 +585,8 @@ media_theme_pref();
|
||||||
|
|
||||||
self.define(
|
self.define(
|
||||||
"hooks::attach_to_partial",
|
"hooks::attach_to_partial",
|
||||||
({ $ }, partial, full, attach, wrapper, page, run_on_load) => {
|
({ $ }, partial, full, attach, wrapper, page) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, _) => {
|
||||||
async function load_partial() {
|
async function load_partial() {
|
||||||
const url = `${partial}${partial.includes("?") ? "&" : "?"}page=${page}`;
|
const url = `${partial}${partial.includes("?") ? "&" : "?"}page=${page}`;
|
||||||
history.replaceState(
|
history.replaceState(
|
||||||
|
@ -1148,6 +1148,8 @@ ${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
|
||||||
"[ui_ident=io_data_load]",
|
"[ui_ident=io_data_load]",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self.IO_HTML_TMPL = document.getElementById("loading_skeleton");
|
||||||
|
|
||||||
if (!self.IO_DATA_ELEMENT || !self.IO_DATA_MARKER) {
|
if (!self.IO_DATA_ELEMENT || !self.IO_DATA_MARKER) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"ui::io_data_load called, but required elements don't exist",
|
"ui::io_data_load called, but required elements don't exist",
|
||||||
|
@ -1167,14 +1169,19 @@ ${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
|
||||||
self.IO_DATA_PAGE += 1;
|
self.IO_DATA_PAGE += 1;
|
||||||
console.log("load page", self.IO_DATA_PAGE);
|
console.log("load page", self.IO_DATA_PAGE);
|
||||||
|
|
||||||
|
// show loading component
|
||||||
|
const loading = self.IO_HTML_TMPL.content.cloneNode(true);
|
||||||
|
self.IO_DATA_ELEMENT.appendChild(loading);
|
||||||
|
|
||||||
|
// ...
|
||||||
const text = await (
|
const text = await (
|
||||||
await fetch(`${self.IO_DATA_TMPL}${self.IO_DATA_PAGE}`)
|
await fetch(`${self.IO_DATA_TMPL}${self.IO_DATA_PAGE}`)
|
||||||
).text();
|
).text();
|
||||||
|
|
||||||
|
self.IO_DATA_ELEMENT.querySelector("[ui_ident=loading_skel]").remove();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
text.includes(
|
text.includes(`!<!-- observer_disconnect_${window.BUILD_CODE} -->`)
|
||||||
`That's a wrap!<!-- observer_disconnect_${window.BUILD_CODE} -->`,
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
console.log("io_data_end; disconnect");
|
console.log("io_data_end; disconnect");
|
||||||
self.IO_DATA_OBSERVER.disconnect();
|
self.IO_DATA_OBSERVER.disconnect();
|
||||||
|
@ -1251,7 +1258,7 @@ ${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
|
||||||
|
|
||||||
self.define(
|
self.define(
|
||||||
"open",
|
"open",
|
||||||
async ({ $ }, warning_id, warning_hash, warning_page = "") => {
|
async (_, warning_id, warning_hash, warning_page = "") => {
|
||||||
// check localStorage for this warning_id
|
// check localStorage for this warning_id
|
||||||
if (accepted_warnings[warning_id] !== undefined) {
|
if (accepted_warnings[warning_id] !== undefined) {
|
||||||
// check hash
|
// check hash
|
||||||
|
@ -1272,7 +1279,7 @@ ${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
self.define("accept", ({ _ }, warning_id, warning_hash) => {
|
self.define("accept", (_, warning_id, warning_hash) => {
|
||||||
accepted_warnings[warning_id] = warning_hash;
|
accepted_warnings[warning_id] = warning_hash;
|
||||||
|
|
||||||
window.localStorage.setItem(
|
window.localStorage.setItem(
|
||||||
|
|
|
@ -42,22 +42,9 @@ pub async fn index_request(
|
||||||
return {
|
return {
|
||||||
// all timeline for unauthenticated users
|
// all timeline for unauthenticated users
|
||||||
// i'm only changing this for stripe
|
// i'm only changing this for stripe
|
||||||
let list = match data.0.get_latest_posts(12, req.page).await {
|
|
||||||
Ok(l) => match data
|
|
||||||
.0
|
|
||||||
.fill_posts_with_community(l, 0, &Vec::new(), &None)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(l) => l,
|
|
||||||
Err(e) => return Html(render_error(e, &jar, &data, &None).await),
|
|
||||||
},
|
|
||||||
Err(e) => return Html(render_error(e, &jar, &data, &None).await),
|
|
||||||
};
|
|
||||||
|
|
||||||
let lang = get_lang!(jar, data.0);
|
let lang = get_lang!(jar, data.0);
|
||||||
let mut context = initial_context(&data.0.0.0, lang, &None).await;
|
let mut context = initial_context(&data.0.0.0, lang, &None).await;
|
||||||
|
|
||||||
context.insert("list", &list);
|
|
||||||
context.insert("page", &req.page);
|
context.insert("page", &req.page);
|
||||||
Html(data.1.render("timelines/all.html", &context).unwrap())
|
Html(data.1.render("timelines/all.html", &context).unwrap())
|
||||||
};
|
};
|
||||||
|
@ -101,36 +88,9 @@ pub async fn popular_request(
|
||||||
let data = data.read().await;
|
let data = data.read().await;
|
||||||
let user = get_user_from_token!(jar, data.0);
|
let user = get_user_from_token!(jar, data.0);
|
||||||
|
|
||||||
let ignore_users = crate::ignore_users_gen!(user, data);
|
|
||||||
|
|
||||||
let list = match data.0.get_popular_posts(12, req.page, 604_800_000).await {
|
|
||||||
Ok(l) => match data
|
|
||||||
.0
|
|
||||||
.fill_posts_with_community(
|
|
||||||
l,
|
|
||||||
if let Some(ref ua) = user { ua.id } else { 0 },
|
|
||||||
&ignore_users,
|
|
||||||
&user,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(l) => data.0.posts_muted_phrase_filter(
|
|
||||||
&l,
|
|
||||||
if let Some(ref ua) = user {
|
|
||||||
Some(&ua.settings.muted)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Err(e) => return Html(render_error(e, &jar, &data, &user).await),
|
|
||||||
},
|
|
||||||
Err(e) => return Html(render_error(e, &jar, &data, &user).await),
|
|
||||||
};
|
|
||||||
|
|
||||||
let lang = get_lang!(jar, data.0);
|
let lang = get_lang!(jar, data.0);
|
||||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||||
|
|
||||||
context.insert("list", &list);
|
|
||||||
context.insert("page", &req.page);
|
context.insert("page", &req.page);
|
||||||
Html(data.1.render("timelines/popular.html", &context).unwrap())
|
Html(data.1.render("timelines/popular.html", &context).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -151,30 +111,9 @@ pub async fn following_request(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let ignore_users = crate::ignore_users_gen!(user!, data);
|
|
||||||
|
|
||||||
let list = match data
|
|
||||||
.0
|
|
||||||
.get_posts_from_user_following(user.id, 12, req.page)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(l) => match data
|
|
||||||
.0
|
|
||||||
.fill_posts_with_community(l, user.id, &ignore_users, &Some(user.clone()))
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(l) => data
|
|
||||||
.0
|
|
||||||
.posts_muted_phrase_filter(&l, Some(&user.settings.muted)),
|
|
||||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
|
|
||||||
},
|
|
||||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let lang = get_lang!(jar, data.0);
|
let lang = get_lang!(jar, data.0);
|
||||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||||
|
|
||||||
context.insert("list", &list);
|
|
||||||
context.insert("page", &req.page);
|
context.insert("page", &req.page);
|
||||||
Ok(Html(
|
Ok(Html(
|
||||||
data.1.render("timelines/following.html", &context).unwrap(),
|
data.1.render("timelines/following.html", &context).unwrap(),
|
||||||
|
@ -190,36 +129,9 @@ pub async fn all_request(
|
||||||
let data = data.read().await;
|
let data = data.read().await;
|
||||||
let user = get_user_from_token!(jar, data.0);
|
let user = get_user_from_token!(jar, data.0);
|
||||||
|
|
||||||
let ignore_users = crate::ignore_users_gen!(user, data);
|
|
||||||
|
|
||||||
let list = match data.0.get_latest_posts(12, req.page).await {
|
|
||||||
Ok(l) => match data
|
|
||||||
.0
|
|
||||||
.fill_posts_with_community(
|
|
||||||
l,
|
|
||||||
if let Some(ref ua) = user { ua.id } else { 0 },
|
|
||||||
&ignore_users,
|
|
||||||
&user,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(l) => data.0.posts_muted_phrase_filter(
|
|
||||||
&l,
|
|
||||||
if let Some(ref ua) = user {
|
|
||||||
Some(&ua.settings.muted)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Err(e) => return Html(render_error(e, &jar, &data, &user).await),
|
|
||||||
},
|
|
||||||
Err(e) => return Html(render_error(e, &jar, &data, &user).await),
|
|
||||||
};
|
|
||||||
|
|
||||||
let lang = get_lang!(jar, data.0);
|
let lang = get_lang!(jar, data.0);
|
||||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||||
|
|
||||||
context.insert("list", &list);
|
|
||||||
context.insert("page", &req.page);
|
context.insert("page", &req.page);
|
||||||
Html(data.1.render("timelines/all.html", &context).unwrap())
|
Html(data.1.render("timelines/all.html", &context).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -654,8 +566,16 @@ pub async fn search_request(
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct TimelineQuery {
|
pub struct TimelineQuery {
|
||||||
|
#[serde(default)]
|
||||||
pub tl: DefaultTimelineChoice,
|
pub tl: DefaultTimelineChoice,
|
||||||
|
#[serde(default)]
|
||||||
pub page: usize,
|
pub page: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub stack_id: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub user_id: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub tag: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `/_swiss_army_timeline`
|
/// `/_swiss_army_timeline`
|
||||||
|
@ -669,83 +589,107 @@ pub async fn swiss_army_timeline_request(
|
||||||
|
|
||||||
let ignore_users = crate::ignore_users_gen!(user, data);
|
let ignore_users = crate::ignore_users_gen!(user, data);
|
||||||
|
|
||||||
let list = match match req.tl {
|
let list = if req.stack_id != 0 {
|
||||||
DefaultTimelineChoice::AllPosts => data.0.get_latest_posts(12, req.page).await,
|
// stacks
|
||||||
DefaultTimelineChoice::PopularPosts => {
|
if let Some(ref ua) = user {
|
||||||
data.0.get_popular_posts(12, req.page, 604_800_000).await
|
match data
|
||||||
}
|
.0
|
||||||
DefaultTimelineChoice::FollowingPosts => {
|
.get_stack_posts(
|
||||||
if let Some(ref ua) = user {
|
ua.id,
|
||||||
data.0
|
req.stack_id,
|
||||||
.get_posts_from_user_following(ua.id, 12, req.page)
|
|
||||||
.await
|
|
||||||
} else {
|
|
||||||
return Err(Html(
|
|
||||||
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DefaultTimelineChoice::MyCommunities => {
|
|
||||||
if let Some(ref ua) = user {
|
|
||||||
data.0
|
|
||||||
.get_posts_from_user_communities(ua.id, 12, req.page)
|
|
||||||
.await
|
|
||||||
} else {
|
|
||||||
return Err(Html(
|
|
||||||
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DefaultTimelineChoice::Stack(ref s) => {
|
|
||||||
data.0
|
|
||||||
.get_posts_by_stack(
|
|
||||||
match s.parse::<usize>() {
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(_) => {
|
|
||||||
return Err(Html(
|
|
||||||
render_error(
|
|
||||||
Error::MiscError("ID deserialization error".to_string()),
|
|
||||||
&jar,
|
|
||||||
&data,
|
|
||||||
&user,
|
|
||||||
)
|
|
||||||
.await,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
12,
|
12,
|
||||||
req.page,
|
req.page,
|
||||||
|
&ignore_users,
|
||||||
|
&Some(ua.to_owned()),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
{
|
||||||
// questions bad
|
Ok(l) => l,
|
||||||
_ => {
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return Err(Html(
|
return Err(Html(
|
||||||
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} {
|
} else {
|
||||||
Ok(l) => match data
|
match if req.user_id != 0 {
|
||||||
.0
|
// users
|
||||||
.fill_posts_with_community(
|
let other_user = match data.0.get_user_by_id(req.user_id).await {
|
||||||
l,
|
Ok(ua) => ua,
|
||||||
if let Some(ref ua) = user { ua.id } else { 0 },
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
||||||
&ignore_users,
|
};
|
||||||
&user,
|
|
||||||
)
|
check_user_blocked_or_private!(user, other_user, data, jar);
|
||||||
.await
|
|
||||||
{
|
if req.tag.is_empty() {
|
||||||
Ok(l) => data.0.posts_muted_phrase_filter(
|
data.0
|
||||||
&l,
|
.get_posts_by_user(req.user_id, 12, req.page, &user)
|
||||||
if let Some(ref ua) = user {
|
.await
|
||||||
Some(&ua.settings.muted)
|
} else {
|
||||||
} else {
|
data.0
|
||||||
None
|
.get_posts_by_user_tag(req.user_id, &req.tag, 12, req.page, &user)
|
||||||
},
|
.await
|
||||||
),
|
}
|
||||||
|
} else {
|
||||||
|
// everything else
|
||||||
|
match req.tl {
|
||||||
|
DefaultTimelineChoice::AllPosts => data.0.get_latest_posts(12, req.page).await,
|
||||||
|
DefaultTimelineChoice::PopularPosts => {
|
||||||
|
data.0.get_popular_posts(12, req.page, 604_800_000).await
|
||||||
|
}
|
||||||
|
DefaultTimelineChoice::FollowingPosts => {
|
||||||
|
if let Some(ref ua) = user {
|
||||||
|
data.0
|
||||||
|
.get_posts_from_user_following(ua.id, 12, req.page)
|
||||||
|
.await
|
||||||
|
} else {
|
||||||
|
return Err(Html(
|
||||||
|
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultTimelineChoice::MyCommunities => {
|
||||||
|
if let Some(ref ua) = user {
|
||||||
|
data.0
|
||||||
|
.get_posts_from_user_communities(ua.id, 12, req.page)
|
||||||
|
.await
|
||||||
|
} else {
|
||||||
|
return Err(Html(
|
||||||
|
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// questions bad
|
||||||
|
_ => {
|
||||||
|
return Err(Html(
|
||||||
|
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
Ok(l) => match data
|
||||||
|
.0
|
||||||
|
.fill_posts_with_community(
|
||||||
|
l,
|
||||||
|
if let Some(ref ua) = user { ua.id } else { 0 },
|
||||||
|
&ignore_users,
|
||||||
|
&user,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(l) => data.0.posts_muted_phrase_filter(
|
||||||
|
&l,
|
||||||
|
if let Some(ref ua) = user {
|
||||||
|
Some(&ua.settings.muted)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Err(e) => return Ok(Html(render_error(e, &jar, &data, &user).await)),
|
||||||
|
},
|
||||||
Err(e) => return Ok(Html(render_error(e, &jar, &data, &user).await)),
|
Err(e) => return Ok(Html(render_error(e, &jar, &data, &user).await)),
|
||||||
},
|
}
|
||||||
Err(e) => return Ok(Html(render_error(e, &jar, &data, &user).await)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let lang = get_lang!(jar, data.0);
|
let lang = get_lang!(jar, data.0);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use super::{render_error, PaginatedQuery, ProfileQuery};
|
use super::{render_error, PaginatedQuery, ProfileQuery};
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::initial_context, check_user_blocked_or_private, get_lang, get_user_from_token, State,
|
assets::initial_context, check_user_blocked_or_private, get_lang, get_user_from_token,
|
||||||
|
ignore_users_gen, State,
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
Extension,
|
Extension,
|
||||||
|
@ -241,67 +242,8 @@ pub async fn posts_request(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch data
|
// fetch pinned
|
||||||
let ignore_users = crate::ignore_users_gen!(user, data);
|
let ignore_users = ignore_users_gen!(user, data);
|
||||||
|
|
||||||
let posts = if props.tag.is_empty() {
|
|
||||||
match data
|
|
||||||
.0
|
|
||||||
.get_posts_by_user(other_user.id, 12, props.page, &user)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(p) => match data
|
|
||||||
.0
|
|
||||||
.fill_posts_with_community(
|
|
||||||
p,
|
|
||||||
if let Some(ref ua) = user { ua.id } else { 0 },
|
|
||||||
&ignore_users,
|
|
||||||
&user,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(p) => data.0.posts_muted_phrase_filter(
|
|
||||||
&p,
|
|
||||||
if let Some(ref ua) = user {
|
|
||||||
Some(&ua.settings.muted)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
|
||||||
},
|
|
||||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
match data
|
|
||||||
.0
|
|
||||||
.get_posts_by_user_tag(other_user.id, &props.tag, 12, props.page, &user)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(p) => match data
|
|
||||||
.0
|
|
||||||
.fill_posts_with_community(
|
|
||||||
p,
|
|
||||||
if let Some(ref ua) = user { ua.id } else { 0 },
|
|
||||||
&ignore_users,
|
|
||||||
&user,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(p) => data.0.posts_muted_phrase_filter(
|
|
||||||
&p,
|
|
||||||
if let Some(ref ua) = user {
|
|
||||||
Some(&ua.settings.muted)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
|
||||||
},
|
|
||||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let pinned = if props.tag.is_empty() {
|
let pinned = if props.tag.is_empty() {
|
||||||
match data.0.get_pinned_posts_by_user(other_user.id).await {
|
match data.0.get_pinned_posts_by_user(other_user.id).await {
|
||||||
Ok(p) => match data
|
Ok(p) => match data
|
||||||
|
@ -375,7 +317,6 @@ pub async fn posts_request(
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
context.insert("posts", &posts);
|
|
||||||
context.insert("pinned", &pinned);
|
context.insert("pinned", &pinned);
|
||||||
context.insert("page", &props.page);
|
context.insert("page", &props.page);
|
||||||
context.insert("tag", &props.tag);
|
context.insert("tag", &props.tag);
|
||||||
|
|
|
@ -92,25 +92,6 @@ pub async fn feed_request(
|
||||||
.await
|
.await
|
||||||
.is_ok(),
|
.is_ok(),
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
let ignore_users = crate::ignore_users_gen!(user!, data);
|
|
||||||
let list = match data
|
|
||||||
.0
|
|
||||||
.get_stack_posts(
|
|
||||||
user.id,
|
|
||||||
stack.id,
|
|
||||||
12,
|
|
||||||
req.page,
|
|
||||||
&ignore_users,
|
|
||||||
&Some(user.clone()),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(l) => l,
|
|
||||||
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
|
|
||||||
};
|
|
||||||
|
|
||||||
context.insert("list", &list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return
|
// return
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue