add: profile and full search
This commit is contained in:
parent
b8b0ef7f21
commit
3e4ee8126a
52 changed files with 897 additions and 484 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -3282,7 +3282,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tetratto"
|
name = "tetratto"
|
||||||
version = "3.1.0"
|
version = "4.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ammonia",
|
"ammonia",
|
||||||
"async-stripe",
|
"async-stripe",
|
||||||
|
@ -3313,7 +3313,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tetratto-core"
|
name = "tetratto-core"
|
||||||
version = "3.1.0"
|
version = "4.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
"base16ct",
|
"base16ct",
|
||||||
|
@ -3337,7 +3337,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tetratto-l10n"
|
name = "tetratto-l10n"
|
||||||
version = "3.1.0"
|
version = "4.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pathbufd",
|
"pathbufd",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -3346,7 +3346,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tetratto-shared"
|
name = "tetratto-shared"
|
||||||
version = "3.1.0"
|
version = "4.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ammonia",
|
"ammonia",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tetratto"
|
name = "tetratto"
|
||||||
version = "3.1.0"
|
version = "4.0.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -87,6 +87,7 @@ pub const TIMELINES_FOLLOWING_QUESTIONS: &str =
|
||||||
include_str!("./public/html/timelines/following_questions.html");
|
include_str!("./public/html/timelines/following_questions.html");
|
||||||
pub const TIMELINES_ALL_QUESTIONS: &str =
|
pub const TIMELINES_ALL_QUESTIONS: &str =
|
||||||
include_str!("./public/html/timelines/all_questions.html");
|
include_str!("./public/html/timelines/all_questions.html");
|
||||||
|
pub const TIMELINES_SEARCH: &str = include_str!("./public/html/timelines/search.html");
|
||||||
|
|
||||||
pub const MOD_AUDIT_LOG: &str = include_str!("./public/html/mod/audit_log.html");
|
pub const MOD_AUDIT_LOG: &str = include_str!("./public/html/mod/audit_log.html");
|
||||||
pub const MOD_REPORTS: &str = include_str!("./public/html/mod/reports.html");
|
pub const MOD_REPORTS: &str = include_str!("./public/html/mod/reports.html");
|
||||||
|
@ -283,6 +284,7 @@ pub(crate) async fn write_assets(config: &Config) -> PathBufD {
|
||||||
write_template!(html_path->"timelines/popular_questions.html"(crate::assets::TIMELINES_POPULAR_QUESTIONS) --config=config);
|
write_template!(html_path->"timelines/popular_questions.html"(crate::assets::TIMELINES_POPULAR_QUESTIONS) --config=config);
|
||||||
write_template!(html_path->"timelines/following_questions.html"(crate::assets::TIMELINES_FOLLOWING_QUESTIONS) --config=config);
|
write_template!(html_path->"timelines/following_questions.html"(crate::assets::TIMELINES_FOLLOWING_QUESTIONS) --config=config);
|
||||||
write_template!(html_path->"timelines/all_questions.html"(crate::assets::TIMELINES_ALL_QUESTIONS) --config=config);
|
write_template!(html_path->"timelines/all_questions.html"(crate::assets::TIMELINES_ALL_QUESTIONS) --config=config);
|
||||||
|
write_template!(html_path->"timelines/search.html"(crate::assets::TIMELINES_SEARCH) --config=config);
|
||||||
|
|
||||||
write_template!(html_path->"mod/audit_log.html"(crate::assets::MOD_AUDIT_LOG) -d "mod" --config=config);
|
write_template!(html_path->"mod/audit_log.html"(crate::assets::MOD_AUDIT_LOG) -d "mod" --config=config);
|
||||||
write_template!(html_path->"mod/reports.html"(crate::assets::MOD_REPORTS) --config=config);
|
write_template!(html_path->"mod/reports.html"(crate::assets::MOD_REPORTS) --config=config);
|
||||||
|
|
|
@ -15,6 +15,7 @@ version = "1.0.0"
|
||||||
"general:link.reports" = "Reports"
|
"general:link.reports" = "Reports"
|
||||||
"general:link.ip_bans" = "IP bans"
|
"general:link.ip_bans" = "IP bans"
|
||||||
"general:link.stats" = "Stats"
|
"general:link.stats" = "Stats"
|
||||||
|
"general:link.search" = "Search"
|
||||||
"general:action.save" = "Save"
|
"general:action.save" = "Save"
|
||||||
"general:action.delete" = "Delete"
|
"general:action.delete" = "Delete"
|
||||||
"general:action.purge" = "Purge"
|
"general:action.purge" = "Purge"
|
||||||
|
@ -109,7 +110,6 @@ version = "1.0.0"
|
||||||
"communities:label.repost" = "Repost"
|
"communities:label.repost" = "Repost"
|
||||||
"communities:label.quote_post" = "Quote post"
|
"communities:label.quote_post" = "Quote post"
|
||||||
"communities:label.expand_original" = "Expand original"
|
"communities:label.expand_original" = "Expand original"
|
||||||
"communities:label.search" = "Search"
|
|
||||||
"communities:label.search_results" = "Search results"
|
"communities:label.search_results" = "Search results"
|
||||||
"communities:label.query" = "Query"
|
"communities:label.query" = "Query"
|
||||||
"communities:label.join_new" = "Join new"
|
"communities:label.join_new" = "Join new"
|
||||||
|
|
|
@ -97,7 +97,7 @@ macro_rules! get_lang {
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! check_user_blocked_or_private {
|
macro_rules! check_user_blocked_or_private {
|
||||||
($user:ident, $other_user:ident, $data:ident, $jar:ident) => {
|
($user:expr, $other_user:ident, $data:ident, $jar:ident) => {
|
||||||
// check require_account
|
// check require_account
|
||||||
if $user.is_none() && $other_user.settings.require_account {
|
if $user.is_none() && $other_user.settings.require_account {
|
||||||
return Err(Html(
|
return Err(Html(
|
||||||
|
|
|
@ -755,6 +755,38 @@ select:focus {
|
||||||
border-bottom-right-radius: var(--radius);
|
border-bottom-right-radius: var(--radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pillmenu:not(.rows) .row {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows .row {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows a {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows .row:first-of-type a:first-child {
|
||||||
|
border-top-left-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows .row:first-of-type a:last-child {
|
||||||
|
border-top-right-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows .row:last-of-type a:first-child {
|
||||||
|
border-bottom-left-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows .row:last-of-type a:last-child {
|
||||||
|
border-bottom-right-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 900px) {
|
@media screen and (max-width: 900px) {
|
||||||
.pillmenu {
|
.pillmenu {
|
||||||
/* convert into a sidemenu */
|
/* convert into a sidemenu */
|
||||||
|
@ -762,9 +794,9 @@ select:focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
.pillmenu a:first-child {
|
.pillmenu a:first-child {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
border-top-left-radius: var(--radius);
|
border-top-left-radius: var(--radius);
|
||||||
border-top-right-radius: var(--radius);
|
border-top-right-radius: var(--radius);
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pillmenu a:last-child {
|
.pillmenu a:last-child {
|
||||||
|
@ -772,6 +804,17 @@ select:focus {
|
||||||
border-bottom-left-radius: var(--radius);
|
border-bottom-left-radius: var(--radius);
|
||||||
border-bottom-right-radius: var(--radius);
|
border-bottom-right-radius: var(--radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows .row {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pillmenu.rows .row:first-of-type a:first-child,
|
||||||
|
.pillmenu.rows .row:first-of-type a:last-child,
|
||||||
|
.pillmenu.rows .row:last-of-type a:first-child,
|
||||||
|
.pillmenu.rows .row:last-of-type a:last-child {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notification */
|
/* notification */
|
||||||
|
|
|
@ -72,4 +72,4 @@ config.connections.last_fm_key %}
|
||||||
}, 500);
|
}, 500);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
</script>
|
</script>
|
||||||
{% endif %} {% endblock %}
|
{%- endif %} {% endblock %}
|
||||||
|
|
|
@ -7,15 +7,15 @@ hide_user_menu=true) }}
|
||||||
class="flex gap-2 items-center active"
|
class="flex gap-2 items-center active"
|
||||||
onclick="toggle_sidebars(event)"
|
onclick="toggle_sidebars(event)"
|
||||||
>
|
>
|
||||||
{{ icon "panel-left" }} {% if community %}
|
{{ icon "panel-left" }} {% if community -%}
|
||||||
<b class="name shorter">
|
<b class="name shorter">
|
||||||
{% if community.context.display_name %} {{
|
{% if community.context.display_name -%} {{
|
||||||
community.context.display_name }} {% else %} {{ community.title }}
|
community.context.display_name }} {% else %} {{ community.title }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</b>
|
</b>
|
||||||
{% else %}
|
{% else %}
|
||||||
<b>{{ text "chats:label.my_chats" }}</b>
|
<b>{{ text "chats:label.my_chats" }}</b>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</button>
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
@ -27,36 +27,36 @@ hide_user_menu=true) }}
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="/chats/0/0"
|
href="/chats/0/0"
|
||||||
class="button quaternary channel_icon {% if selected_community == 0 %}selected{% endif %}"
|
class="button quaternary channel_icon {% if selected_community == 0 -%}selected{%- endif %}"
|
||||||
data-turbo="false"
|
data-turbo="false"
|
||||||
>
|
>
|
||||||
{{ icon "message-circle" }}
|
{{ icon "message-circle" }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% for community in communities %} {% if community.id != 0 %}
|
{% for community in communities %} {% if community.id != 0 -%}
|
||||||
<a
|
<a
|
||||||
href="/chats/{{ community.id }}/0"
|
href="/chats/{{ community.id }}/0"
|
||||||
class="button quaternary channel_icon {% if selected_community == community.id %}selected{% endif %}"
|
class="button quaternary channel_icon {% if selected_community == community.id -%}selected{%- endif %}"
|
||||||
data-turbo="false"
|
data-turbo="false"
|
||||||
>
|
>
|
||||||
{{ components::community_avatar(id=community.id,
|
{{ components::community_avatar(id=community.id,
|
||||||
community=community, size="48px") }}
|
community=community, size="48px") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %} {% endfor %}
|
{%- endif %} {% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sidebar flex flex-col gap-2 justify-between" id="channels_list">
|
<div class="sidebar flex flex-col gap-2 justify-between" id="channels_list">
|
||||||
<div class="flex flex-col gap-2 w-full">
|
<div class="flex flex-col gap-2 w-full">
|
||||||
<div class="title flex items-center justify-between channel_header">
|
<div class="title flex items-center justify-between channel_header">
|
||||||
{% if community %}
|
{% if community -%}
|
||||||
<b class="name shorter">
|
<b class="name shorter">
|
||||||
{% if community.context.display_name %} {{
|
{% if community.context.display_name -%} {{
|
||||||
community.context.display_name }} {% else %} {{
|
community.context.display_name }} {% else %} {{
|
||||||
community.title }} {% endif %}
|
community.title }} {%- endif %}
|
||||||
</b>
|
</b>
|
||||||
{% else %}
|
{% else %}
|
||||||
<b>{{ text "chats:label.my_chats" }}</b>
|
<b>{{ text "chats:label.my_chats" }}</b>
|
||||||
{% endif %} {% if selected_community != 0 %}
|
{%- endif %} {% if selected_community != 0 -%}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
class="camo small"
|
class="camo small"
|
||||||
|
@ -74,18 +74,18 @@ hide_user_menu=true) }}
|
||||||
}}</span
|
}}</span
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
{% if can_manage_channels %}
|
{% if can_manage_channels -%}
|
||||||
<a href="/community/{{ selected_community }}/manage">
|
<a href="/community/{{ selected_community }}/manage">
|
||||||
{{ icon "settings" }}
|
{{ icon "settings" }}
|
||||||
<span>{{ text "general:action.manage" }}</span>
|
<span>{{ text "general:action.manage" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if can_manage_channels %}
|
{% if can_manage_channels -%}
|
||||||
<a
|
<a
|
||||||
class="button w-full justify-start quaternary"
|
class="button w-full justify-start quaternary"
|
||||||
href="/community/{{ selected_community }}/manage#/channels"
|
href="/community/{{ selected_community }}/manage#/channels"
|
||||||
|
@ -93,7 +93,7 @@ hide_user_menu=true) }}
|
||||||
{{ icon "plus" }}
|
{{ icon "plus" }}
|
||||||
<span>{{ text "communities:action.create_channel" }}</span>
|
<span>{{ text "communities:action.create_channel" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<turbo-frame
|
<turbo-frame
|
||||||
id="channels_list_frame"
|
id="channels_list_frame"
|
||||||
|
@ -105,7 +105,7 @@ hide_user_menu=true) }}
|
||||||
{{ components::user_plate(user=user, show_menu=true) }}
|
{{ components::user_plate(user=user, show_menu=true) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if channel %}
|
{% if channel -%}
|
||||||
<div class="w-full flex flex-col gap-2" id="stream" style="padding: 1rem">
|
<div class="w-full flex flex-col gap-2" id="stream" style="padding: 1rem">
|
||||||
<turbo-frame
|
<turbo-frame
|
||||||
id="stream_body_frame"
|
id="stream_body_frame"
|
||||||
|
@ -132,7 +132,7 @@ hide_user_menu=true) }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
|
@ -695,7 +695,7 @@ hide_user_menu=true) }}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% if selected_channel %}
|
{% if selected_channel -%}
|
||||||
<script>
|
<script>
|
||||||
window.SUBSCRIBE_CHANNEL = "{{ selected_community }}" === "0";
|
window.SUBSCRIBE_CHANNEL = "{{ selected_community }}" === "0";
|
||||||
|
|
||||||
|
@ -713,6 +713,6 @@ hide_user_menu=true) }}
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{%- import "components.html" as components -%}
|
{%- import "components.html" as components -%}
|
||||||
<turbo-frame id="channels_list_frame">
|
<turbo-frame id="channels_list_frame">
|
||||||
<div
|
<div
|
||||||
class="channels_list_half flex flex-col gap-2 {% if selected_community != 0 or selected_channel == 0%}no_members{% endif %}"
|
class="channels_list_half flex flex-col gap-2 {% if selected_community != 0 or selected_channel == 0%}no_members{%- endif -%}"
|
||||||
>
|
>
|
||||||
{% for channel in channels %}
|
{% for channel in channels %}
|
||||||
<div class="flex flex-row gap-1">
|
<div class="flex flex-row gap-1">
|
||||||
<a
|
<a
|
||||||
class="w-full justify-start button {% if selected_channel == channel.id %}quaternary{% else %}camo{% endif %}"
|
class="w-full justify-start button {% if selected_channel == channel.id -%}quaternary{% else %}camo{%- endif %}"
|
||||||
href="/chats/{{ selected_community }}/{{ channel.id }}"
|
href="/chats/{{ selected_community }}/{{ channel.id }}"
|
||||||
data-turbo="{{ selected_community == '0' }}"
|
data-turbo="{{ selected_community == '0' }}"
|
||||||
>
|
>
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
class="big_icon {% if selected_channel == channel.id %}quaternary{% else %}camo{% endif %}"
|
class="big_icon {% if selected_channel == channel.id -%}quaternary{% else %}camo{%- endif %}"
|
||||||
onclick="trigger('atto::hooks::dropdown', [event])"
|
onclick="trigger('atto::hooks::dropdown', [event])"
|
||||||
exclude="dropdown"
|
exclude="dropdown"
|
||||||
style="width: 32px"
|
style="width: 32px"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
{% if user.id == channel.owner %} {% if selected_community
|
{% if user.id == channel.owner -%} {% if selected_community
|
||||||
== 0 %}
|
== 0 %}
|
||||||
<button
|
<button
|
||||||
class="quaternary small"
|
class="quaternary small"
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
{{ icon "user-plus" }}
|
{{ icon "user-plus" }}
|
||||||
<span>{{ text "chats:action.add_someone" }}</span>
|
<span>{{ text "chats:action.add_someone" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="quaternary small"
|
class="quaternary small"
|
||||||
|
@ -59,17 +59,17 @@
|
||||||
{{ icon "door-open" }}
|
{{ icon "door-open" }}
|
||||||
<span>{{ text "chats:action.leave" }}</span>
|
<span>{{ text "chats:action.leave" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if selected_community == 0 and selected_channel %}
|
{% if selected_community == 0 and selected_channel -%}
|
||||||
<div class="members_list_half flex flex-col gap-2">
|
<div class="members_list_half flex flex-col gap-2">
|
||||||
{% for member in members %} {{ components::user_plate(user=member,
|
{% for member in members %} {{ components::user_plate(user=member,
|
||||||
show_kick=user.id == channel.owner) }} {% endfor %}
|
show_kick=user.id == channel.owner) }} {% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</turbo-frame>
|
</turbo-frame>
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
<turbo-frame id="stream_body_frame">
|
<turbo-frame id="stream_body_frame">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="gap-2" id="stream_body">
|
<div class="gap-2" id="stream_body">
|
||||||
{% if page != 0 %}
|
{% if page != 0 -%}
|
||||||
<div class="card flex gap-2 small tertiary flex-wrap">
|
<div class="card flex gap-2 small tertiary flex-wrap">
|
||||||
<b>{{ text "chats:label.viewing_old_messages" }}</b>
|
<b>{{ text "chats:label.viewing_old_messages" }}</b>
|
||||||
<a href="/chats/{{ community }}/{{ channel }}/_stream?page={{ page - 1}}" class="button small" onclick="window.CURRENT_PAGE -= 1">
|
<a href="/chats/{{ community }}/{{ channel }}/_stream?page={{ page - 1}}" class="button small" onclick="window.CURRENT_PAGE -= 1">
|
||||||
{{ text "chats:label.go_back" }}
|
{{ text "chats:label.go_back" }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% if message %}
|
{% if message -%}
|
||||||
<div class="card flex gap-2 small tertiary flex-wrap">
|
<div class="card flex gap-2 small tertiary flex-wrap">
|
||||||
<b>{{ text "chats:label.viewing_single_message" }}</b>
|
<b>{{ text "chats:label.viewing_single_message" }}</b>
|
||||||
<a href="/chats/{{ community }}/{{ channel }}?page={{ page }}" class="button small" onclick="window.VIEWING_SINGLE = false" target="_top">
|
<a href="/chats/{{ community }}/{{ channel }}?page={{ page }}" class="button small" onclick="window.VIEWING_SINGLE = false" target="_top">
|
||||||
|
@ -24,23 +24,23 @@
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
{{ components::message(user=message[1], message=message[0], grouped=message[2]) }}
|
{{ components::message(user=message[1], message=message[0], grouped=message[2]) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% if messages|length > 0 %}
|
{% if messages|length > 0 -%}
|
||||||
<div class="flex gap-2 w-full justify-center">
|
<div class="flex gap-2 w-full justify-center">
|
||||||
<a class="button" href="/chats/{{ community }}/{{ channel }}/_stream?page={{ page + 1 }}" onclick="window.CURRENT_PAGE += 1">
|
<a class="button" href="/chats/{{ community }}/{{ channel }}/_stream?page={{ page + 1 }}" onclick="window.CURRENT_PAGE += 1">
|
||||||
{{ icon "clock" }}
|
{{ icon "clock" }}
|
||||||
<span>{{ text "chats:label.view_older" }}</span>
|
<span>{{ text "chats:label.view_older" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if page != 0 %}
|
{% if page != 0 -%}
|
||||||
<a class="button quaternary" href="/chats/{{ community }}/{{ channel }}/_stream?page={{ page - 1 }}" onclick="window.CURRENT_PAGE -= 1">
|
<a class="button quaternary" href="/chats/{{ community }}/{{ channel }}/_stream?page={{ page - 1 }}" onclick="window.CURRENT_PAGE -= 1">
|
||||||
{{ icon "rewind" }}
|
{{ icon "rewind" }}
|
||||||
<span>{{ text "chats:label.view_more_recent" }}</span>
|
<span>{{ text "chats:label.view_more_recent" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -51,13 +51,13 @@
|
||||||
class="title name shorter flex gap-2"
|
class="title name shorter flex gap-2"
|
||||||
>
|
>
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% if community.context.display_name %}
|
{% if community.context.display_name -%}
|
||||||
{{ community.context.display_name }}
|
{{ community.context.display_name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ community.title }}
|
{{ community.title }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% if community.context.is_nsfw %}
|
{% if community.context.is_nsfw -%}
|
||||||
<span
|
<span
|
||||||
title="NSFW community"
|
title="NSFW community"
|
||||||
class="flex items-center"
|
class="flex items-center"
|
||||||
|
@ -65,10 +65,10 @@
|
||||||
>
|
>
|
||||||
{{ icon "square-asterisk" }}
|
{{ icon "square-asterisk" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
{% if user %} {% if user.id != community.owner
|
{% if user -%} {% if user.id != community.owner
|
||||||
%}
|
%}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
|
@ -92,16 +92,16 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {% endif %}
|
{%- endif %} {%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="fade">{{ community.title }}</span>
|
<span class="fade">{{ community.title }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<div class="card flex gap-2 flex-wrap" id="join_or_leave">
|
<div class="card flex gap-2 flex-wrap" id="join_or_leave">
|
||||||
{% if not is_owner %} {% if not is_joined %} {% if not
|
{% if not is_owner -%} {% if not is_joined -%} {% if not
|
||||||
is_pending %}
|
is_pending %}
|
||||||
<button class="primary" onclick="join_community()">
|
<button class="primary" onclick="join_community()">
|
||||||
{{ icon "circle-plus" }}
|
{{ icon "circle-plus" }}
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
{% endif %} {% else %}
|
{%- endif %} {% else %}
|
||||||
<button
|
<button
|
||||||
class="quaternary red"
|
class="quaternary red"
|
||||||
onclick="leave_community()"
|
onclick="leave_community()"
|
||||||
|
@ -187,7 +187,7 @@
|
||||||
<span>{{ text "communities:label.chats" }}</span>
|
<span>{{ text "communities:label.chats" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if user and can_post %}
|
{% if user and can_post -%}
|
||||||
<a
|
<a
|
||||||
href="/communities/intents/post?community={{ community.id }}"
|
href="/communities/intents/post?community={{ community.id }}"
|
||||||
class="button quaternary"
|
class="button quaternary"
|
||||||
|
@ -196,7 +196,7 @@
|
||||||
{{ icon "plus" }}
|
{{ icon "plus" }}
|
||||||
<span>{{ text "general:action.post" }}</span>
|
<span>{{ text "general:action.post" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
globalThis.leave_community = async () => {
|
globalThis.leave_community = async () => {
|
||||||
|
@ -227,7 +227,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
{% endif %} {% else %}
|
{%- endif %} {% else %}
|
||||||
<a
|
<a
|
||||||
href="/chats/{{ community.id }}/0"
|
href="/chats/{{ community.id }}/0"
|
||||||
class="button quaternary"
|
class="button quaternary"
|
||||||
|
@ -244,7 +244,8 @@
|
||||||
{{ icon "plus" }}
|
{{ icon "plus" }}
|
||||||
<span>{{ text "general:action.post" }}</span>
|
<span>{{ text "general:action.post" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %} {% if can_manage_community or is_manager %}
|
{%- endif %} {% if can_manage_community or is_manager
|
||||||
|
-%}
|
||||||
<a
|
<a
|
||||||
href="/community/{{ community.id }}/manage"
|
href="/community/{{ community.id }}/manage"
|
||||||
class="button primary"
|
class="button primary"
|
||||||
|
@ -254,10 +255,10 @@
|
||||||
>{{ text "communities:action.configure" }}</span
|
>{{ text "communities:action.configure" }}</span
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-nest flex flex-col">
|
<div class="card-nest flex flex-col">
|
||||||
|
@ -296,7 +297,7 @@
|
||||||
>{{ community.likes - community.dislikes
|
>{{ community.likes - community.dislikes
|
||||||
}}</b
|
}}</b
|
||||||
>
|
>
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<div
|
<div
|
||||||
class="flex gap-1 reactions_box"
|
class="flex gap-1 reactions_box"
|
||||||
hook="check_reactions"
|
hook="check_reactions"
|
||||||
|
@ -307,7 +308,7 @@
|
||||||
likes=community.likes,
|
likes=community.likes,
|
||||||
dislikes=community.dislikes) }}
|
dislikes=community.dislikes) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -315,7 +316,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="rhs w-full">
|
<div class="rhs w-full">
|
||||||
{% if can_read %} {% block content %}{% endblock %} {% else %}
|
{% if can_read -%} {% block content %}{% endblock %} {% else %}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
{{ icon "frown" }}
|
{{ icon "frown" }}
|
||||||
|
@ -331,7 +332,7 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<title>Create post - {{ config.name }}</title>
|
<title>Create post - {{ config.name }}</title>
|
||||||
{% endblock %} {% block body %} {{ macros::nav() }}
|
{% endblock %} {% block body %} {{ macros::nav() }}
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{% if drafts|length > 0 %}
|
{% if drafts|length > 0 -%}
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
<a href="#/create" data-tab-button="create" class="active">
|
<a href="#/create" data-tab-button="create" class="active">
|
||||||
{{ icon "plus" }}
|
{{ icon "plus" }}
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
<span>{{ text "communities:label.drafts" }}</span>
|
<span>{{ text "communities:label.drafts" }}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest" data-tab="create">
|
<div class="card-nest" data-tab="create">
|
||||||
<div class="card small flex items-center justify-between gap-2">
|
<div class="card small flex items-center justify-between gap-2">
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card tertiary flex flex-col gap-2">
|
<div class="card tertiary flex flex-col gap-2">
|
||||||
{% if draft %}
|
{% if draft -%}
|
||||||
<div
|
<div
|
||||||
class="card secondary w-full flex items-center justify-between gap-2 small"
|
class="card secondary w-full flex items-center justify-between gap-2 small"
|
||||||
>
|
>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex flex-row gap-2 items-center">
|
<div class="card small flex flex-row gap-2 items-center">
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
value="{{ config.town_square }}"
|
value="{{ config.town_square }}"
|
||||||
selected="{% if not selected_community %}true{% else %}false{% endif %}"
|
selected="{% if not selected_community -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
{{ text "auth:link.my_profile" }}
|
{{ text "auth:link.my_profile" }}
|
||||||
</option>
|
</option>
|
||||||
|
@ -75,14 +75,14 @@
|
||||||
{% for community in communities %}
|
{% for community in communities %}
|
||||||
<option
|
<option
|
||||||
value="{{ community.id }}"
|
value="{{ community.id }}"
|
||||||
selected="{% if selected_community == community.id %}true{% else %}false{% endif %}"
|
selected="{% if selected_community == community.id -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% if community.context.display_name %}
|
{% if community.context.display_name -%}
|
||||||
{{ community.context.display_name }}
|
{{ community.context.display_name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ community.title }}
|
{{ community.title }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</option>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
minlength="2"
|
minlength="2"
|
||||||
maxlength="4096"
|
maxlength="4096"
|
||||||
>
|
>
|
||||||
{% if draft %}{{ draft.content }}{% endif %}</textarea
|
{% if draft -%}{{ draft.content }}{%- endif %}</textarea
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -114,9 +114,9 @@
|
||||||
<div class="flex justify-between gap-2">
|
<div class="flex justify-between gap-2">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
{{ components::emoji_picker(element_id="content",
|
{{ components::emoji_picker(element_id="content",
|
||||||
render_dialog=true) }} {% if is_supporter %} {{
|
render_dialog=true) }} {% if is_supporter -%} {{
|
||||||
components::file_picker(files_list_id="files_list")
|
components::file_picker(files_list_id="files_list")
|
||||||
}} {% endif %}
|
}} {%- endif %}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="small square quaternary"
|
class="small square quaternary"
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
{% if draft %}
|
{% if draft -%}
|
||||||
<button
|
<button
|
||||||
class="secondary small square"
|
class="secondary small square"
|
||||||
title="Save as Draft"
|
title="Save as Draft"
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
>
|
>
|
||||||
{{ icon "notepad-text-dashed" }}
|
{{ icon "notepad-text-dashed" }}
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<button class="primary">
|
<button class="primary">
|
||||||
{{ text "communities:action.create" }}
|
{{ text "communities:action.create" }}
|
||||||
|
@ -221,7 +221,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove draft
|
// remove draft
|
||||||
// {% if draft %}
|
// {% if draft -%}
|
||||||
if ("{{ draft.id }}") {
|
if ("{{ draft.id }}") {
|
||||||
fetch("/api/v1/drafts/{{ draft.id }}", {
|
fetch("/api/v1/drafts/{{ draft.id }}", {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
|
@ -234,7 +234,7 @@
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// {% endif %}
|
// {%- endif %}
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -325,7 +325,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if drafts|length > 0 %}
|
{% if drafts|length > 0 -%}
|
||||||
<div class="card-nest tertiary hidden" data-tab="drafts">
|
<div class="card-nest tertiary hidden" data-tab="drafts">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
{{ icon "notepad-text-dashed" }}
|
{{ icon "notepad-text-dashed" }}
|
||||||
|
@ -384,7 +384,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -12,15 +12,15 @@
|
||||||
<div class="card flex flex-col gap-4">
|
<div class="card flex flex-col gap-4">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% for post in pinned %}
|
{% for post in pinned %}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% if post[0].context.repost and post[0].context.repost.reposting -%}
|
||||||
{{ components::repost(repost=post[2], post=post[0], owner=post[1], secondary=true, show_community=false, can_manage_post=can_manage_posts) }}
|
{{ components::repost(repost=post[2], post=post[0], owner=post[1], secondary=true, show_community=false, can_manage_post=can_manage_posts) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[3], secondary=true, show_community=false, can_manage_post=can_manage_posts) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[3], secondary=true, show_community=false, can_manage_post=can_manage_posts) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex gap-2 items-center">
|
<div class="card small flex gap-2 items-center">
|
||||||
|
@ -31,11 +31,11 @@
|
||||||
<div class="card flex flex-col gap-4">
|
<div class="card flex flex-col gap-4">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% for post in feed %}
|
{% for post in feed %}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% if post[0].context.repost and post[0].context.repost.reposting -%}
|
||||||
{{ components::repost(repost=post[2], post=post[0], owner=post[1], secondary=true, show_community=false, can_manage_post=can_manage_posts) }}
|
{{ components::repost(repost=post[2], post=post[0], owner=post[1], secondary=true, show_community=false, can_manage_post=can_manage_posts) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[3], secondary=true, show_community=false, can_manage_post=can_manage_posts) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[3], secondary=true, show_community=false, can_manage_post=can_manage_posts) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ components::pagination(page=page, items=feed|length) }}
|
{{ components::pagination(page=page, items=feed|length) }}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<title>My communities - {{ config.name }}</title>
|
<title>My communities - {{ config.name }}</title>
|
||||||
{% endblock %} {% block body %} {{ macros::nav(selected="communities") }}
|
{% endblock %} {% block body %} {{ macros::nav(selected="communities") }}
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small">
|
<div class="card small">
|
||||||
<b>{{ text "communities:label.create_new" }}</b>
|
<b>{{ text "communities:label.create_new" }}</b>
|
||||||
|
@ -31,8 +31,8 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if list|length >= 4 %} {{ components::supporter_ad(body="Become a
|
{% if list|length >= 4 -%} {{ components::supporter_ad(body="Become a
|
||||||
supporter to create up to 10 communities!") }} {% endif %} {% endif %}
|
supporter to create up to 10 communities!") }} {%- endif %} {%- endif %}
|
||||||
|
|
||||||
<div class="card-nest w-full">
|
<div class="card-nest w-full">
|
||||||
<div class="card small flex items-center justify-between gap-2">
|
<div class="card small flex items-center justify-between gap-2">
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card flex flex-col gap-4">
|
<div class="card flex flex-col gap-4">
|
||||||
{% if page == 0 %}
|
{% if page == 0 -%}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
{{ icon "crown" }}
|
{{ icon "crown" }}
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
{{ components::user_card(user=owner) }}
|
{{ components::user_card(user=owner) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% for item in list %}
|
{% for item in list %}
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<span class="date">{{ item[0].created }}</span>
|
<span class="date">{{ item[0].created }}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{% if can_manage_roles %}
|
{% if can_manage_roles -%}
|
||||||
<a
|
<a
|
||||||
href="/community/{{ community.id }}/manage?uid={{ item[1].id }}#/members"
|
href="/community/{{ community.id }}/manage?uid={{ item[1].id }}#/members"
|
||||||
class="button small quaternary"
|
class="button small quaternary"
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
{{ icon "pencil" }}
|
{{ icon "pencil" }}
|
||||||
<span>{{ text "general:action.manage" }}</span>
|
<span>{{ text "general:action.manage" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ components::user_card(user=item[1]) }}
|
{{ components::user_card(user=item[1]) }}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
{{ components::emoji_picker(element_id="content",
|
{{ components::emoji_picker(element_id="content",
|
||||||
render_dialog=true) }} {% if is_supporter %} {{
|
render_dialog=true) }} {% if is_supporter -%} {{
|
||||||
components::file_picker(files_list_id="files_list") }} {% endif
|
components::file_picker(files_list_id="files_list") }} {% endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest w-full" data-tab="replies">
|
<div class="card-nest w-full" data-tab="replies">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
{{ macros::community_nav(community=community, selected="questions") }}
|
{{ macros::community_nav(community=community, selected="questions") }}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% if user and can_post %}
|
{% if user and can_post -%}
|
||||||
<div style="display: contents">
|
<div style="display: contents">
|
||||||
{{ components::create_question_form(community=community.id,
|
{{ components::create_question_form(community=community.id,
|
||||||
is_global=true) }}
|
is_global=true) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex gap-2 items-center">
|
<div class="card small flex gap-2 items-center">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
{{ icon "search" }}
|
{{ icon "search" }}
|
||||||
<span>{{ text "communities:label.search" }}</span>
|
<span>{{ text "general:link.search" }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form class="card flex flex-col gap-4">
|
<form class="card flex flex-col gap-4">
|
||||||
|
|
|
@ -18,17 +18,17 @@
|
||||||
<span>{{ text "communities:tab.members" }}</span>
|
<span>{{ text "communities:tab.members" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if can_manage_channels %}
|
{% if can_manage_channels -%}
|
||||||
<a href="#/channels" data-tab-button="channels">
|
<a href="#/channels" data-tab-button="channels">
|
||||||
{{ icon "rss" }}
|
{{ icon "rss" }}
|
||||||
<span>{{ text "communities:tab.channels" }}</span>
|
<span>{{ text "communities:tab.channels" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %} {% if can_manage_emojis %}
|
{%- endif %} {% if can_manage_emojis -%}
|
||||||
<a href="#/emojis" data-tab-button="emojis">
|
<a href="#/emojis" data-tab-button="emojis">
|
||||||
{{ icon "smile" }}
|
{{ icon "smile" }}
|
||||||
<span>{{ text "communities:tab.emojis" }}</span>
|
<span>{{ text "communities:tab.emojis" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full flex flex-col gap-2" data-tab="general">
|
<div class="w-full flex flex-col gap-2" data-tab="general">
|
||||||
|
@ -42,13 +42,13 @@
|
||||||
<select onchange="save_access(event, 'read')">
|
<select onchange="save_access(event, 'read')">
|
||||||
<option
|
<option
|
||||||
value="Everybody"
|
value="Everybody"
|
||||||
selected="{% if community.read_access == 'Everybody' %}true{% else %}false{% endif %}"
|
selected="{% if community.read_access == 'Everybody' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Everybody
|
Everybody
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Joined"
|
value="Joined"
|
||||||
selected="{% if community.read_access == 'Joined' %}true{% else %}false{% endif %}"
|
selected="{% if community.read_access == 'Joined' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Joined
|
Joined
|
||||||
</option>
|
</option>
|
||||||
|
@ -65,19 +65,19 @@
|
||||||
<select onchange="save_access(event, 'join')">
|
<select onchange="save_access(event, 'join')">
|
||||||
<option
|
<option
|
||||||
value="Everybody"
|
value="Everybody"
|
||||||
selected="{% if community.join_access == 'Everybody' %}true{% else %}false{% endif %}"
|
selected="{% if community.join_access == 'Everybody' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Everybody
|
Everybody
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Request"
|
value="Request"
|
||||||
selected="{% if community.join_access == 'Request' %}true{% else %}false{% endif %}"
|
selected="{% if community.join_access == 'Request' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Request
|
Request
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Nobody"
|
value="Nobody"
|
||||||
selected="{% if community.join_access == 'Nobody' %}true{% else %}false{% endif %}"
|
selected="{% if community.join_access == 'Nobody' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Nobody
|
Nobody
|
||||||
</option>
|
</option>
|
||||||
|
@ -94,19 +94,19 @@
|
||||||
<select onchange="save_access(event, 'write')">
|
<select onchange="save_access(event, 'write')">
|
||||||
<option
|
<option
|
||||||
value="Everybody"
|
value="Everybody"
|
||||||
selected="{% if community.write_access == 'Everybody' %}true{% else %}false{% endif %}"
|
selected="{% if community.write_access == 'Everybody' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Everybody
|
Everybody
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Joined"
|
value="Joined"
|
||||||
selected="{% if community.write_access == 'Joined' %}true{% else %}false{% endif %}"
|
selected="{% if community.write_access == 'Joined' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Joined
|
Joined
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Owner"
|
value="Owner"
|
||||||
selected="{% if community.write_access == 'Owner' %}true{% else %}false{% endif %}"
|
selected="{% if community.write_access == 'Owner' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Owner only
|
Owner only
|
||||||
</option>
|
</option>
|
||||||
|
@ -267,7 +267,7 @@
|
||||||
<div class="card flex flex-col gap-2 w-full" id="membership_info"></div>
|
<div class="card flex flex-col gap-2 w-full" id="membership_info"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if can_manage_channels %}
|
{% if can_manage_channels -%}
|
||||||
<div
|
<div
|
||||||
class="card tertiary w-full hidden flex flex-col gap-2"
|
class="card tertiary w-full hidden flex flex-col gap-2"
|
||||||
data-tab="channels"
|
data-tab="channels"
|
||||||
|
@ -441,7 +441,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endif %} {% if can_manage_emojis %}
|
{%- endif %} {% if can_manage_emojis -%}
|
||||||
<div
|
<div
|
||||||
class="card tertiary w-full hidden flex flex-col gap-2"
|
class="card tertiary w-full hidden flex flex-col gap-2"
|
||||||
data-tab="emojis"
|
data-tab="emojis"
|
||||||
|
@ -602,7 +602,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
style="--size: {{ size }}"
|
style="--size: {{ size }}"
|
||||||
/>
|
/>
|
||||||
{%- endmacro %} {% macro community_avatar(id, community=false, size="24px") -%}
|
{%- endmacro %} {% macro community_avatar(id, community=false, size="24px") -%}
|
||||||
{% if community %}
|
{% if community -%}
|
||||||
<img
|
<img
|
||||||
src="/api/v1/communities/{{ id }}/avatar"
|
src="/api/v1/communities/{{ id }}/avatar"
|
||||||
alt="{{ community.title }}'s avatar"
|
alt="{{ community.title }}'s avatar"
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
style="--size: {{ size }}"
|
style="--size: {{ size }}"
|
||||||
/>
|
/>
|
||||||
{% endif %} {%- endmacro %} {% macro banner(username,
|
{%- endif %} {%- endmacro %} {% macro banner(username,
|
||||||
border_radius="var(--radius)") -%}
|
border_radius="var(--radius)") -%}
|
||||||
<img
|
<img
|
||||||
title="{{ username }}'s banner"
|
title="{{ username }}'s banner"
|
||||||
|
@ -49,7 +49,7 @@ community %}
|
||||||
class="banner shadow"
|
class="banner shadow"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
{% endif %} {%- endmacro %} {% macro community_listing_card(community) -%}
|
{%- endif %} {%- endmacro %} {% macro community_listing_card(community) -%}
|
||||||
<a
|
<a
|
||||||
class="card secondary w-full flex items-center gap-4"
|
class="card secondary w-full flex items-center gap-4"
|
||||||
href="/community/{{ community.title }}"
|
href="/community/{{ community.title }}"
|
||||||
|
@ -63,34 +63,34 @@ community %}
|
||||||
</a>
|
</a>
|
||||||
{%- endmacro %} {% macro username(user) -%}
|
{%- endmacro %} {% macro username(user) -%}
|
||||||
<div style="display: contents">
|
<div style="display: contents">
|
||||||
{% if user.settings.display_name %} {{ user.settings.display_name }} {% else
|
{% if user.settings.display_name -%} {{ user.settings.display_name }} {%
|
||||||
%} {{ user.username }} {% endif %}
|
else %} {{ user.username }} {%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{%- endmacro %} {% macro likes(id, asset_type, likes=0, dislikes=0,
|
{%- endmacro %} {% macro likes(id, asset_type, likes=0, dislikes=0,
|
||||||
secondary=false) -%}
|
secondary=false) -%}
|
||||||
<button
|
<button
|
||||||
title="Like"
|
title="Like"
|
||||||
class="{% if secondary %}quaternary{% else %}camo{% endif %} small"
|
class="{% if secondary -%}quaternary{% else %}camo{%- endif %} small"
|
||||||
hook_element="reaction.like"
|
hook_element="reaction.like"
|
||||||
onclick="trigger('me::react', [event.target, '{{ id }}', '{{ asset_type }}', true])"
|
onclick="trigger('me::react', [event.target, '{{ id }}', '{{ asset_type }}', true])"
|
||||||
>
|
>
|
||||||
{{ icon "heart" }} {% if likes > 0 %}
|
{{ icon "heart" }} {% if likes > 0 -%}
|
||||||
<span>{{ likes }}</span>
|
<span>{{ likes }}</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{% if not user or not user.settings.hide_dislikes %}
|
{% if not user or not user.settings.hide_dislikes -%}
|
||||||
<button
|
<button
|
||||||
title="Dislike"
|
title="Dislike"
|
||||||
class="{% if secondary %}quaternary{% else %}camo{% endif %} small"
|
class="{% if secondary -%}quaternary{% else %}camo{%- endif %} small"
|
||||||
hook_element="reaction.dislike"
|
hook_element="reaction.dislike"
|
||||||
onclick="trigger('me::react', [event.target, '{{ id }}', '{{ asset_type }}', false])"
|
onclick="trigger('me::react', [event.target, '{{ id }}', '{{ asset_type }}', false])"
|
||||||
>
|
>
|
||||||
{{ icon "heart-crack" }} {% if dislikes > 0 %}
|
{{ icon "heart-crack" }} {% if dislikes > 0 -%}
|
||||||
<span>{{ dislikes }}</span>
|
<span>{{ dislikes }}</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {%- endmacro %} {% macro full_username(user) -%}
|
{%- endif %} {%- endmacro %} {% macro full_username(user) -%}
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<a
|
<a
|
||||||
href="/@{{ user.username }}"
|
href="/@{{ user.username }}"
|
||||||
|
@ -101,7 +101,7 @@ secondary=false) -%}
|
||||||
{{ self::username(user=user) }}
|
{{ self::username(user=user) }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{{ self::online_indicator(user=user) }} {% if user.is_verified %}
|
{{ self::online_indicator(user=user) }} {% if user.is_verified -%}
|
||||||
<span
|
<span
|
||||||
title="Verified"
|
title="Verified"
|
||||||
style="color: var(--color-primary)"
|
style="color: var(--color-primary)"
|
||||||
|
@ -109,7 +109,7 @@ secondary=false) -%}
|
||||||
>
|
>
|
||||||
{{ icon "badge-check" }}
|
{{ icon "badge-check" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{%- endmacro %} {% macro repost(repost, post, owner, secondary=false,
|
{%- endmacro %} {% macro repost(repost, post, owner, secondary=false,
|
||||||
community=false, show_community=true, can_manage_post=false) -%}
|
community=false, show_community=true, can_manage_post=false) -%}
|
||||||
|
@ -123,8 +123,8 @@ community=false, show_community=true, can_manage_post=false, repost=false,
|
||||||
expect_repost=false) -%} {% if community and show_community and community.id !=
|
expect_repost=false) -%} {% if community and show_community and community.id !=
|
||||||
config.town_square or question %}
|
config.town_square or question %}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
{% if question %} {{ self::question(question=question[0], owner=question[1])
|
{% if question -%} {{ self::question(question=question[0],
|
||||||
}} {% else %}
|
owner=question[1]) }} {% else %}
|
||||||
<div class="card small">
|
<div class="card small">
|
||||||
<a
|
<a
|
||||||
href="/api/v1/communities/find/{{ post.community }}"
|
href="/api/v1/communities/find/{{ post.community }}"
|
||||||
|
@ -133,56 +133,56 @@ config.town_square or question %}
|
||||||
{{ self::community_avatar(id=post.community, community=community) }}
|
{{ self::community_avatar(id=post.community, community=community) }}
|
||||||
<b>
|
<b>
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% if community.context.display_name %}
|
{% if community.context.display_name -%}
|
||||||
{{ community.context.display_name }}
|
{{ community.context.display_name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ community.title }}
|
{{ community.title }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</b>
|
</b>
|
||||||
|
|
||||||
{% if post.context.is_pinned or post.context.is_profile_pinned %} {{
|
{% if post.context.is_pinned or post.context.is_profile_pinned -%}
|
||||||
icon "pin" }} {% endif %}
|
{{ icon "pin" }} {%- endif %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {% endif %}
|
{%- endif %} {%- endif %}
|
||||||
<div
|
<div
|
||||||
class="card flex flex-col gap-2 {% if secondary %}secondary{% endif %}"
|
class="card flex flex-col gap-2 {% if secondary -%}secondary{%- endif %}"
|
||||||
id="post:{{ post.id }}"
|
id="post:{{ post.id }}"
|
||||||
data-community="{{ post.community }}"
|
data-community="{{ post.community }}"
|
||||||
data-ownsup="{{ owner.permissions|has_supporter }}"
|
data-ownsup="{{ owner.permissions|has_supporter }}"
|
||||||
hook="verify_emojis"
|
hook="verify_emojis"
|
||||||
>
|
>
|
||||||
<div class="w-full flex gap-2">
|
<div class="w-full flex gap-2">
|
||||||
{% if not expect_repost %}
|
{% if not expect_repost -%}
|
||||||
<a href="/@{{ owner.username }}">
|
<a href="/@{{ owner.username }}">
|
||||||
{{ self::avatar(username=owner.username, size="52px",
|
{{ self::avatar(username=owner.username, size="52px",
|
||||||
selector_type="username") }}
|
selector_type="username") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-col w-full gap-1 post_right {% if expect_repost %}repost{% endif %}"
|
class="flex flex-col w-full gap-1 post_right {% if expect_repost -%}repost{%- endif %}"
|
||||||
>
|
>
|
||||||
<div class="flex flex-wrap gap-2 items-center">
|
<div class="flex flex-wrap gap-2 items-center">
|
||||||
{% if expect_repost %}
|
{% if expect_repost -%}
|
||||||
<a href="/@{{ owner.username }}">
|
<a href="/@{{ owner.username }}">
|
||||||
{{ self::avatar(username=owner.username, size="24px",
|
{{ self::avatar(username=owner.username, size="24px",
|
||||||
selector_type="username") }}
|
selector_type="username") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<span class="name"
|
<span class="name"
|
||||||
>{{ self::full_username(user=owner) }}</span
|
>{{ self::full_username(user=owner) }}</span
|
||||||
>
|
>
|
||||||
|
|
||||||
{% if post.context.edited != 0 %}
|
{% if post.context.edited != 0 -%}
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<span class="fade date">{{ post.context.edited }}</span>
|
<span class="fade date">{{ post.context.edited }}</span>
|
||||||
<sup title="Edited">*</sup>
|
<sup title="Edited">*</sup>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="fade date">{{ post.created }}</span>
|
<span class="fade date">{{ post.created }}</span>
|
||||||
{% endif %} {% if post.context.is_nsfw %}
|
{%- endif %} {% if post.context.is_nsfw -%}
|
||||||
<span
|
<span
|
||||||
title="NSFW post"
|
title="NSFW post"
|
||||||
class="flex items-center"
|
class="flex items-center"
|
||||||
|
@ -190,7 +190,7 @@ config.town_square or question %}
|
||||||
>
|
>
|
||||||
{{ icon "square-asterisk" }}
|
{{ icon "square-asterisk" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %} {% if post.context.repost and
|
{%- endif %} {% if post.context.repost and
|
||||||
post.context.repost.reposting %}
|
post.context.repost.reposting %}
|
||||||
<span
|
<span
|
||||||
title="Repost"
|
title="Repost"
|
||||||
|
@ -199,7 +199,7 @@ config.town_square or question %}
|
||||||
>
|
>
|
||||||
{{ icon "repeat-2" }}
|
{{ icon "repeat-2" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %} {% if post.community == config.town_square %}
|
{%- endif %} {% if post.community == config.town_square -%}
|
||||||
<span
|
<span
|
||||||
title="Posted to profile"
|
title="Posted to profile"
|
||||||
class="flex items-center"
|
class="flex items-center"
|
||||||
|
@ -207,7 +207,7 @@ config.town_square or question %}
|
||||||
>
|
>
|
||||||
{{ icon "user-round" }}
|
{{ icon "user-round" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %} {% if post.is_deleted %}
|
{%- endif %} {% if post.is_deleted -%}
|
||||||
<span
|
<span
|
||||||
title="Deleted"
|
title="Deleted"
|
||||||
class="flex items-center"
|
class="flex items-center"
|
||||||
|
@ -215,10 +215,10 @@ config.town_square or question %}
|
||||||
>
|
>
|
||||||
{{ icon "trash-2" }}
|
{{ icon "trash-2" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if not post.context.content_warning %}
|
{% if not post.context.content_warning -%}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<span
|
<span
|
||||||
id="post-content:{{ post.id }}"
|
id="post-content:{{ post.id }}"
|
||||||
|
@ -227,16 +227,16 @@ config.town_square or question %}
|
||||||
>
|
>
|
||||||
{{ post.content|markdown|safe }}
|
{{ post.content|markdown|safe }}
|
||||||
|
|
||||||
{% if expect_repost %}
|
{% if expect_repost -%}
|
||||||
{% if repost %}
|
{% if repost -%}
|
||||||
{{ self::post(post=repost[1], owner=repost[0], secondary=not secondary, community=false, show_community=false, can_manage_post=false) }}
|
{{ self::post(post=repost[1], owner=repost[0], secondary=not secondary, community=false, show_community=false, can_manage_post=false) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="card tertiary red flex items-center gap-2">
|
<div class="card tertiary red flex items-center gap-2">
|
||||||
{{ icon "frown" }}
|
{{ icon "frown" }}
|
||||||
<span>Could not find original post...</span>
|
<span>Could not find original post...</span>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{{ self::post_media(upload_ids=post.uploads) }} {% else %}
|
{{ self::post_media(upload_ids=post.uploads) }} {% else %}
|
||||||
|
@ -257,22 +257,22 @@ config.town_square or question %}
|
||||||
>
|
>
|
||||||
{{ post.content|markdown|safe }}
|
{{ post.content|markdown|safe }}
|
||||||
|
|
||||||
{% if expect_repost %}
|
{% if expect_repost -%}
|
||||||
{% if repost %}
|
{% if repost -%}
|
||||||
{{ self::post(post=repost[1], owner=repost[0], secondary=not secondary, community=false, show_community=false, can_manage_post=false) }}
|
{{ self::post(post=repost[1], owner=repost[0], secondary=not secondary, community=false, show_community=false, can_manage_post=false) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="card tertiary red flex items-center gap-2">
|
<div class="card tertiary red flex items-center gap-2">
|
||||||
{{ icon "frown" }}
|
{{ icon "frown" }}
|
||||||
<span>Could not find original post...</span>
|
<span>Could not find original post...</span>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{{ self::post_media(upload_ids=post.uploads) }}
|
{{ self::post_media(upload_ids=post.uploads) }}
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-2 fade">
|
<div class="flex flex-wrap gap-2 fade">
|
||||||
{% for tag in post.context.tags %}
|
{% for tag in post.context.tags %}
|
||||||
|
@ -287,20 +287,20 @@ config.town_square or question %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-between items-center gap-2 w-full">
|
<div class="flex justify-between items-center gap-2 w-full">
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<div
|
<div
|
||||||
class="flex gap-1 reactions_box"
|
class="flex gap-1 reactions_box"
|
||||||
hook="check_reactions"
|
hook="check_reactions"
|
||||||
hook-arg:id="{{ post.id }}"
|
hook-arg:id="{{ post.id }}"
|
||||||
>
|
>
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% if post.context.reactions_enabled %}
|
{% if post.context.reactions_enabled -%}
|
||||||
{% if post.content|length > 0 %}
|
{% if post.content|length > 0 -%}
|
||||||
{{ self::likes(id=post.id, asset_type="Post", likes=post.likes, dislikes=post.dislikes) }}
|
{{ self::likes(id=post.id, asset_type="Post", likes=post.likes, dislikes=post.dislikes) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% if post.context.repost and post.context.repost.reposting %}
|
{% if post.context.repost and post.context.repost.reposting -%}
|
||||||
<a
|
<a
|
||||||
href="/post/{{ post.context.repost.reposting }}"
|
href="/post/{{ post.context.repost.reposting }}"
|
||||||
class="button small camo"
|
class="button small camo"
|
||||||
|
@ -308,11 +308,11 @@ config.town_square or question %}
|
||||||
>
|
>
|
||||||
{{ icon "expand" }}
|
{{ icon "expand" }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div></div>
|
<div></div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="flex gap-1 buttons_box">
|
<div class="flex gap-1 buttons_box">
|
||||||
<a href="/post/{{ post.id }}" class="button camo small">
|
<a href="/post/{{ post.id }}" class="button camo small">
|
||||||
|
@ -328,7 +328,7 @@ config.town_square or question %}
|
||||||
{{ icon "external-link" }}
|
{{ icon "external-link" }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
class="camo small"
|
class="camo small"
|
||||||
|
@ -357,7 +357,7 @@ config.town_square or question %}
|
||||||
>{{ text "communities:label.quote_post" }}</span
|
>{{ text "communities:label.quote_post" }}</span
|
||||||
>
|
>
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {% if user.id != post.owner %}
|
{%- endif %} {% if user.id != post.owner -%}
|
||||||
<b class="title">{{ text "general:label.safety" }}</b>
|
<b class="title">{{ text "general:label.safety" }}</b>
|
||||||
<button
|
<button
|
||||||
class="red"
|
class="red"
|
||||||
|
@ -366,10 +366,10 @@ config.town_square or question %}
|
||||||
{{ icon "flag" }}
|
{{ icon "flag" }}
|
||||||
<span>{{ text "general:action.report" }}</span>
|
<span>{{ text "general:action.report" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {% if (user.id == post.owner) or is_helper
|
{%- endif %} {% if (user.id == post.owner) or is_helper
|
||||||
or can_manage_post %}
|
or can_manage_post %}
|
||||||
<b class="title">{{ text "general:action.manage" }}</b>
|
<b class="title">{{ text "general:action.manage" }}</b>
|
||||||
{% if user.id == post.owner %}
|
{% if user.id == post.owner -%}
|
||||||
<a href="/post/{{ post.id }}#/edit">
|
<a href="/post/{{ post.id }}#/edit">
|
||||||
{{ icon "pen" }}
|
{{ icon "pen" }}
|
||||||
<span
|
<span
|
||||||
|
@ -377,7 +377,7 @@ config.town_square or question %}
|
||||||
}}</span
|
}}</span
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<a href="/post/{{ post.id }}#/configure">
|
<a href="/post/{{ post.id }}#/configure">
|
||||||
{{ icon "settings" }}
|
{{ icon "settings" }}
|
||||||
|
@ -386,7 +386,7 @@ config.town_square or question %}
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if not post.is_deleted %}
|
{% if not post.is_deleted -%}
|
||||||
<button
|
<button
|
||||||
class="red"
|
class="red"
|
||||||
onclick="trigger('me::remove_post', ['{{ post.id }}'])"
|
onclick="trigger('me::remove_post', ['{{ post.id }}'])"
|
||||||
|
@ -394,7 +394,7 @@ config.town_square or question %}
|
||||||
{{ icon "trash" }}
|
{{ icon "trash" }}
|
||||||
<span>{{ text "general:action.delete" }}</span>
|
<span>{{ text "general:action.delete" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {% if is_helper and post.is_deleted %}
|
{%- endif %} {% if is_helper and post.is_deleted -%}
|
||||||
<button
|
<button
|
||||||
class="red"
|
class="red"
|
||||||
onclick="trigger('me::purge_post', ['{{ post.id }}'])"
|
onclick="trigger('me::purge_post', ['{{ post.id }}'])"
|
||||||
|
@ -410,17 +410,17 @@ config.town_square or question %}
|
||||||
{{ icon "undo" }}
|
{{ icon "undo" }}
|
||||||
<span>{{ text "general:action.restore" }}</span>
|
<span>{{ text "general:action.restore" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {% endif %}
|
{%- endif %} {%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if community and show_community and community.id != config.town_square or
|
{% if community and show_community and community.id != config.town_square or
|
||||||
question %}
|
question %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %} {% macro post_media(upload_ids) -%} {% if
|
{%- endif %} {%- endmacro %} {% macro post_media(upload_ids) -%} {% if
|
||||||
upload_ids|length > 0%}
|
upload_ids|length > 0%}
|
||||||
<div class="media_gallery gap-2">
|
<div class="media_gallery gap-2">
|
||||||
{% for upload in upload_ids %}
|
{% for upload in upload_ids %}
|
||||||
|
@ -431,10 +431,10 @@ upload_ids|length > 0%}
|
||||||
/>
|
/>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %} {% macro notification(notification) -%}
|
{%- endif %} {%- endmacro %} {% macro notification(notification) -%}
|
||||||
<div class="w-full card-nest">
|
<div class="w-full card-nest">
|
||||||
<div class="card small notif_title flex items-center">
|
<div class="card small notif_title flex items-center">
|
||||||
{% if not notification.read %}
|
{% if not notification.read -%}
|
||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
|
@ -443,7 +443,7 @@ upload_ids|length > 0%}
|
||||||
>
|
>
|
||||||
<circle cx="12" cy="12" r="6"></circle>
|
<circle cx="12" cy="12" r="6"></circle>
|
||||||
</svg>
|
</svg>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
<b class="no_p_margin">{{ notification.title|markdown|safe }}</b>
|
<b class="no_p_margin">{{ notification.title|markdown|safe }}</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ upload_ids|length > 0%}
|
||||||
>
|
>
|
||||||
|
|
||||||
<div class="card secondary w-full flex flex-wrap gap-2">
|
<div class="card secondary w-full flex flex-wrap gap-2">
|
||||||
{% if notification.read %}
|
{% if notification.read -%}
|
||||||
<button
|
<button
|
||||||
class="tertiary"
|
class="tertiary"
|
||||||
onclick="trigger('me::update_notification_read_status', ['{{ notification.id }}', false])"
|
onclick="trigger('me::update_notification_read_status', ['{{ notification.id }}', false])"
|
||||||
|
@ -469,7 +469,7 @@ upload_ids|length > 0%}
|
||||||
{{ icon "check" }}
|
{{ icon "check" }}
|
||||||
<span>{{ text "notifs:action.mark_as_read" }}</span>
|
<span>{{ text "notifs:action.mark_as_read" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="red tertiary"
|
class="red tertiary"
|
||||||
|
@ -497,7 +497,7 @@ upload_ids|length > 0%}
|
||||||
</a>
|
</a>
|
||||||
{%- endmacro %} {% macro pagination(page=0, items=0, key="", value="") -%}
|
{%- endmacro %} {% macro pagination(page=0, items=0, key="", value="") -%}
|
||||||
<div class="flex justify-between gap-2 w-full">
|
<div class="flex justify-between gap-2 w-full">
|
||||||
{% if page > 0 %}
|
{% if page > 0 -%}
|
||||||
<a
|
<a
|
||||||
class="button quaternary"
|
class="button quaternary"
|
||||||
href="?page={{ page - 1 }}{{ key }}{{ value }}"
|
href="?page={{ page - 1 }}{{ key }}{{ value }}"
|
||||||
|
@ -507,7 +507,7 @@ upload_ids|length > 0%}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div></div>
|
<div></div>
|
||||||
{% endif %} {% if items != 0 %}
|
{%- endif %} {% if items != 0 -%}
|
||||||
<a
|
<a
|
||||||
class="button quaternary"
|
class="button quaternary"
|
||||||
href="?page={{ page + 1 }}{{ key }}{{ value }}"
|
href="?page={{ page + 1 }}{{ key }}{{ value }}"
|
||||||
|
@ -515,7 +515,7 @@ upload_ids|length > 0%}
|
||||||
<span>{{ text "general:link.next" }}</span>
|
<span>{{ text "general:link.next" }}</span>
|
||||||
{{ icon "arrow-right"}}
|
{{ icon "arrow-right"}}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{%- endmacro %} {% macro online_indicator(user) -%} {% if not
|
{%- endmacro %} {% macro online_indicator(user) -%} {% if not
|
||||||
user.settings.private_last_seen or is_helper %}
|
user.settings.private_last_seen or is_helper %}
|
||||||
|
@ -569,26 +569,26 @@ user.settings.private_last_seen or is_helper %}
|
||||||
<circle cx="12" cy="12" r="6"></circle>
|
<circle cx="12" cy="12" r="6"></circle>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %} {% macro theme(user, theme_preference) -%} {% if
|
{%- endif %} {%- endmacro %} {% macro theme(user, theme_preference) -%} {% if
|
||||||
user %} {% if user.settings.theme_hue %}
|
user %} {% if user.settings.theme_hue -%}
|
||||||
<style>
|
<style>
|
||||||
:root, * {
|
:root, * {
|
||||||
--hue: {{ user.settings.theme_hue }} !important;
|
--hue: {{ user.settings.theme_hue }} !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endif %} {% if user.settings.theme_sat %}
|
{%- endif %} {% if user.settings.theme_sat -%}
|
||||||
<style>
|
<style>
|
||||||
:root, * {
|
:root, * {
|
||||||
--sat: {{ user.settings.theme_sat }} !important;
|
--sat: {{ user.settings.theme_sat }} !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endif %} {% if user.settings.theme_lit %}
|
{%- endif %} {% if user.settings.theme_lit -%}
|
||||||
<style>
|
<style>
|
||||||
:root, * {
|
:root, * {
|
||||||
--lit: {{ user.settings.theme_lit }} !important;
|
--lit: {{ user.settings.theme_lit }} !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endif %} {% if theme_preference %}
|
{%- endif %} {% if theme_preference -%}
|
||||||
<script>
|
<script>
|
||||||
function match_user_theme() {
|
function match_user_theme() {
|
||||||
const pref = "{{ theme_preference }}".toLowerCase();
|
const pref = "{{ theme_preference }}".toLowerCase();
|
||||||
|
@ -604,7 +604,7 @@ user %} {% if user.settings.theme_hue %}
|
||||||
match_user_theme();
|
match_user_theme();
|
||||||
}, 150);
|
}, 150);
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div style="display: none;">
|
<div style="display: none;">
|
||||||
{{ self::theme_color(color=user.settings.theme_color_surface, css="color-surface") }}
|
{{ self::theme_color(color=user.settings.theme_color_surface, css="color-surface") }}
|
||||||
|
@ -627,11 +627,12 @@ user %} {% if user.settings.theme_hue %}
|
||||||
{{ self::theme_color(color=user.settings.theme_color_text_secondary, css="color-text-secondary") }}
|
{{ self::theme_color(color=user.settings.theme_color_text_secondary, css="color-text-secondary") }}
|
||||||
{{ self::theme_color(color=user.settings.theme_color_secondary_lowered, css="color-secondary-lowered") }}
|
{{ self::theme_color(color=user.settings.theme_color_secondary_lowered, css="color-secondary-lowered") }}
|
||||||
|
|
||||||
{% if user.permissions|has_supporter %}
|
{% if user.permissions|has_supporter -%}
|
||||||
<style>{{ user.settings.theme_custom_css }}</style>
|
<style>{{ user.settings.theme_custom_css }}</style>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %} {% macro theme_color(color, css) -%} {% if color %}
|
{%- endif %} {%- endmacro %} {% macro theme_color(color, css) -%} {% if color
|
||||||
|
-%}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<style>
|
<style>
|
||||||
:root,
|
:root,
|
||||||
|
@ -639,7 +640,7 @@ user %} {% if user.settings.theme_hue %}
|
||||||
--{{ css }}: {{ color|color }} !important;
|
--{{ css }}: {{ color|color }} !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endif %} {%- endmacro %} {% macro quote_form() -%} {% if config.town_square
|
{%- endif %} {%- endmacro %} {% macro quote_form() -%} {% if config.town_square
|
||||||
and user %}
|
and user %}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex flex-col">
|
<div class="card small flex flex-col">
|
||||||
|
@ -681,12 +682,12 @@ and user %}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endif %} {%- endmacro %} {% macro question(question, owner,
|
{%- endif %} {%- endmacro %} {% macro question(question, owner,
|
||||||
show_community=true, secondary=false) -%}
|
show_community=true, secondary=false) -%}
|
||||||
<div class="card{% if secondary %} secondary{% endif %} flex gap-2">
|
<div class="card{% if secondary -%} secondary{%- endif %} flex gap-2">
|
||||||
{% if owner.id == 0 %}
|
{% if owner.id == 0 -%}
|
||||||
<span>
|
<span>
|
||||||
{% if profile and profile.settings.anonymous_avatar_url %}
|
{% if profile and profile.settings.anonymous_avatar_url -%}
|
||||||
<img
|
<img
|
||||||
src="/api/v1/util/proxy?url={{ profile.settings.anonymous_avatar_url }}"
|
src="/api/v1/util/proxy?url={{ profile.settings.anonymous_avatar_url }}"
|
||||||
alt="anonymous' avatar"
|
alt="anonymous' avatar"
|
||||||
|
@ -695,21 +696,21 @@ show_community=true, secondary=false) -%}
|
||||||
style="--size: 52px"
|
style="--size: 52px"
|
||||||
/>
|
/>
|
||||||
{% else %} {{ self::avatar(username=owner.username,
|
{% else %} {{ self::avatar(username=owner.username,
|
||||||
selector_type="username", size="52px") }} {% endif %}
|
selector_type="username", size="52px") }} {%- endif %}
|
||||||
</span>
|
</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="/@{{ owner.username }}">
|
<a href="/@{{ owner.username }}">
|
||||||
{{ self::avatar(username=owner.username, selector_type="username",
|
{{ self::avatar(username=owner.username, selector_type="username",
|
||||||
size="52px") }}
|
size="52px") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<div class="flex items-center gap-2 flex-wrap">
|
<div class="flex items-center gap-2 flex-wrap">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<span class="name">
|
<span class="name">
|
||||||
{% if owner.id == 0 %}
|
{% if owner.id == 0 -%}
|
||||||
{% if profile and profile.settings.anonymous_username %}
|
{% if profile and profile.settings.anonymous_username -%}
|
||||||
<span class="flex items-center gap-2">
|
<span class="flex items-center gap-2">
|
||||||
<b>{{ profile.settings.anonymous_username }}</b>
|
<b>{{ profile.settings.anonymous_username }}</b>
|
||||||
<span
|
<span
|
||||||
|
@ -722,10 +723,10 @@ show_community=true, secondary=false) -%}
|
||||||
</span>
|
</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<b>anonymous</b>
|
<b>anonymous</b>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ self::full_username(user=owner) }}
|
{{ self::full_username(user=owner) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="date">{{ question.created }}</span>
|
<span class="date">{{ question.created }}</span>
|
||||||
|
@ -738,7 +739,7 @@ show_community=true, secondary=false) -%}
|
||||||
{{ icon "message-circle-heart" }}
|
{{ icon "message-circle-heart" }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{% if question.context.is_nsfw %}
|
{% if question.context.is_nsfw -%}
|
||||||
<span
|
<span
|
||||||
title="NSFW community"
|
title="NSFW community"
|
||||||
class="flex items-center"
|
class="flex items-center"
|
||||||
|
@ -746,18 +747,18 @@ show_community=true, secondary=false) -%}
|
||||||
>
|
>
|
||||||
{{ icon "square-asterisk" }}
|
{{ icon "square-asterisk" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %} {% if question.community > 0 and show_community %}
|
{%- endif %} {% if question.community > 0 and show_community -%}
|
||||||
<a
|
<a
|
||||||
href="/api/v1/communities/find/{{ question.community }}"
|
href="/api/v1/communities/find/{{ question.community }}"
|
||||||
class="flex items-center"
|
class="flex items-center"
|
||||||
>
|
>
|
||||||
{{ self::community_avatar(id=question.community, size="24px") }}
|
{{ self::community_avatar(id=question.community, size="24px") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %} {% if question.is_global %}
|
{%- endif %} {% if question.is_global -%}
|
||||||
<a class="notification chip" href="/question/{{ question.id }}"
|
<a class="notification chip" href="/question/{{ question.id }}"
|
||||||
>{{ question.answer_count }} answers</a
|
>{{ question.answer_count }} answers</a
|
||||||
>
|
>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="no_p_margin" style="font-weight: 500"
|
<span class="no_p_margin" style="font-weight: 500"
|
||||||
|
@ -774,11 +775,11 @@ header="", is_global=false) -%}
|
||||||
{{ icon "message-circle-heart" }}
|
{{ icon "message-circle-heart" }}
|
||||||
<span class="no_p_margin">
|
<span class="no_p_margin">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% if header %}
|
{% if header -%}
|
||||||
{{ header|markdown|safe }}
|
{{ header|markdown|safe }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ text "requests:label.ask_question" }}
|
{{ text "requests:label.ask_question" }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -839,7 +840,7 @@ secondary=false, show_community=true) -%}
|
||||||
show_community=show_community) }}
|
show_community=show_community) }}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="small card flex justify-between flex-wrap gap-2{% if secondary %} secondary{% endif %}"
|
class="small card flex justify-between flex-wrap gap-2{% if secondary -%} secondary{%- endif %}"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex gap-1 reactions_box"
|
class="flex gap-1 reactions_box"
|
||||||
|
@ -853,14 +854,14 @@ secondary=false, show_community=true) -%}
|
||||||
|
|
||||||
<div class="flex gap-1 buttons_box">
|
<div class="flex gap-1 buttons_box">
|
||||||
<a href="/question/{{ question[0].id }}" class="button small">
|
<a href="/question/{{ question[0].id }}" class="button small">
|
||||||
{{ icon "external-link" }} {% if user %}
|
{{ icon "external-link" }} {% if user -%}
|
||||||
<span>{{ text "requests:label.answer" }}</span>
|
<span>{{ text "requests:label.answer" }}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span>{{ text "general:action.open" }}</span>
|
<span>{{ text "general:action.open" }}</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if user %} {% if can_manage_questions or is_helper or
|
{% if user -%} {% if can_manage_questions or is_helper or
|
||||||
question[1].id == user.id %}
|
question[1].id == user.id %}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
|
@ -881,7 +882,7 @@ secondary=false, show_community=true) -%}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {% endif %}
|
{%- endif %} {%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -931,7 +932,7 @@ state.data %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %} {% macro last_fm_playing(state, size="60px") -%} {%
|
{%- endif %} {%- endmacro %} {% macro last_fm_playing(state, size="60px") -%} {%
|
||||||
if state and state.data %}
|
if state and state.data %}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card flex items-center justify-between gap-2 small">
|
<div class="card flex items-center justify-between gap-2 small">
|
||||||
|
@ -967,7 +968,7 @@ if state and state.data %}
|
||||||
></span
|
></span
|
||||||
>
|
>
|
||||||
|
|
||||||
{% if state.data.duration_ms and state.data.duration_ms != "0" %}
|
{% if state.data.duration_ms and state.data.duration_ms != "0" -%}
|
||||||
<span
|
<span
|
||||||
hook="spotify_time_text"
|
hook="spotify_time_text"
|
||||||
hook-arg:updated="{{ state.data.timestamp }}"
|
hook-arg:updated="{{ state.data.timestamp }}"
|
||||||
|
@ -975,22 +976,22 @@ if state and state.data %}
|
||||||
hook-arg:duration="{{ state.data.duration_ms }}"
|
hook-arg:duration="{{ state.data.duration_ms }}"
|
||||||
hook-arg:display="full"
|
hook-arg:display="full"
|
||||||
></span>
|
></span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %} {% macro connection_icon(key) -%}
|
{%- endif %} {%- endmacro %} {% macro connection_icon(key) -%}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div style="display: contents;">
|
<div style="display: contents;">
|
||||||
{% if key == "Spotify" %}
|
{% if key == "Spotify" -%}
|
||||||
{{ icon "spotify" }}
|
{{ icon "spotify" }}
|
||||||
{% elif key == "LastFm" %}
|
{% elif key == "LastFm" %}
|
||||||
{{ icon "last_fm" }}
|
{{ icon "last_fm" }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{%- endmacro %} {% macro connection_url(key, value) -%} {% if value[0].data.url
|
{%- endmacro %} {% macro connection_url(key, value) -%} {% if value[0].data.url
|
||||||
%} {{ value[0].data.url }} {% elif key == "LastFm" %} https://last.fm/user/{{
|
%} {{ value[0].data.url }} {% elif key == "LastFm" %} https://last.fm/user/{{
|
||||||
value[0].data.name }} {% endif %} {%- endmacro %} {% macro
|
value[0].data.name }} {%- endif %} {%- endmacro %} {% macro
|
||||||
message_actions(can_manage_message, owner, message, owner) -%}
|
message_actions(can_manage_message, owner, message, owner) -%}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
|
@ -1002,12 +1003,12 @@ message_actions(can_manage_message, owner, message, owner) -%}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
{% if can_manage_message or (user and user.id == message.owner) %}
|
{% if can_manage_message or (user and user.id == message.owner) -%}
|
||||||
<button class="red" onclick="delete_message('{{ message.id }}')">
|
<button class="red" onclick="delete_message('{{ message.id }}')">
|
||||||
{{ icon "trash" }}
|
{{ icon "trash" }}
|
||||||
<span>{{ text "general:action.delete" }}</span>
|
<span>{{ text "general:action.delete" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onclick="window.location.href = `${window.location.origin}/chats/{{ community }}/{{ channel }}?message={{ message.id }}`"
|
onclick="window.location.href = `${window.location.origin}/chats/{{ community }}/{{ channel }}?message={{ message.id }}`"
|
||||||
|
@ -1032,17 +1033,17 @@ message_actions(can_manage_message, owner, message, owner) -%}
|
||||||
{%- endmacro %} {% macro message(user, message, can_manage_message=false,
|
{%- endmacro %} {% macro message(user, message, can_manage_message=false,
|
||||||
grouped=false) -%}
|
grouped=false) -%}
|
||||||
<div
|
<div
|
||||||
class="card secondary message flex gap-2 {% if grouped %}grouped{% endif %}"
|
class="card secondary message flex gap-2 {% if grouped -%}grouped{%- endif %}"
|
||||||
id="message-{{ message.id }}"
|
id="message-{{ message.id }}"
|
||||||
>
|
>
|
||||||
{% if not grouped %}
|
{% if not grouped -%}
|
||||||
<a href="/@{{ user.username }}" target="_top">
|
<a href="/@{{ user.username }}" target="_top">
|
||||||
{{ self::avatar(username=user.username, size="42px") }}
|
{{ self::avatar(username=user.username, size="42px") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="flex flex-col gap-1 w-full">
|
<div class="flex flex-col gap-1 w-full">
|
||||||
{% if not grouped %}
|
{% if not grouped -%}
|
||||||
<div class="flex gap-2 w-full justify-between flex-wrap">
|
<div class="flex gap-2 w-full justify-between flex-wrap">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
{{ self::full_username(user=user) }} {% if message.edited !=
|
{{ self::full_username(user=user) }} {% if message.edited !=
|
||||||
|
@ -1052,7 +1053,7 @@ grouped=false) -%}
|
||||||
>
|
>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="date">{{ message.created }}</span>
|
<span class="date">{{ message.created }}</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-2 hidden">
|
<div class="flex gap-2 hidden">
|
||||||
|
@ -1060,17 +1061,17 @@ grouped=false) -%}
|
||||||
can_manage_message=can_manage_message) }}
|
can_manage_message=can_manage_message) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="flex w-full gap-2 justify-between">
|
<div class="flex w-full gap-2 justify-between">
|
||||||
<span class="no_p_margin">{{ message.content|markdown|safe }}</span>
|
<span class="no_p_margin">{{ message.content|markdown|safe }}</span>
|
||||||
|
|
||||||
{% if grouped %}
|
{% if grouped -%}
|
||||||
<div class="hidden">
|
<div class="hidden">
|
||||||
{{ self::message_actions(owner=user, message=message,
|
{{ self::message_actions(owner=user, message=message,
|
||||||
can_manage_message=can_manage_message) }}
|
can_manage_message=can_manage_message) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1087,7 +1088,7 @@ grouped=false) -%}
|
||||||
<span>{{ text "auth:link.settings" }}</span>
|
<span>{{ text "auth:link.settings" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if is_helper %}
|
{% if is_helper -%}
|
||||||
<b class="title">{{ text "general:label.mod" }}</b>
|
<b class="title">{{ text "general:label.mod" }}</b>
|
||||||
|
|
||||||
<a href="/mod_panel/audit_log">
|
<a href="/mod_panel/audit_log">
|
||||||
|
@ -1109,7 +1110,7 @@ grouped=false) -%}
|
||||||
{{ icon "chart-line" }}
|
{{ icon "chart-line" }}
|
||||||
<span>{{ text "general:link.stats" }}</span>
|
<span>{{ text "general:link.stats" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<b class="title">{{ config.name }}</b>
|
<b class="title">{{ config.name }}</b>
|
||||||
|
|
||||||
|
@ -1166,10 +1167,10 @@ other_user.connections.Spotify[1].data.track %}
|
||||||
}}</span
|
}}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %} {% macro user_plate(user, show_menu=false,
|
{%- endif %} {%- endmacro %} {% macro user_plate(user, show_menu=false,
|
||||||
show_kick=false, secondary=false) -%}
|
show_kick=false, secondary=false) -%}
|
||||||
<div
|
<div
|
||||||
class="flex gap-2 items-center card tiny user_plate {% if secondary %}secondary{% endif %}"
|
class="flex gap-2 items-center card tiny user_plate {% if secondary -%}secondary{%- endif %}"
|
||||||
>
|
>
|
||||||
<a href="/@{{ user.username }}">
|
<a href="/@{{ user.username }}">
|
||||||
{{ self::avatar(username=user.username, size="42px",
|
{{ self::avatar(username=user.username, size="42px",
|
||||||
|
@ -1178,13 +1179,13 @@ show_kick=false, secondary=false) -%}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex justify-center flex-col"
|
class="flex justify-center flex-col"
|
||||||
style="{% if show_menu or show_kick %}width: 60%{% else %}max-width: 200px{% endif %}"
|
style="{% if show_menu or show_kick -%}width: 60%{% else %}max-width: 200px{%- endif %}"
|
||||||
>
|
>
|
||||||
{{ self::full_username(user=user) }}
|
{{ self::full_username(user=user) }}
|
||||||
<div class="user_status">{{ self::user_status(other_user=user) }}</div>
|
<div class="user_status">{{ self::user_status(other_user=user) }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if show_menu %}
|
{% if show_menu -%}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
class="camo small square"
|
class="camo small square"
|
||||||
|
@ -1216,7 +1217,7 @@ show_kick=false, secondary=false) -%}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
{%- endmacro %} {% macro emoji_picker(element_id, render_dialog=false) -%}
|
{%- endmacro %} {% macro emoji_picker(element_id, render_dialog=false) -%}
|
||||||
<button
|
<button
|
||||||
|
@ -1228,7 +1229,7 @@ show_kick=false, secondary=false) -%}
|
||||||
{{ icon "smile-plus" }}
|
{{ icon "smile-plus" }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{% if render_dialog %}
|
{% if render_dialog -%}
|
||||||
<dialog id="emoji_dialog">
|
<dialog id="emoji_dialog">
|
||||||
<div class="inner flex flex-col gap-2">
|
<div class="inner flex flex-col gap-2">
|
||||||
<script
|
<script
|
||||||
|
@ -1307,7 +1308,7 @@ show_kick=false, secondary=false) -%}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
{% endif %} {%- endmacro %} {% macro file_picker(files_list_id) -%}
|
{%- endif %} {%- endmacro %} {% macro file_picker(files_list_id) -%}
|
||||||
<button
|
<button
|
||||||
class="button small square quaternary"
|
class="button small square quaternary"
|
||||||
onclick="pick_file()"
|
onclick="pick_file()"
|
||||||
|
@ -1384,11 +1385,11 @@ is_supporter %}
|
||||||
onclick="window.location.href = '/settings#/account/billing'"
|
onclick="window.location.href = '/settings#/account/billing'"
|
||||||
>
|
>
|
||||||
<div class="card w-full flex flex-wrap items-center gap-2 justify-between">
|
<div class="card w-full flex flex-wrap items-center gap-2 justify-between">
|
||||||
{% if body %}
|
{% if body -%}
|
||||||
<b>{{ body }}</b>
|
<b>{{ body }}</b>
|
||||||
{% else %}
|
{% else %}
|
||||||
<b>{{ text "general:label.supporter_motivation" }}</b>
|
<b>{{ text "general:label.supporter_motivation" }}</b>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<a href="/settings#/account/billing" class="button small">
|
<a href="/settings#/account/billing" class="button small">
|
||||||
{{ icon "heart" }}
|
{{ icon "heart" }}
|
||||||
|
@ -1396,4 +1397,4 @@ is_supporter %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %}
|
{%- endif %} {%- endmacro %}
|
||||||
|
|
|
@ -6,30 +6,30 @@
|
||||||
<b>{{ config.name }}</b>
|
<b>{{ config.name }}</b>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if show_lhs %}
|
{% if show_lhs -%}
|
||||||
<a
|
<a
|
||||||
href="{{ home }}"
|
href="{{ home }}"
|
||||||
class="button {% if selected == 'home' %}active{% endif %}"
|
class="button {% if selected == 'home' -%}active{%- endif %}"
|
||||||
>
|
>
|
||||||
{{ icon "house" }}
|
{{ icon "house" }}
|
||||||
<span class="desktop">{{ text "general:link.home" }}</span>
|
<span class="desktop">{{ text "general:link.home" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<a
|
<a
|
||||||
href="/communities"
|
href="/communities"
|
||||||
class="button {% if selected == 'communities' %}active{% endif %}"
|
class="button {% if selected == 'communities' -%}active{%- endif %}"
|
||||||
>
|
>
|
||||||
{{ icon "book-heart" }}
|
{{ icon "book-heart" }}
|
||||||
<span class="desktop"
|
<span class="desktop"
|
||||||
>{{ text "general:link.communities" }}</span
|
>{{ text "general:link.communities" }}</span
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
{% endif %} {% endif %}
|
{%- endif %} {%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex nav_side">
|
<div class="flex nav_side">
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<a
|
<a
|
||||||
href="/communities/intents/post"
|
href="/communities/intents/post"
|
||||||
class="button"
|
class="button"
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="/chats/0/0"
|
href="/chats/0/0"
|
||||||
class="button {% if selected == 'chats' %}active{% endif %}"
|
class="button {% if selected == 'chats' -%}active{%- endif %}"
|
||||||
title="Chats"
|
title="Chats"
|
||||||
>
|
>
|
||||||
{{ icon "message-circle" }}
|
{{ icon "message-circle" }}
|
||||||
|
@ -48,12 +48,12 @@
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="/requests"
|
href="/requests"
|
||||||
class="button {% if selected == 'requests' %}active{% endif %}"
|
class="button {% if selected == 'requests' -%}active{%- endif %}"
|
||||||
title="Requests"
|
title="Requests"
|
||||||
>
|
>
|
||||||
{{ icon "inbox" }}
|
{{ icon "inbox" }}
|
||||||
<span
|
<span
|
||||||
class="notification tr {% if user.request_count <= 0 %}hidden{% endif %}"
|
class="notification tr {% if user.request_count <= 0 -%}hidden{%- endif %}"
|
||||||
id="requests_span"
|
id="requests_span"
|
||||||
>{{ user.request_count }}</span
|
>{{ user.request_count }}</span
|
||||||
>
|
>
|
||||||
|
@ -61,18 +61,18 @@
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="/notifs"
|
href="/notifs"
|
||||||
class="button {% if selected == 'notifications' %}active{% endif %}"
|
class="button {% if selected == 'notifications' -%}active{%- endif %}"
|
||||||
title="Notifications"
|
title="Notifications"
|
||||||
>
|
>
|
||||||
{{ icon "bell" }}
|
{{ icon "bell" }}
|
||||||
<span
|
<span
|
||||||
class="notification tr {% if user.notification_count <= 0 %}hidden{% endif %}"
|
class="notification tr {% if user.notification_count <= 0 -%}hidden{%- endif %}"
|
||||||
id="notifications_span"
|
id="notifications_span"
|
||||||
>{{ user.notification_count }}</span
|
>{{ user.notification_count }}</span
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if not hide_user_menu %}
|
{% if not hide_user_menu -%}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
class="flex-row title"
|
class="flex-row title"
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
|
|
||||||
{{ components::user_menu() }}
|
{{ components::user_menu() }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {% else %}
|
{%- endif %} {% else %}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
class="title"
|
class="title"
|
||||||
|
@ -113,71 +113,92 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
{%- endmacro %} {% macro timelines_nav(selected="") -%}
|
{%- endmacro %} {% macro timelines_nav(selected="") -%}
|
||||||
<div class="pillmenu w-full">
|
<div class="pillmenu {% if user -%}rows{% endif %} w-full">
|
||||||
{% if user %}
|
<div class="row">
|
||||||
<a href="/" class="{% if selected == 'home' %}active{% endif %}">
|
{% if user -%}
|
||||||
{{ icon "newspaper" }}
|
<a href="/" class="{% if selected == 'home' -%}active{%- endif %}">
|
||||||
<span>{{ text "general:link.home" }}</span>
|
{{ icon "newspaper" }}
|
||||||
</a>
|
<span>{{ text "general:link.home" }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a href="/stacks" class="{% if selected == 'stacks' %}active{% endif %}">
|
<a
|
||||||
{{ icon "layers" }}
|
href="/stacks"
|
||||||
<span>{{ text "stacks:link.stacks" }}</span>
|
class="{% if selected == 'stacks' -%}active{%- endif %}"
|
||||||
</a>
|
>
|
||||||
{% else %}
|
{{ icon "layers" }}
|
||||||
<a href="/" class="{% if selected == 'all' %}active{% endif %}">
|
<span>{{ text "stacks:link.stacks" }}</span>
|
||||||
{{ icon "earth" }}
|
</a>
|
||||||
<span>{{ text "general:link.all" }}</span>
|
{% else %}
|
||||||
</a>
|
<a href="/" class="{% if selected == 'all' -%}active{%- endif %}">
|
||||||
{% endif %}
|
{{ icon "earth" }}
|
||||||
|
<span>{{ text "general:link.all" }}</span>
|
||||||
|
</a>
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
<a href="/popular" class="{% if selected == 'popular' %}active{% endif %}">
|
<a
|
||||||
{{ icon "trending-up" }}
|
href="/popular"
|
||||||
<span>{{ text "general:link.popular" }}</span>
|
class="{% if selected == 'popular' -%}active{%- endif %}"
|
||||||
</a>
|
>
|
||||||
|
{{ icon "trending-up" }}
|
||||||
|
<span>{{ text "general:link.popular" }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if user %}
|
<div class="row">
|
||||||
<a
|
{% if user -%}
|
||||||
href="/following"
|
<a
|
||||||
class="{% if selected == 'following' %}active{% endif %}"
|
href="/following"
|
||||||
>
|
class="{% if selected == 'following' -%}active{%- endif %}"
|
||||||
{{ icon "rss" }}
|
>
|
||||||
<span>{{ text "general:link.following" }}</span>
|
{{ icon "rss" }}
|
||||||
</a>
|
<span>{{ text "general:link.following" }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a href="/all" class="{% if selected == 'all' %}active{% endif %}">
|
<a
|
||||||
{{ icon "earth" }}
|
href="/search"
|
||||||
<span>{{ text "general:link.all" }}</span>
|
class="{% if selected == 'search' -%}active{%- endif %}"
|
||||||
</a>
|
>
|
||||||
{% endif %}
|
{{ icon "search" }}
|
||||||
|
<span>{{ text "general:link.search" }}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/all" class="{% if selected == 'all' -%}active{%- endif %}">
|
||||||
|
{{ icon "earth" }}
|
||||||
|
<span>{{ text "general:link.all" }}</span>
|
||||||
|
</a>
|
||||||
|
{%- endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{%- endmacro %} {% macro timelines_secondary_nav(posts="", questions="",
|
{%- endmacro %} {% macro timelines_secondary_nav(posts="", questions="",
|
||||||
selected="posts") -%} {% if user %}
|
selected="posts") -%} {% if user -%}
|
||||||
<div class="pillmenu w-full">
|
<div class="pillmenu w-full">
|
||||||
<a href="{{ posts }}" class="{% if selected == 'posts' %}active{% endif %}">
|
<a
|
||||||
|
href="{{ posts }}"
|
||||||
|
class="{% if selected == 'posts' -%}active{%- endif %}"
|
||||||
|
>
|
||||||
{{ icon "newspaper" }}
|
{{ icon "newspaper" }}
|
||||||
<span>{{ text "communities:label.posts" }}</span>
|
<span>{{ text "communities:label.posts" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="{{ questions }}"
|
href="{{ questions }}"
|
||||||
class="{% if selected == 'questions' %}active{% endif %}"
|
class="{% if selected == 'questions' -%}active{%- endif %}"
|
||||||
>
|
>
|
||||||
{{ icon "message-circle-heart" }}
|
{{ icon "message-circle-heart" }}
|
||||||
<span>{{ text "communities:label.questions" }}</span>
|
<span>{{ text "communities:label.questions" }}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %} {% macro community_nav(community, selected="") -%}
|
{%- endif %} {%- endmacro %} {% macro community_nav(community, selected="") -%}
|
||||||
{% if community.context.enable_questions %}
|
{% if community.context.enable_questions -%}
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
<a
|
<a
|
||||||
href="/community/{{ community.title }}"
|
href="/community/{{ community.title }}"
|
||||||
class="{% if selected == 'posts' %}active{% endif %}"
|
class="{% if selected == 'posts' -%}active{%- endif %}"
|
||||||
>
|
>
|
||||||
{{ icon "newspaper" }}
|
{{ icon "newspaper" }}
|
||||||
<span>{{ text "communities:tab.posts" }}</span>
|
<span>{{ text "communities:tab.posts" }}</span>
|
||||||
|
@ -185,10 +206,10 @@ selected="posts") -%} {% if user %}
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="/community/{{ community.title }}/questions"
|
href="/community/{{ community.title }}/questions"
|
||||||
class="{% if selected == 'questions' %}active{% endif %}"
|
class="{% if selected == 'questions' -%}active{%- endif %}"
|
||||||
>
|
>
|
||||||
{{ icon "message-circle-heart" }}
|
{{ icon "message-circle-heart" }}
|
||||||
<span>{{ text "communities:tab.questions" }}</span>
|
<span>{{ text "communities:tab.questions" }}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {%- endmacro %}
|
{%- endif %} {%- endmacro %}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
<div class="card flex flex-col gap-4">
|
<div class="card flex flex-col gap-4">
|
||||||
<span>{{ error_text }}</span>
|
<span>{{ error_text }}</span>
|
||||||
|
|
||||||
<div class="w-full flex gap-2">
|
<div class="w-full flex gap-2">
|
||||||
<a class="button primary" href="/">Home</a>
|
<a class="button primary" href="/">Home</a>
|
||||||
<a class="button secondary" href="javascript:history.back()"
|
<a class="button secondary" href="javascript:history.back()"
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {% endfor %} {% for question in questions %}
|
{%- endif %} {% endfor %} {% for question in questions %}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
{{ components::question(question=question[0], owner=question[1]) }}
|
{{ components::question(question=question[0], owner=question[1]) }}
|
||||||
|
@ -112,9 +112,9 @@
|
||||||
|
|
||||||
<div class="flex flex-wrap w-full gap-2">
|
<div class="flex flex-wrap w-full gap-2">
|
||||||
{{ components::emoji_picker(element_id="content",
|
{{ components::emoji_picker(element_id="content",
|
||||||
render_dialog=true) }} {% if is_supporter %} {{
|
render_dialog=true) }} {% if is_supporter -%} {{
|
||||||
components::file_picker(files_list_id="files_list") }}
|
components::file_picker(files_list_id="files_list") }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<button class="primary">{{ text "requests:label.answer" }}</button>
|
<button class="primary">{{ text "requests:label.answer" }}</button>
|
||||||
<button type="button" class="red quaternary" onclick="trigger('me::remove_question', ['{{ question[0].id }}'])">{{ text "general:action.delete" }}</button>
|
<button type="button" class="red quaternary" onclick="trigger('me::remove_question', ['{{ question[0].id }}'])">{{ text "general:action.delete" }}</button>
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<span>{{ text "settings:label.delete_account" }}</span>
|
<span>{{ text "settings:label.delete_account" }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{% if profile.permissions != 131073 %}
|
{% if profile.permissions != 131073 -%}
|
||||||
<button
|
<button
|
||||||
class="red quaternary"
|
class="red quaternary"
|
||||||
onclick="update_user_role(131073)"
|
onclick="update_user_role(131073)"
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
<button class="quaternary" onclick="update_user_role(1)">
|
<button class="quaternary" onclick="update_user_role(1)">
|
||||||
Unban
|
Unban
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -2,20 +2,20 @@
|
||||||
<title>Post quotes - {{ config.name }}</title>
|
<title>Post quotes - {{ config.name }}</title>
|
||||||
{% endblock %} {% block body %} {{ macros::nav() }}
|
{% endblock %} {% block body %} {{ macros::nav() }}
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{% if post.replying_to %}
|
{% if post.replying_to -%}
|
||||||
<a href="/post/{{ post.replying_to }}" class="button">
|
<a href="/post/{{ post.replying_to }}" class="button">
|
||||||
{{ icon "arrow-up" }}
|
{{ icon "arrow-up" }}
|
||||||
<span>{{ text "communities:action.continue_thread" }}</span>
|
<span>{{ text "communities:action.continue_thread" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div style="display: contents;">
|
<div style="display: contents;">
|
||||||
{% if post.context.repost and post.context.repost.reposting %}
|
{% if post.context.repost and post.context.repost.reposting -%}
|
||||||
{{ components::repost(repost=reposting, post=post, owner=owner, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
{{ components::repost(repost=reposting, post=post, owner=owner, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post, owner=owner, question=question, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
{{ components::post(post=post, owner=owner, question=question, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
|
@ -35,14 +35,14 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if (user and user.id == post.owner) or can_manage_posts %}
|
{% if (user and user.id == post.owner) or can_manage_posts -%}
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
{% if user and user.id == post.owner %}
|
{% if user and user.id == post.owner -%}
|
||||||
<a href="/post/{{ post.id }}#/edit">
|
<a href="/post/{{ post.id }}#/edit">
|
||||||
{{ icon "pen" }}
|
{{ icon "pen" }}
|
||||||
<span>{{ text "communities:label.edit_content" }}</span>
|
<span>{{ text "communities:label.edit_content" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
<a href="/post/{{ post.id }}/likes" class="active">
|
<a href="/post/{{ post.id }}/likes" class="active">
|
||||||
{{ icon "heart" }}
|
{{ icon "heart" }}
|
||||||
<span>{{ text "communities:label.likes" }}</span>
|
<span>{{ text "communities:label.likes" }}</span>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
<span>{{ text "communities:action.configure" }}</span>
|
<span>{{ text "communities:action.configure" }}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest w-full">
|
<div class="card-nest w-full">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
|
|
|
@ -2,23 +2,23 @@
|
||||||
<title>Post - {{ config.name }}</title>
|
<title>Post - {{ config.name }}</title>
|
||||||
{% endblock %} {% block body %} {{ macros::nav() }}
|
{% endblock %} {% block body %} {{ macros::nav() }}
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{% if post.replying_to %}
|
{% if post.replying_to -%}
|
||||||
<a href="/post/{{ post.replying_to }}" class="button">
|
<a href="/post/{{ post.replying_to }}" class="button">
|
||||||
{{ icon "arrow-up" }}
|
{{ icon "arrow-up" }}
|
||||||
<span>{{ text "communities:action.continue_thread" }}</span>
|
<span>{{ text "communities:action.continue_thread" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div style="display: contents;">
|
<div style="display: contents;">
|
||||||
{% if post.context.repost and post.context.repost.reposting %}
|
{% if post.context.repost and post.context.repost.reposting -%}
|
||||||
{{ components::repost(repost=reposting, post=post, owner=owner, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
{{ components::repost(repost=reposting, post=post, owner=owner, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post, owner=owner, question=question, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
{{ components::post(post=post, owner=owner, question=question, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if user and post.context.comments_enabled %}
|
{% if user and post.context.comments_enabled -%}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small">
|
<div class="card small">
|
||||||
<b>{{ text "communities:label.create_reply" }}</b>
|
<b>{{ text "communities:label.create_reply" }}</b>
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
{{ components::emoji_picker(element_id="content",
|
{{ components::emoji_picker(element_id="content",
|
||||||
render_dialog=true) }} {% if is_supporter %} {{
|
render_dialog=true) }} {% if is_supporter -%} {{
|
||||||
components::file_picker(files_list_id="files_list") }} {% endif
|
components::file_picker(files_list_id="files_list") }} {% endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
<a href="#/replies" data-tab-button="replies" class="active">
|
<a href="#/replies" data-tab-button="replies" class="active">
|
||||||
{{ icon "newspaper" }}
|
{{ icon "newspaper" }}
|
||||||
|
@ -75,14 +75,14 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if (user and user.id == post.owner) or can_manage_posts %}
|
{% if (user and user.id == post.owner) or can_manage_posts -%}
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
{% if user and user.id == post.owner %}
|
{% if user and user.id == post.owner -%}
|
||||||
<a href="/post/{{ post.id }}#/edit">
|
<a href="/post/{{ post.id }}#/edit">
|
||||||
{{ icon "pen" }}
|
{{ icon "pen" }}
|
||||||
<span>{{ text "communities:label.edit_content" }}</span>
|
<span>{{ text "communities:label.edit_content" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<a href="/post/{{ post.id }}/likes">
|
<a href="/post/{{ post.id }}/likes">
|
||||||
{{ icon "heart" }}
|
{{ icon "heart" }}
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
<span>{{ text "communities:action.configure" }}</span>
|
<span>{{ text "communities:action.configure" }}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="flex flex-col gap-2 hidden" data-tab="configure">
|
<div class="flex flex-col gap-2 hidden" data-tab="configure">
|
||||||
<div class="card-nest w-full">
|
<div class="card-nest w-full">
|
||||||
|
@ -218,7 +218,7 @@
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if user and user.id == post.owner %}
|
{% if user and user.id == post.owner -%}
|
||||||
<div class="card-nest w-full hidden" data-tab="edit">
|
<div class="card-nest w-full hidden" data-tab="edit">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
{{ icon "pen" }}
|
{{ icon "pen" }}
|
||||||
|
@ -279,7 +279,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest w-full" data-tab="replies">
|
<div class="card-nest w-full" data-tab="replies">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
|
|
|
@ -2,20 +2,20 @@
|
||||||
<title>Post quotes - {{ config.name }}</title>
|
<title>Post quotes - {{ config.name }}</title>
|
||||||
{% endblock %} {% block body %} {{ macros::nav() }}
|
{% endblock %} {% block body %} {{ macros::nav() }}
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{% if post.replying_to %}
|
{% if post.replying_to -%}
|
||||||
<a href="/post/{{ post.replying_to }}" class="button">
|
<a href="/post/{{ post.replying_to }}" class="button">
|
||||||
{{ icon "arrow-up" }}
|
{{ icon "arrow-up" }}
|
||||||
<span>{{ text "communities:action.continue_thread" }}</span>
|
<span>{{ text "communities:action.continue_thread" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div style="display: contents;">
|
<div style="display: contents;">
|
||||||
{% if post.context.repost and post.context.repost.reposting %}
|
{% if post.context.repost and post.context.repost.reposting -%}
|
||||||
{{ components::repost(repost=reposting, post=post, owner=owner, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
{{ components::repost(repost=reposting, post=post, owner=owner, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post, owner=owner, question=question, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
{{ components::post(post=post, owner=owner, question=question, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
|
@ -35,14 +35,14 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if (user and user.id == post.owner) or can_manage_posts %}
|
{% if (user and user.id == post.owner) or can_manage_posts -%}
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
{% if user and user.id == post.owner %}
|
{% if user and user.id == post.owner -%}
|
||||||
<a href="/post/{{ post.id }}#/edit">
|
<a href="/post/{{ post.id }}#/edit">
|
||||||
{{ icon "pen" }}
|
{{ icon "pen" }}
|
||||||
<span>{{ text "communities:label.edit_content" }}</span>
|
<span>{{ text "communities:label.edit_content" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
<a href="/post/{{ post.id }}/likes">
|
<a href="/post/{{ post.id }}/likes">
|
||||||
{{ icon "heart" }}
|
{{ icon "heart" }}
|
||||||
<span>{{ text "communities:label.likes" }}</span>
|
<span>{{ text "communities:label.likes" }}</span>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
<span>{{ text "communities:action.configure" }}</span>
|
<span>{{ text "communities:action.configure" }}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest w-full">
|
<div class="card-nest w-full">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
|
|
|
@ -2,20 +2,20 @@
|
||||||
<title>Post reposts - {{ config.name }}</title>
|
<title>Post reposts - {{ config.name }}</title>
|
||||||
{% endblock %} {% block body %} {{ macros::nav() }}
|
{% endblock %} {% block body %} {{ macros::nav() }}
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{% if post.replying_to %}
|
{% if post.replying_to -%}
|
||||||
<a href="/post/{{ post.replying_to }}" class="button">
|
<a href="/post/{{ post.replying_to }}" class="button">
|
||||||
{{ icon "arrow-up" }}
|
{{ icon "arrow-up" }}
|
||||||
<span>{{ text "communities:action.continue_thread" }}</span>
|
<span>{{ text "communities:action.continue_thread" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div style="display: contents;">
|
<div style="display: contents;">
|
||||||
{% if post.context.repost and post.context.repost.reposting %}
|
{% if post.context.repost and post.context.repost.reposting -%}
|
||||||
{{ components::repost(repost=reposting, post=post, owner=owner, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
{{ components::repost(repost=reposting, post=post, owner=owner, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post, owner=owner, question=question, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
{{ components::post(post=post, owner=owner, question=question, community=community, show_community=true, can_manage_post=can_manage_posts) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
|
@ -35,14 +35,14 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if (user and user.id == post.owner) or can_manage_posts %}
|
{% if (user and user.id == post.owner) or can_manage_posts -%}
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
{% if user and user.id == post.owner %}
|
{% if user and user.id == post.owner -%}
|
||||||
<a href="/post/{{ post.id }}#/edit">
|
<a href="/post/{{ post.id }}#/edit">
|
||||||
{{ icon "pen" }}
|
{{ icon "pen" }}
|
||||||
<span>{{ text "communities:label.edit_content" }}</span>
|
<span>{{ text "communities:label.edit_content" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
<a href="/post/{{ post.id }}/likes">
|
<a href="/post/{{ post.id }}/likes">
|
||||||
{{ icon "heart" }}
|
{{ icon "heart" }}
|
||||||
<span>{{ text "communities:label.likes" }}</span>
|
<span>{{ text "communities:label.likes" }}</span>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
<span>{{ text "communities:action.configure" }}</span>
|
<span>{{ text "communities:action.configure" }}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest w-full">
|
<div class="card-nest w-full">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
|
|
|
@ -50,23 +50,23 @@
|
||||||
<h3 id="username" class="username flex items-center gap-2 flex-wrap w-full">
|
<h3 id="username" class="username flex items-center gap-2 flex-wrap w-full">
|
||||||
<span class="name shorter">{{ components::username(user=profile) }}</span>
|
<span class="name shorter">{{ components::username(user=profile) }}</span>
|
||||||
|
|
||||||
{% if profile.is_verified %}
|
{% if profile.is_verified -%}
|
||||||
<span title="Verified" style="color: var(--color-primary);" class="flex items-center">
|
<span title="Verified" style="color: var(--color-primary);" class="flex items-center">
|
||||||
{{ icon "badge-check" }}
|
{{ icon "badge-check" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% if profile.permissions|has_supporter %}
|
{% if profile.permissions|has_supporter -%}
|
||||||
<span title="Supporter" style="color: var(--color-primary);" class="flex items-center">
|
<span title="Supporter" style="color: var(--color-primary);" class="flex items-center">
|
||||||
{{ icon "star" }}
|
{{ icon "star" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% if profile.permissions|has_staff_badge %}
|
{% if profile.permissions|has_staff_badge -%}
|
||||||
<span title="Staff" style="color: var(--color-primary);" class="flex items-center">
|
<span title="Staff" style="color: var(--color-primary);" class="flex items-center">
|
||||||
{{ icon "shield-user" }}
|
{{ icon "shield-user" }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<span class="fade">{{ profile.username }}</span>
|
<span class="fade">{{ profile.username }}</span>
|
||||||
|
@ -77,9 +77,9 @@
|
||||||
class="card flex flex-col items-center gap-2"
|
class="card flex flex-col items-center gap-2"
|
||||||
id="social"
|
id="social"
|
||||||
>
|
>
|
||||||
{% if profile.settings.status %}
|
{% if profile.settings.status -%}
|
||||||
<p>{{ profile.settings.status }}</p>
|
<p>{{ profile.settings.status }}</p>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="w-full flex">
|
<div class="w-full flex">
|
||||||
<a
|
<a
|
||||||
|
@ -98,14 +98,14 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if is_following_you %}
|
{% if is_following_you -%}
|
||||||
<b
|
<b
|
||||||
class="notification chip w-content flex items-center gap-2"
|
class="notification chip w-content flex items-center gap-2"
|
||||||
>
|
>
|
||||||
{{ icon "heart" }}
|
{{ icon "heart" }}
|
||||||
<span>Follows you</span>
|
<span>Follows you</span>
|
||||||
</b>
|
</b>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -117,11 +117,11 @@
|
||||||
<div class="card flex flex-col gap-2">
|
<div class="card flex flex-col gap-2">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div style="display: contents;">
|
<div style="display: contents;">
|
||||||
{% if profile.connections.Spotify and profile.connections.Spotify[0].data.name %}
|
{% if profile.connections.Spotify and profile.connections.Spotify[0].data.name -%}
|
||||||
{{ components::spotify_playing(state=profile.connections.Spotify[1]) }}
|
{{ components::spotify_playing(state=profile.connections.Spotify[1]) }}
|
||||||
{% elif profile.connections.LastFm and profile.connections.LastFm[0].data.name %}
|
{% elif profile.connections.LastFm and profile.connections.LastFm[0].data.name %}
|
||||||
{{ components::last_fm_playing(state=profile.connections.LastFm[1]) }}
|
{{ components::last_fm_playing(state=profile.connections.LastFm[1]) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full flex justify-between items-center">
|
<div class="w-full flex justify-between items-center">
|
||||||
|
@ -157,21 +157,21 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if not is_self and user %}
|
{% if not is_self and user -%}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small">
|
<div class="card small">
|
||||||
<b>{{ text "auth:label.relationship" }}</b>
|
<b>{{ text "auth:label.relationship" }}</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card flex gap-2 flex-wrap">
|
<div class="card flex gap-2 flex-wrap">
|
||||||
{% if not is_blocking %}
|
{% if not is_blocking -%}
|
||||||
<button
|
<button
|
||||||
onclick="toggle_follow_user(event)"
|
onclick="toggle_follow_user(event)"
|
||||||
class="{% if is_following %} hidden{% endif %}"
|
class="{% if is_following -%} hidden{%- endif %}"
|
||||||
atto_tag="user.follow"
|
atto_tag="user.follow"
|
||||||
>
|
>
|
||||||
{{ icon "user-plus" }}
|
{{ icon "user-plus" }}
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onclick="toggle_follow_user(event)"
|
onclick="toggle_follow_user(event)"
|
||||||
class="quaternary red{% if not is_following %} hidden{% endif %}"
|
class="quaternary red{% if not is_following -%} hidden{%- endif %}"
|
||||||
atto_tag="user.unfollow"
|
atto_tag="user.unfollow"
|
||||||
>
|
>
|
||||||
{{ icon "user-minus" }}
|
{{ icon "user-minus" }}
|
||||||
|
@ -202,7 +202,7 @@
|
||||||
{{ icon "shield-off" }}
|
{{ icon "shield-off" }}
|
||||||
<span>{{ text "auth:action.unblock" }}</span>
|
<span>{{ text "auth:action.unblock" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {% if not user.settings.private_chats or
|
{%- endif %} {% if not user.settings.private_chats or
|
||||||
is_following_you %}
|
is_following_you %}
|
||||||
<button
|
<button
|
||||||
onclick="create_group_chat()"
|
onclick="create_group_chat()"
|
||||||
|
@ -211,7 +211,7 @@
|
||||||
{{ icon "message-circle" }}
|
{{ icon "message-circle" }}
|
||||||
<span>{{ text "auth:action.message" }}</span>
|
<span>{{ text "auth:action.message" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {% if is_helper %}
|
{%- endif %} {% if is_helper -%}
|
||||||
<a
|
<a
|
||||||
href="/mod_panel/profile/{{ profile.id }}"
|
href="/mod_panel/profile/{{ profile.id }}"
|
||||||
class="button quaternary"
|
class="button quaternary"
|
||||||
|
@ -219,7 +219,7 @@
|
||||||
{{ icon "shield" }}
|
{{ icon "shield" }}
|
||||||
<span>{{ text "general:action.manage" }}</span>
|
<span>{{ text "general:action.manage" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
globalThis.create_group_chat = async () => {
|
globalThis.create_group_chat = async () => {
|
||||||
|
@ -320,7 +320,7 @@
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {% if not profile.settings.private_communities or
|
{%- endif %} {% if not profile.settings.private_communities or
|
||||||
is_self or is_helper %}
|
is_self or is_helper %}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex gap-2 items-center">
|
<div class="card small flex gap-2 items-center">
|
||||||
|
@ -337,7 +337,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="flex flex-col gap-2" id="connections">
|
<div class="flex flex-col gap-2" id="connections">
|
||||||
{% for key, value in profile.connections %} {% if
|
{% for key, value in profile.connections %} {% if
|
||||||
|
@ -355,7 +355,7 @@
|
||||||
{{ icon "external-link" }}
|
{{ icon "external-link" }}
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
{% endif %} {% endfor %}
|
{%- endif %} {% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
{% if not is_self and profile.settings.warning %}
|
{% if not is_self and profile.settings.warning -%}
|
||||||
<script>
|
<script>
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// check for warning
|
// check for warning
|
||||||
|
@ -376,5 +376,5 @@
|
||||||
]);
|
]);
|
||||||
}, 150);
|
}, 150);
|
||||||
</script>
|
</script>
|
||||||
{% endif %} {% if not use_user_theme %} {{ components::theme(user=profile,
|
{%- endif %} {% if not use_user_theme -%} {{ components::theme(user=profile,
|
||||||
theme_preference=profile.settings.profile_theme) }} {% endif %} {% endblock %}
|
theme_preference=profile.settings.profile_theme) }} {%- endif %} {% endblock %}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<span>{{ text "auth:label.blocked_profile_message" }}</span>
|
<span>{{ text "auth:label.blocked_profile_message" }}</span>
|
||||||
|
|
||||||
<div class="card w-full secondary flex gap-2">
|
<div class="card w-full secondary flex gap-2">
|
||||||
{% if user %} {% if not is_blocking %}
|
{% if user -%} {% if not is_blocking -%}
|
||||||
<button onclick="toggle_block_user()" class="quaternary red">
|
<button onclick="toggle_block_user()" class="quaternary red">
|
||||||
{{ icon "shield" }}
|
{{ icon "shield" }}
|
||||||
<span>{{ text "auth:action.block" }}</span>
|
<span>{{ text "auth:action.block" }}</span>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
{{ icon "shield-off" }}
|
{{ icon "shield-off" }}
|
||||||
<span>{{ text "auth:action.unblock" }}</span>
|
<span>{{ text "auth:action.unblock" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
globalThis.toggle_block_user = async () => {
|
globalThis.toggle_block_user = async () => {
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<a href="/" class="button red quaternary">
|
<a href="/" class="button red quaternary">
|
||||||
{{ icon "x" }}
|
{{ icon "x" }}
|
||||||
|
|
|
@ -5,7 +5,7 @@ profile.settings.allow_anonymous_questions) %}
|
||||||
{{ components::create_question_form(receiver=profile.id,
|
{{ components::create_question_form(receiver=profile.id,
|
||||||
header=profile.settings.motivational_header) }}
|
header=profile.settings.motivational_header) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %} {% if not tag and pinned|length != 0 %}
|
{%- endif %} {% if not tag and pinned|length != 0 -%}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex gap-2 items-center">
|
<div class="card small flex gap-2 items-center">
|
||||||
{{ icon "pin" }}
|
{{ icon "pin" }}
|
||||||
|
@ -15,37 +15,51 @@ profile.settings.allow_anonymous_questions) %}
|
||||||
<div class="card flex flex-col gap-4">
|
<div class="card flex flex-col gap-4">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% for post in pinned %}
|
{% for post in pinned %}
|
||||||
{% if post[2].read_access == "Everybody" %}
|
{% if post[2].read_access == "Everybody" -%}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% 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) }}
|
{{ 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 %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex gap-2 items-center">
|
<div class="card small flex gap-2 justify-between items-center">
|
||||||
{% if not tag %} {{ icon "clock" }}
|
<div class="flex gap-2 items-center">
|
||||||
<span>{{ text "auth:label.recent_posts" }}</span>
|
{% if not tag -%} {{ icon "clock" }}
|
||||||
{% else %} {{ icon "tag" }}
|
<span>{{ text "auth:label.recent_posts" }}</span>
|
||||||
<span>{{ text "auth:label.recent_with_tag" }}: <b>{{ tag }}</b></span>
|
{% else %} {{ icon "tag" }}
|
||||||
{% endif %}
|
<span
|
||||||
|
>{{ text "auth:label.recent_with_tag" }}: <b>{{ tag }}</b></span
|
||||||
|
>
|
||||||
|
{%- endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if user -%}
|
||||||
|
<a
|
||||||
|
href="/search?profile={{ profile.id }}"
|
||||||
|
class="button quaternary small"
|
||||||
|
>
|
||||||
|
{{ icon "search" }}
|
||||||
|
<span>{{ text "general:link.search" }}</span>
|
||||||
|
</a>
|
||||||
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card flex flex-col gap-4">
|
<div class="card flex flex-col gap-4">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
{% if post[2].read_access == "Everybody" %}
|
{% if post[2].read_access == "Everybody" -%}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% 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) }}
|
{{ 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 %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ components::pagination(page=page, items=posts|length, key="&tag=", value=tag) }}
|
{{ components::pagination(page=page, items=posts|length, key="&tag=", value=tag) }}
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
<span>{{ text "auth:label.private_profile_message" }}</span>
|
<span>{{ text "auth:label.private_profile_message" }}</span>
|
||||||
|
|
||||||
<div class="card w-full secondary flex gap-2">
|
<div class="card w-full secondary flex gap-2">
|
||||||
{% if user %} {% if not is_following %}
|
{% if user -%} {% if not is_following -%}
|
||||||
<button
|
<button
|
||||||
onclick="toggle_follow_user(event)"
|
onclick="toggle_follow_user(event)"
|
||||||
class="{% if follow_requested %} hidden{% endif %}"
|
class="{% if follow_requested -%} hidden{%- endif %}"
|
||||||
atto_tag="user.follow_request"
|
atto_tag="user.follow_request"
|
||||||
>
|
>
|
||||||
{{ icon "user-plus" }}
|
{{ icon "user-plus" }}
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onclick="cancel_follow_user(event)"
|
onclick="cancel_follow_user(event)"
|
||||||
class="quaternary red{% if not follow_requested %} hidden{% endif %}"
|
class="quaternary red{% if not follow_requested -%} hidden{%- endif %}"
|
||||||
atto_tag="user.cancel_request"
|
atto_tag="user.cancel_request"
|
||||||
>
|
>
|
||||||
{{ icon "user-minus" }}
|
{{ icon "user-minus" }}
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
{{ icon "user-minus" }}
|
{{ icon "user-minus" }}
|
||||||
<span>{{ text "auth:action.unfollow" }}</span>
|
<span>{{ text "auth:action.unfollow" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {% if not is_blocking %}
|
{%- endif %} {% if not is_blocking -%}
|
||||||
<button onclick="toggle_block_user()" class="quaternary red">
|
<button onclick="toggle_block_user()" class="quaternary red">
|
||||||
{{ icon "shield" }}
|
{{ icon "shield" }}
|
||||||
<span>{{ text "auth:action.block" }}</span>
|
<span>{{ text "auth:action.block" }}</span>
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
{{ icon "shield-off" }}
|
{{ icon "shield-off" }}
|
||||||
<span>{{ text "auth:action.unblock" }}</span>
|
<span>{{ text "auth:action.unblock" }}</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
globalThis.toggle_follow_user = async (e) => {
|
globalThis.toggle_follow_user = async (e) => {
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<a href="/" class="button red quaternary">
|
<a href="/" class="button red quaternary">
|
||||||
{{ icon "x" }}
|
{{ icon "x" }}
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
<title>Settings - {{ config.name }}</title>
|
<title>Settings - {{ config.name }}</title>
|
||||||
{% endblock %} {% block body %} {{ macros::nav() }}
|
{% endblock %} {% block body %} {{ macros::nav() }}
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{% if profile.id != user.id %}
|
{% if profile.id != user.id -%}
|
||||||
<div class="card w-full red flex gap-2 items-center">
|
<div class="card w-full red flex gap-2 items-center">
|
||||||
{{ icon "skull" }}
|
{{ icon "skull" }}
|
||||||
<b>Editing other user's settings! Please be careful.</b>
|
<b>Editing other user's settings! Please be careful.</b>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="pillmenu">
|
<div class="pillmenu">
|
||||||
<a data-tab-button="account" class="active" href="#/account">
|
<a data-tab-button="account" class="active" href="#/account">
|
||||||
|
@ -65,12 +65,12 @@
|
||||||
<span>{{ text "settings:tab.uploads" }}</span>
|
<span>{{ text "settings:tab.uploads" }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if config.stripe %}
|
{% if config.stripe -%}
|
||||||
<a data-tab-button="account/billing" href="#/account/billing">
|
<a data-tab-button="account/billing" href="#/account/billing">
|
||||||
{{ icon "credit-card" }}
|
{{ icon "credit-card" }}
|
||||||
<span>{{ text "settings:tab.billing" }}</span>
|
<span>{{ text "settings:tab.billing" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-nest" ui_ident="home_timeline">
|
<div class="card-nest" ui_ident="home_timeline">
|
||||||
|
@ -84,59 +84,59 @@
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
value="MyCommunities"
|
value="MyCommunities"
|
||||||
selected="{% if home == '/' %}true{% else %}false{% endif %}"
|
selected="{% if home == '/' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
My communities
|
My communities
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="MyCommunitiesQuestions"
|
value="MyCommunitiesQuestions"
|
||||||
selected="{% if home == '/questions' %}true{% else %}false{% endif %}"
|
selected="{% if home == '/questions' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
My communities (questions)
|
My communities (questions)
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option
|
<option
|
||||||
value="PopularPosts"
|
value="PopularPosts"
|
||||||
selected="{% if home == '/popular' %}true{% else %}false{% endif %}"
|
selected="{% if home == '/popular' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Popular
|
Popular
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="PopularQuestions"
|
value="PopularQuestions"
|
||||||
selected="{% if home == '/popular/questions' %}true{% else %}false{% endif %}"
|
selected="{% if home == '/popular/questions' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Popular (questions)
|
Popular (questions)
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option
|
<option
|
||||||
value="FollowingPosts"
|
value="FollowingPosts"
|
||||||
selected="{% if home == '/following' %}true{% else %}false{% endif %}"
|
selected="{% if home == '/following' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Following
|
Following
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="FollowingQuestions"
|
value="FollowingQuestions"
|
||||||
selected="{% if home == '/following/questions' %}true{% else %}false{% endif %}"
|
selected="{% if home == '/following/questions' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Following (questions)
|
Following (questions)
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option
|
<option
|
||||||
value="AllPosts"
|
value="AllPosts"
|
||||||
selected="{% if home == '/all' %}true{% else %}false{% endif %}"
|
selected="{% if home == '/all' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
All
|
All
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="AllQuestions"
|
value="AllQuestions"
|
||||||
selected="{% if home == '/all/questions' %}true{% else %}false{% endif %}"
|
selected="{% if home == '/all/questions' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
All (questions)
|
All (questions)
|
||||||
</option>
|
</option>
|
||||||
{% for stack in stacks %}
|
{% for stack in stacks %}
|
||||||
<option
|
<option
|
||||||
value='{"Stack":"{{ stack.id }}"}'
|
value='{"Stack":"{{ stack.id }}"}'
|
||||||
selected="{% if home is ending_with(stack.id|as_str) %}true{% else %}false{% endif %}"
|
selected="{% if home is ending_with(stack.id|as_str) -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
{{ stack.name }} (stack)
|
{{ stack.name }} (stack)
|
||||||
</option>
|
</option>
|
||||||
|
@ -265,7 +265,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card flex flex-col gap-2">
|
<div class="card flex flex-col gap-2">
|
||||||
{% if profile.totp|length == 0 %}
|
{% if profile.totp|length == 0 -%}
|
||||||
<div id="totp_stuff" style="display: none">
|
<div id="totp_stuff" style="display: none">
|
||||||
<span
|
<span
|
||||||
>Scan this QR code in a TOTP authenticator
|
>Scan this QR code in a TOTP authenticator
|
||||||
|
@ -312,7 +312,7 @@
|
||||||
Disable TOTP 2FA
|
Disable TOTP 2FA
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -569,7 +569,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card flex flex-col gap-2 secondary">
|
<div class="card flex flex-col gap-2 secondary">
|
||||||
{% if config.stripe %}
|
{% if config.stripe -%}
|
||||||
<div class="card-nest" ui_ident="supporter_card">
|
<div class="card-nest" ui_ident="supporter_card">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
{{ icon "star" }}
|
{{ icon "star" }}
|
||||||
|
@ -577,7 +577,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card flex flex-col gap-2">
|
<div class="card flex flex-col gap-2">
|
||||||
{% if is_supporter %}
|
{% if is_supporter -%}
|
||||||
<p>
|
<p>
|
||||||
You <b>are</b> a supporter! Thank you for all
|
You <b>are</b> a supporter! Thank you for all
|
||||||
that you do. You can manage your billing
|
that you do. You can manage your billing
|
||||||
|
@ -617,6 +617,7 @@
|
||||||
<li>Create infinite stack timelines</li>
|
<li>Create infinite stack timelines</li>
|
||||||
<li>Ability to upload images to posts</li>
|
<li>Ability to upload images to posts</li>
|
||||||
<li>Save infinite post drafts</li>
|
<li>Save infinite post drafts</li>
|
||||||
|
<li>Ability to search through all posts</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
|
@ -631,10 +632,10 @@
|
||||||
completing payment. It is required to manage
|
completing payment. It is required to manage
|
||||||
your billing settings.</span
|
your billing settings.</span
|
||||||
>
|
>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -727,7 +728,7 @@
|
||||||
"
|
"
|
||||||
>{{ token[1] }}</b
|
>{{ token[1] }}</b
|
||||||
>
|
>
|
||||||
{% if is_helper %}
|
{% if is_helper -%}
|
||||||
<span class="flex gap-2 items-center">
|
<span class="flex gap-2 items-center">
|
||||||
<span class="fade"
|
<span class="fade"
|
||||||
><a href="/api/v1/auth/user/find_by_ip/{{ token[0] }}"
|
><a href="/api/v1/auth/user/find_by_ip/{{ token[0] }}"
|
||||||
|
@ -737,7 +738,7 @@
|
||||||
</span>
|
</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="fade"><code>{{ token[0] }}</code></span>
|
<span class="fade"><code>{{ token[0] }}</code></span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<span class="fade date">{{ token[2] }}</span>
|
<span class="fade date">{{ token[2] }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -754,7 +755,7 @@
|
||||||
|
|
||||||
<div class="w-full hidden flex flex-col gap-2" data-tab="theme">
|
<div class="w-full hidden flex flex-col gap-2" data-tab="theme">
|
||||||
<div class="card tertiary flex flex-col gap-2" id="theme_settings">
|
<div class="card tertiary flex flex-col gap-2" id="theme_settings">
|
||||||
{% if failing_color_keys|length > 0 %}
|
{% if failing_color_keys|length > 0 -%}
|
||||||
<div
|
<div
|
||||||
class="card flex flex-col gap-2"
|
class="card flex flex-col gap-2"
|
||||||
style="background: white; color: black"
|
style="background: white; color: black"
|
||||||
|
@ -773,7 +774,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="card w-full flex flex-wrap gap-2"
|
class="card w-full flex flex-wrap gap-2"
|
||||||
|
@ -804,19 +805,19 @@
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
value="Auto"
|
value="Auto"
|
||||||
selected="{% if user.settings.theme_preference == 'Auto' %}true{% else %}false{% endif %}"
|
selected="{% if user.settings.theme_preference == 'Auto' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Auto
|
Auto
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Light"
|
value="Light"
|
||||||
selected="{% if user.settings.theme_preference == 'Light' %}true{% else %}false{% endif %}"
|
selected="{% if user.settings.theme_preference == 'Light' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Light
|
Light
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Dark"
|
value="Dark"
|
||||||
selected="{% if user.settings.theme_preference == 'Dark' %}true{% else %}false{% endif %}"
|
selected="{% if user.settings.theme_preference == 'Dark' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Dark
|
Dark
|
||||||
</option>
|
</option>
|
||||||
|
@ -839,19 +840,19 @@
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
value="Auto"
|
value="Auto"
|
||||||
selected="{% if user.settings.profile_theme == 'Auto' %}true{% else %}false{% endif %}"
|
selected="{% if user.settings.profile_theme == 'Auto' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Auto
|
Auto
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Light"
|
value="Light"
|
||||||
selected="{% if user.settings.profile_theme == 'Light' %}true{% else %}false{% endif %}"
|
selected="{% if user.settings.profile_theme == 'Light' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Light
|
Light
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Dark"
|
value="Dark"
|
||||||
selected="{% if user.settings.profile_theme == 'Dark' %}true{% else %}false{% endif %}"
|
selected="{% if user.settings.profile_theme == 'Dark' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Dark
|
Dark
|
||||||
</option>
|
</option>
|
||||||
|
@ -885,7 +886,7 @@
|
||||||
{{ icon "spotify" }}
|
{{ icon "spotify" }}
|
||||||
<span>Spotify</span>
|
<span>Spotify</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %} {% if config.connections.last_fm_key and not
|
{%- endif %} {% if config.connections.last_fm_key and not
|
||||||
profile.connections.LastFm %}
|
profile.connections.LastFm %}
|
||||||
<button
|
<button
|
||||||
class="quaternary"
|
class="quaternary"
|
||||||
|
@ -894,7 +895,7 @@
|
||||||
{{ icon "last_fm" }}
|
{{ icon "last_fm" }}
|
||||||
<span>Last.fm</span>
|
<span>Last.fm</span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% for key, value in profile.connections %}
|
{% for key, value in profile.connections %}
|
||||||
|
@ -904,13 +905,13 @@
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<b class="flex items-center gap-2">
|
<b class="flex items-center gap-2">
|
||||||
{% if value[0].data.name %}
|
{% if value[0].data.name -%}
|
||||||
<span>{{ value[0].data.name }}</span>
|
<span>{{ value[0].data.name }}</span>
|
||||||
<span style="display: contents;" title="Verified connection">{{ icon "badge-check" }}</span>
|
<span style="display: contents;" title="Verified connection">{{ icon "badge-check" }}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span>{{ key }}</span>
|
<span>{{ key }}</span>
|
||||||
<span style="display: contents;">{{ icon "badge-alert" }}</span>
|
<span style="display: contents;">{{ icon "badge-alert" }}</span>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -926,7 +927,7 @@
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
{% if value[0].show_on_profile %}checked{% endif %}
|
{% if value[0].show_on_profile -%}checked{%- endif %}
|
||||||
id="{{ key }}-shown"
|
id="{{ key }}-shown"
|
||||||
onchange="trigger('connections::push_con_shown', ['{{ key }}', event.target.checked])"
|
onchange="trigger('connections::push_con_shown', ['{{ key }}', event.target.checked])"
|
||||||
class="w-content"
|
class="w-content"
|
||||||
|
|
|
@ -16,14 +16,14 @@ macros -%}
|
||||||
|
|
||||||
<link rel="stylesheet" href="/css/style.css" />
|
<link rel="stylesheet" href="/css/style.css" />
|
||||||
|
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<script>
|
<script>
|
||||||
window.localStorage.setItem(
|
window.localStorage.setItem(
|
||||||
"tetratto:theme",
|
"tetratto:theme",
|
||||||
"{{ user.settings.theme_preference }}",
|
"{{ user.settings.theme_preference }}",
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<script src="/js/loader.js"></script>
|
<script src="/js/loader.js"></script>
|
||||||
<script defer async src="/js/atto.js"></script>
|
<script defer async src="/js/atto.js"></script>
|
||||||
|
@ -69,7 +69,7 @@ macros -%}
|
||||||
|
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% if user and user.id == 0 %}
|
{% if user and user.id == 0 -%}
|
||||||
<article>
|
<article>
|
||||||
<main>
|
<main>
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
|
@ -89,7 +89,7 @@ macros -%}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</article>
|
</article>
|
||||||
{% else %} {% block body %}{% endblock %} {% endif %}
|
{% else %} {% block body %}{% endblock %} {%- endif %}
|
||||||
<!-- html_footer_goes_here -->
|
<!-- html_footer_goes_here -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ macros -%}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<script data-turbo-permanent="true" id="update-seen-script">
|
<script data-turbo-permanent="true" id="update-seen-script">
|
||||||
document.documentElement.addEventListener("turbo:load", () => {
|
document.documentElement.addEventListener("turbo:load", () => {
|
||||||
trigger("me::seen");
|
trigger("me::seen");
|
||||||
|
@ -141,7 +141,7 @@ macros -%}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<!-- dialogs -->
|
<!-- dialogs -->
|
||||||
<dialog id="link_filter">
|
<dialog id="link_filter">
|
||||||
|
@ -294,7 +294,7 @@ macros -%}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<dialog id="tokens_dialog">
|
<dialog id="tokens_dialog">
|
||||||
<div class="inner flex flex-col gap-2">
|
<div class="inner flex flex-col gap-2">
|
||||||
<form
|
<form
|
||||||
|
@ -345,7 +345,7 @@ macros -%}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
{% endif %} {% if user and use_user_theme %} {{
|
{%- endif %} {% if user and use_user_theme -%} {{
|
||||||
components::theme(user=user,
|
components::theme(user=user,
|
||||||
theme_preference=user.settings.theme_preference) }}
|
theme_preference=user.settings.theme_preference) }}
|
||||||
<script>
|
<script>
|
||||||
|
@ -353,7 +353,7 @@ macros -%}
|
||||||
trigger("atto::use_theme_preference");
|
trigger("atto::use_theme_preference");
|
||||||
}, 150);
|
}, 150);
|
||||||
</script>
|
</script>
|
||||||
{% endif %} {% if user and user.connections.Spotify and
|
{%- endif %} {% if user and user.connections.Spotify and
|
||||||
config.connections.spotify_client_id and
|
config.connections.spotify_client_id and
|
||||||
user.connections.Spotify[0].data.token and
|
user.connections.Spotify[0].data.token and
|
||||||
user.connections.Spotify[0].data.refresh_token %}
|
user.connections.Spotify[0].data.refresh_token %}
|
||||||
|
@ -439,6 +439,6 @@ macros -%}
|
||||||
}
|
}
|
||||||
}, 150);
|
}, 150);
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<title>My stacks - {{ config.name }}</title>
|
<title>My stacks - {{ config.name }}</title>
|
||||||
{% endblock %} {% block body %} {{ macros::nav() }}
|
{% endblock %} {% block body %} {{ macros::nav() }}
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{{ macros::timelines_nav(selected="stacks") }} {% if user %}
|
{{ macros::timelines_nav(selected="stacks") }} {% if user -%}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small">
|
<div class="card small">
|
||||||
<b>{{ text "stacks:label.create_new" }}</b>
|
<b>{{ text "stacks:label.create_new" }}</b>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<div class="card-nest w-full">
|
<div class="card-nest w-full">
|
||||||
<div class="card small flex items-center justify-between gap-2">
|
<div class="card small flex items-center justify-between gap-2">
|
||||||
|
|
|
@ -25,13 +25,13 @@
|
||||||
<select onchange="save_privacy(event)">
|
<select onchange="save_privacy(event)">
|
||||||
<option
|
<option
|
||||||
value="Private"
|
value="Private"
|
||||||
selected="{% if stack.privacy == 'Private' %}true{% else %}false{% endif %}"
|
selected="{% if stack.privacy == 'Private' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Private
|
Private
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Public"
|
value="Public"
|
||||||
selected="{% if stack.privacy == 'Public' %}true{% else %}false{% endif %}"
|
selected="{% if stack.privacy == 'Public' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Public
|
Public
|
||||||
</option>
|
</option>
|
||||||
|
@ -48,13 +48,13 @@
|
||||||
<select onchange="save_mode(event)">
|
<select onchange="save_mode(event)">
|
||||||
<option
|
<option
|
||||||
value="Include"
|
value="Include"
|
||||||
selected="{% if stack.mode == 'Include' %}true{% else %}false{% endif %}"
|
selected="{% if stack.mode == 'Include' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Include
|
Include
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Exclude"
|
value="Exclude"
|
||||||
selected="{% if stack.mode == 'Exclude' %}true{% else %}false{% endif %}"
|
selected="{% if stack.mode == 'Exclude' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Exclude
|
Exclude
|
||||||
</option>
|
</option>
|
||||||
|
@ -71,13 +71,13 @@
|
||||||
<select onchange="save_sort(event)">
|
<select onchange="save_sort(event)">
|
||||||
<option
|
<option
|
||||||
value="Created"
|
value="Created"
|
||||||
selected="{% if stack.sort == 'Created' %}true{% else %}false{% endif %}"
|
selected="{% if stack.sort == 'Created' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Created
|
Created
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
value="Likes"
|
value="Likes"
|
||||||
selected="{% if stack.sort == 'Likes' %}true{% else %}false{% endif %}"
|
selected="{% if stack.sort == 'Likes' -%}true{% else %}false{%- endif %}"
|
||||||
>
|
>
|
||||||
Likes
|
Likes
|
||||||
</option>
|
</option>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<span>{{ stack.name }}</span>
|
<span>{{ stack.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if user and user.id == stack.owner %}
|
{% if user and user.id == stack.owner -%}
|
||||||
<a
|
<a
|
||||||
href="/stacks/{{ stack.id }}/manage"
|
href="/stacks/{{ stack.id }}/manage"
|
||||||
class="button quaternary small"
|
class="button quaternary small"
|
||||||
|
@ -18,23 +18,23 @@
|
||||||
{{ icon "pencil" }}
|
{{ icon "pencil" }}
|
||||||
<span>{{ text "general:action.manage" }}</span>
|
<span>{{ text "general:action.manage" }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="card w-full flex flex-col gap-2">
|
<div class="card w-full flex flex-col gap-2">
|
||||||
{% if list|length == 0 %}
|
{% if list|length == 0 -%}
|
||||||
<p>No posts yet! Maybe <a href="/stacks/{{ stack.id }}/manage#/users">add a user to this stack</a>!</p>
|
<p>No posts yet! Maybe <a href="/stacks/{{ stack.id }}/manage#/users">add a user to this stack</a>!</p>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% for post in list %}
|
{% for post in list %}
|
||||||
{% if post[2].read_access == "Everybody" %}
|
{% if post[2].read_access == "Everybody" -%}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% 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) }}
|
{{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ components::pagination(page=page, items=list|length) }}
|
{{ components::pagination(page=page, items=list|length) }}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<main class="flex flex-col gap-2">
|
<main class="flex flex-col gap-2">
|
||||||
{{ macros::timelines_nav(selected="all") }} {{
|
{{ macros::timelines_nav(selected="all") }} {{
|
||||||
macros::timelines_secondary_nav(posts="/all", questions="/all/questions") }}
|
macros::timelines_secondary_nav(posts="/all", questions="/all/questions") }}
|
||||||
{% if not user %}
|
{% if not user -%}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card small flex items-center gap-2">
|
<div class="card small flex items-center gap-2">
|
||||||
{{ icon "heart" }}
|
{{ icon "heart" }}
|
||||||
|
@ -23,18 +23,18 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="card w-full flex flex-col gap-2">
|
<div class="card w-full flex flex-col gap-2">
|
||||||
{% for post in list %}
|
{% for post in list %}
|
||||||
{% if post[2].read_access == "Everybody" %}
|
{% if post[2].read_access == "Everybody" -%}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% 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) }}
|
{{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ components::pagination(page=page, items=list|length) }}
|
{{ components::pagination(page=page, items=list|length) }}
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="card w-full flex flex-col gap-2">
|
<div class="card w-full flex flex-col gap-2">
|
||||||
{% for post in list %}
|
{% for post in list %}
|
||||||
{% if post[2].read_access == "Everybody" %}
|
{% if post[2].read_access == "Everybody" -%}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% 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) }}
|
{{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ components::pagination(page=page, items=list|length) }}
|
{{ components::pagination(page=page, items=list|length) }}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
{{ macros::timelines_nav(selected="home") }} {{
|
{{ macros::timelines_nav(selected="home") }} {{
|
||||||
macros::timelines_secondary_nav(posts="/", questions="/questions") }}
|
macros::timelines_secondary_nav(posts="/", questions="/questions") }}
|
||||||
|
|
||||||
{% if list|length == 0 and page == 0 %}
|
{% if list|length == 0 and page == 0 -%}
|
||||||
<div class="card-nest">
|
<div class="card-nest">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<b>✨ Welcome to <i>{{ config.name }}</i>!</b>
|
<b>✨ Welcome to <i>{{ config.name }}</i>!</b>
|
||||||
|
@ -26,15 +26,15 @@
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="card w-full flex flex-col gap-2">
|
<div class="card w-full flex flex-col gap-2">
|
||||||
{% for post in list %}
|
{% for post in list %}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% 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) }}
|
{{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ components::pagination(page=page, items=list|length) }}
|
{{ components::pagination(page=page, items=list|length) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="card w-full flex flex-col gap-2">
|
<div class="card w-full flex flex-col gap-2">
|
||||||
{% for post in list %}
|
{% for post in list %}
|
||||||
{% if post[2].read_access == "Everybody" %}
|
{% if post[2].read_access == "Everybody" -%}
|
||||||
{% if post[0].context.repost and post[0].context.repost.reposting %}
|
{% 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) }}
|
{{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2]) }}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{{ components::pagination(page=page, items=list|length) }}
|
{{ components::pagination(page=page, items=list|length) }}
|
||||||
|
|
75
crates/app/src/public/html/timelines/search.html
Normal file
75
crates/app/src/public/html/timelines/search.html
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
{% extends "root.html" %} {% block head %}
|
||||||
|
<title>Search - {{ config.name }}</title>
|
||||||
|
{% endblock %} {% block body %} {{ macros::nav() }}
|
||||||
|
<main class="flex flex-col gap-2">
|
||||||
|
{{ macros::timelines_nav(selected="search") }}
|
||||||
|
<div class="card-nest w-full">
|
||||||
|
<div class="card small flex items-center justify-between gap-2">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
{{ icon "search" }} {% if not profile -%}
|
||||||
|
<span>{{ text "general:link.search" }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span>{{ components::full_username(user=profile) }}</span>
|
||||||
|
{%- endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card w-full flex flex-col gap-2">
|
||||||
|
{% if not profile and not user.permissions|has_supporter -%} {{
|
||||||
|
components::supporter_ad(body="Become a supporter for full-site
|
||||||
|
search!") }} {% else %}
|
||||||
|
<form class="flex flex-col gap-2">
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="query"
|
||||||
|
id="query"
|
||||||
|
required
|
||||||
|
value="{{ query }}"
|
||||||
|
placeholder="{% if profile -%}Search {{ profile.username }}'s posts{% else %}Search all posts{%- endif %}"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{% if profile -%}
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="hidden"
|
||||||
|
value="{{ profile.id }}"
|
||||||
|
name="profile"
|
||||||
|
id="profile"
|
||||||
|
/>
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
<button class="small square">{{ icon "search" }}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if config.manuals.search_help -%}
|
||||||
|
<span
|
||||||
|
><a href="{{ config.manuals.search_help }}">
|
||||||
|
Search help
|
||||||
|
</a></span
|
||||||
|
>
|
||||||
|
{%- endif %}
|
||||||
|
</form>
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
{% 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]) }}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if profile -%}
|
||||||
|
{{ components::pagination(page=page, items=list|length, key="&profile=" ~ profile.id, value="&query=" ~ query) }}
|
||||||
|
{% else %}
|
||||||
|
{{ components::pagination(page=page, items=list|length, key="&query=" ~ query) }}
|
||||||
|
{%- endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
|
@ -1,12 +1,15 @@
|
||||||
use super::{PaginatedQuery, render_error};
|
use super::{PaginatedQuery, render_error};
|
||||||
use crate::{State, assets::initial_context, get_lang, get_user_from_token};
|
use crate::{
|
||||||
|
assets::initial_context, check_user_blocked_or_private, get_lang, get_user_from_token, State,
|
||||||
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, Query},
|
extract::{Path, Query},
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
Extension,
|
Extension,
|
||||||
};
|
};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::CookieJar;
|
||||||
use tetratto_core::model::{requests::ActionType, Error};
|
use serde::Deserialize;
|
||||||
|
use tetratto_core::model::{permissions::FinePermission, requests::ActionType, Error};
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
use pathbufd::PathBufD;
|
use pathbufd::PathBufD;
|
||||||
|
|
||||||
|
@ -497,3 +500,96 @@ pub async fn markdown_document_request(
|
||||||
// return
|
// return
|
||||||
Ok(Html(data.1.render("misc/markdown.html", &context).unwrap()))
|
Ok(Html(data.1.render("misc/markdown.html", &context).unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct SearchQuery {
|
||||||
|
#[serde(default)]
|
||||||
|
pub query: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub profile: usize,
|
||||||
|
#[serde(default)]
|
||||||
|
pub page: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `/search`
|
||||||
|
pub async fn search_request(
|
||||||
|
jar: CookieJar,
|
||||||
|
Extension(data): Extension<State>,
|
||||||
|
Query(mut req): Query<SearchQuery>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let data = data.read().await;
|
||||||
|
let user = match get_user_from_token!(jar, data.0) {
|
||||||
|
Some(ua) => ua,
|
||||||
|
None => {
|
||||||
|
return Err(Html(
|
||||||
|
render_error(Error::NotAllowed, &jar, &data, &None).await,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if req.profile == 0 && !user.permissions.check(FinePermission::SUPPORTER) {
|
||||||
|
req.query = String::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
req.query = req.query.trim().replace(" ", " & "); // change spaces into & for tsquery
|
||||||
|
|
||||||
|
let ignore_users = data.0.get_userblocks_receivers(user.id).await;
|
||||||
|
|
||||||
|
let list = if req.query.is_empty() {
|
||||||
|
Vec::new()
|
||||||
|
} else {
|
||||||
|
if req.profile != 0 {
|
||||||
|
match data
|
||||||
|
.0
|
||||||
|
.get_posts_by_user_searched(req.profile, 12, req.page, &req.query, &Some(&user))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(l) => match data
|
||||||
|
.0
|
||||||
|
.fill_posts_with_community(l, user.id, &ignore_users, &Some(user.clone()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(l) => l,
|
||||||
|
Err(_) => Vec::new(),
|
||||||
|
},
|
||||||
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match data.0.get_posts_searched(12, req.page, &req.query).await {
|
||||||
|
Ok(l) => match data
|
||||||
|
.0
|
||||||
|
.fill_posts_with_community(l, user.id, &ignore_users, &Some(user.clone()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(l) => l,
|
||||||
|
Err(_) => Vec::new(),
|
||||||
|
},
|
||||||
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let profile = if req.profile != 0 {
|
||||||
|
Some(match data.0.get_user_by_id(req.profile).await {
|
||||||
|
Ok(ua) => {
|
||||||
|
check_user_blocked_or_private!(Some(user.clone()), ua, data, jar);
|
||||||
|
ua
|
||||||
|
}
|
||||||
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let lang = get_lang!(jar, data.0);
|
||||||
|
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||||
|
|
||||||
|
context.insert("list", &list);
|
||||||
|
context.insert("profile", &profile);
|
||||||
|
context.insert("query", &req.query);
|
||||||
|
context.insert("page", &req.page);
|
||||||
|
|
||||||
|
Ok(Html(
|
||||||
|
data.1.render("timelines/search.html", &context).unwrap(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ pub fn routes() -> Router {
|
||||||
.route("/popular", get(misc::popular_request))
|
.route("/popular", get(misc::popular_request))
|
||||||
.route("/following", get(misc::following_request))
|
.route("/following", get(misc::following_request))
|
||||||
.route("/all", get(misc::all_request))
|
.route("/all", get(misc::all_request))
|
||||||
|
.route("/search", get(misc::search_request))
|
||||||
// question timelines
|
// question timelines
|
||||||
.route("/questions", get(misc::index_questions_request))
|
.route("/questions", get(misc::index_questions_request))
|
||||||
.route("/popular/questions", get(misc::popular_questions_request))
|
.route("/popular/questions", get(misc::popular_questions_request))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tetratto-core"
|
name = "tetratto-core"
|
||||||
version = "3.1.0"
|
version = "4.0.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -196,6 +196,21 @@ pub struct StripeConfig {
|
||||||
pub billing_portal_url: String,
|
pub billing_portal_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Manuals config (search help, etc)
|
||||||
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
|
pub struct ManualsConfig {
|
||||||
|
/// The page shown for help with search syntax.
|
||||||
|
pub search_help: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ManualsConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
search_help: "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Configuration file
|
/// Configuration file
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
@ -259,6 +274,9 @@ pub struct Config {
|
||||||
pub html_footer_path: String,
|
pub html_footer_path: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub stripe: Option<StripeConfig>,
|
pub stripe: Option<StripeConfig>,
|
||||||
|
/// The relative paths to manuals.
|
||||||
|
#[serde(default)]
|
||||||
|
pub manuals: ManualsConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_name() -> String {
|
fn default_name() -> String {
|
||||||
|
@ -307,12 +325,15 @@ fn default_banned_usernames() -> Vec<String> {
|
||||||
"moderator".to_string(),
|
"moderator".to_string(),
|
||||||
"api".to_string(),
|
"api".to_string(),
|
||||||
"communities".to_string(),
|
"communities".to_string(),
|
||||||
|
"community".to_string(),
|
||||||
"notifs".to_string(),
|
"notifs".to_string(),
|
||||||
"notification".to_string(),
|
"notification".to_string(),
|
||||||
"post".to_string(),
|
"post".to_string(),
|
||||||
"void".to_string(),
|
"void".to_string(),
|
||||||
"anonymous".to_string(),
|
"anonymous".to_string(),
|
||||||
|
"stacks".to_string(),
|
||||||
"stack".to_string(),
|
"stack".to_string(),
|
||||||
|
"search".to_string(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,6 +349,10 @@ fn default_connections() -> ConnectionsConfig {
|
||||||
ConnectionsConfig::default()
|
ConnectionsConfig::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_manuals() -> ManualsConfig {
|
||||||
|
ManualsConfig::default()
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -348,6 +373,7 @@ impl Default for Config {
|
||||||
connections: default_connections(),
|
connections: default_connections(),
|
||||||
html_footer_path: String::new(),
|
html_footer_path: String::new(),
|
||||||
stripe: None,
|
stripe: None,
|
||||||
|
manuals: default_manuals(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,5 +13,6 @@ CREATE TABLE IF NOT EXISTS posts (
|
||||||
comment_count INT NOT NULL,
|
comment_count INT NOT NULL,
|
||||||
-- ...
|
-- ...
|
||||||
uploads TEXT NOT NULL,
|
uploads TEXT NOT NULL,
|
||||||
is_deleted INT NOT NULL
|
is_deleted INT NOT NULL,
|
||||||
|
tsvector_content tsvector GENERATED ALWAYS AS (to_tsvector ('english', coalesce(content, ''))) STORED
|
||||||
)
|
)
|
||||||
|
|
|
@ -52,6 +52,37 @@ macro_rules! private_post_replying {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
($post:ident, $replying_posts:ident, id=$user_id:ident, $data:ident) => {
|
||||||
|
// post owner is not following us
|
||||||
|
// check if we're the owner of the post the post is replying to
|
||||||
|
// all routes but 1 must lead to continue
|
||||||
|
if let Some(replying) = $post.replying_to {
|
||||||
|
if replying != 0 {
|
||||||
|
if let Some(post) = $replying_posts.get(&replying) {
|
||||||
|
// we've seen this post before
|
||||||
|
if post.owner != $user_id {
|
||||||
|
// we aren't the owner of this post,
|
||||||
|
// so we can't see their comment
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we haven't seen this post before
|
||||||
|
let post = $data.get_post_by_id(replying).await?;
|
||||||
|
|
||||||
|
if post.owner != $user_id {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$replying_posts.insert(post.id, post);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataManager {
|
impl DataManager {
|
||||||
|
@ -317,6 +348,7 @@ impl DataManager {
|
||||||
|
|
||||||
let mut seen_before: HashMap<(usize, usize), (User, Community)> = HashMap::new();
|
let mut seen_before: HashMap<(usize, usize), (User, Community)> = HashMap::new();
|
||||||
let mut seen_user_follow_statuses: HashMap<(usize, usize), bool> = HashMap::new();
|
let mut seen_user_follow_statuses: HashMap<(usize, usize), bool> = HashMap::new();
|
||||||
|
let mut replying_posts: HashMap<usize, Post> = HashMap::new();
|
||||||
|
|
||||||
for post in posts {
|
for post in posts {
|
||||||
if post.is_deleted {
|
if post.is_deleted {
|
||||||
|
@ -355,9 +387,8 @@ impl DataManager {
|
||||||
if user_id != ua.id {
|
if user_id != ua.id {
|
||||||
if let Some(is_following) = seen_user_follow_statuses.get(&(ua.id, user_id))
|
if let Some(is_following) = seen_user_follow_statuses.get(&(ua.id, user_id))
|
||||||
{
|
{
|
||||||
if !is_following && (ua.id != user_id) {
|
if !is_following {
|
||||||
// post owner is not following us
|
private_post_replying!(post, replying_posts, id = user_id, self);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if self
|
if self
|
||||||
|
@ -367,7 +398,7 @@ impl DataManager {
|
||||||
{
|
{
|
||||||
// post owner is not following us
|
// post owner is not following us
|
||||||
seen_user_follow_statuses.insert((ua.id, user_id), false);
|
seen_user_follow_statuses.insert((ua.id, user_id), false);
|
||||||
continue;
|
private_post_replying!(post, replying_posts, id = user_id, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
seen_user_follow_statuses.insert((ua.id, user_id), true);
|
seen_user_follow_statuses.insert((ua.id, user_id), true);
|
||||||
|
@ -428,9 +459,9 @@ impl DataManager {
|
||||||
let res = query_rows!(
|
let res = query_rows!(
|
||||||
&conn,
|
&conn,
|
||||||
&format!(
|
&format!(
|
||||||
"SELECT * FROM posts WHERE owner = $1 AND replying_to = 0 AND NOT context LIKE '%\"is_profile_pinned\":true%' {} ORDER BY created DESC LIMIT $2 OFFSET $3",
|
"SELECT * FROM posts WHERE owner = $1 AND replying_to = 0 AND NOT (context::json->>'is_profile_pinned')::boolean {} ORDER BY created DESC LIMIT $2 OFFSET $3",
|
||||||
if hide_nsfw {
|
if hide_nsfw {
|
||||||
"AND NOT context LIKE '%\"is_nsfw\":true%'"
|
"AND NOT (context::json->>'is_nsfw')::boolean"
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
@ -446,6 +477,101 @@ impl DataManager {
|
||||||
Ok(res.unwrap())
|
Ok(res.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get all posts from the given user (searched).
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `id` - the ID of the user the requested posts belong to
|
||||||
|
/// * `batch` - the limit of posts in each page
|
||||||
|
/// * `page` - the page number
|
||||||
|
/// * `text_query` - the search query
|
||||||
|
/// * `user` - the user who is viewing the posts
|
||||||
|
pub async fn get_posts_by_user_searched(
|
||||||
|
&self,
|
||||||
|
id: usize,
|
||||||
|
batch: usize,
|
||||||
|
page: usize,
|
||||||
|
text_query: &str,
|
||||||
|
user: &Option<&User>,
|
||||||
|
) -> Result<Vec<Post>> {
|
||||||
|
let other_user = self.get_user_by_id(id).await?;
|
||||||
|
|
||||||
|
let conn = match self.connect().await {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
|
};
|
||||||
|
|
||||||
|
// check if we should hide nsfw posts
|
||||||
|
let mut hide_nsfw: bool = true;
|
||||||
|
|
||||||
|
if let Some(ua) = user {
|
||||||
|
if ua.id == other_user.id {
|
||||||
|
hide_nsfw = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if other_user.settings.private_profile {
|
||||||
|
hide_nsfw = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
let res = query_rows!(
|
||||||
|
&conn,
|
||||||
|
&format!(
|
||||||
|
"SELECT * FROM posts WHERE owner = $1 AND tsvector_content @@ to_tsquery($2) AND replying_to = 0 AND NOT (context::json->>'is_profile_pinned')::boolean {} ORDER BY created DESC LIMIT $3 OFFSET $4",
|
||||||
|
if hide_nsfw {
|
||||||
|
"AND NOT (context::json->>'is_nsfw')::boolean"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
),
|
||||||
|
params![
|
||||||
|
&(id as i64),
|
||||||
|
&text_query,
|
||||||
|
&(batch as i64),
|
||||||
|
&((page * batch) as i64)
|
||||||
|
],
|
||||||
|
|x| { Self::get_post_from_row(x) }
|
||||||
|
);
|
||||||
|
|
||||||
|
if res.is_err() {
|
||||||
|
return Err(Error::GeneralNotFound("post".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res.unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get all post (searched).
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `batch` - the limit of posts in each page
|
||||||
|
/// * `page` - the page number
|
||||||
|
/// * `text_query` - the search query
|
||||||
|
pub async fn get_posts_searched(
|
||||||
|
&self,
|
||||||
|
batch: usize,
|
||||||
|
page: usize,
|
||||||
|
text_query: &str,
|
||||||
|
) -> Result<Vec<Post>> {
|
||||||
|
let conn = match self.connect().await {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
|
};
|
||||||
|
|
||||||
|
// ...
|
||||||
|
let res = query_rows!(
|
||||||
|
&conn,
|
||||||
|
"SELECT * FROM posts WHERE tsvector_content @@ to_tsquery($1) AND replying_to = 0 AND NOT (context::json->>'is_profile_pinned')::boolean ORDER BY created DESC LIMIT $2 OFFSET $3",
|
||||||
|
params![&text_query, &(batch as i64), &((page * batch) as i64)],
|
||||||
|
|x| { Self::get_post_from_row(x) }
|
||||||
|
);
|
||||||
|
|
||||||
|
if res.is_err() {
|
||||||
|
return Err(Error::GeneralNotFound("post".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res.unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get all posts from the given user with the given tag (from most recent).
|
/// Get all posts from the given user with the given tag (from most recent).
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -487,7 +613,7 @@ impl DataManager {
|
||||||
&format!(
|
&format!(
|
||||||
"SELECT * FROM posts WHERE owner = $1 AND context::json->>'tags' LIKE $2 {} ORDER BY created DESC LIMIT $3 OFFSET $4",
|
"SELECT * FROM posts WHERE owner = $1 AND context::json->>'tags' LIKE $2 {} ORDER BY created DESC LIMIT $3 OFFSET $4",
|
||||||
if hide_nsfw {
|
if hide_nsfw {
|
||||||
"AND NOT context LIKE '%\"is_nsfw\":true%'"
|
"AND NOT (context::json->>'is_nsfw')::boolean"
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tetratto-l10n"
|
name = "tetratto-l10n"
|
||||||
version = "3.1.0"
|
version = "4.0.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tetratto-shared"
|
name = "tetratto-shared"
|
||||||
version = "3.1.0"
|
version = "4.0.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% if user %}
|
{% if user -%}
|
||||||
<script>
|
<script>
|
||||||
console.log("current user is {{ user.username }}");
|
console.log("current user is {{ user.username }}");
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{%- endif %}
|
||||||
|
|
4
sql_changes/posts_tscvector_content.sql
Normal file
4
sql_changes/posts_tscvector_content.sql
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE posts
|
||||||
|
ADD COLUMN tsvector_content tsvector GENERATED ALWAYS AS (to_tsvector ('english', coalesce(content, ''))) STORED;
|
||||||
|
|
||||||
|
CREATE INDEX tsvector_content_idx ON posts USING GIN (tsvector_content);
|
Loading…
Add table
Add a link
Reference in a new issue