add: post tags

This commit is contained in:
trisua 2025-05-08 20:08:43 -04:00
parent efeb660de6
commit 8c3024cb40
13 changed files with 180 additions and 34 deletions

View file

@ -56,6 +56,7 @@ version = "1.0.0"
"auth:label.relationship" = "Relationship"
"auth:label.joined_communities" = "Joined communities"
"auth:label.recent_posts" = "Recent posts"
"auth:label.recent_with_tag" = "Recent posts (with tag)"
"auth:label.before_you_view" = "Before you view"
"auth:label.private_profile" = "Private profile"
"auth:label.private_profile_message" = "This profile is private, meaning you can only view it if they follow you."

View file

@ -197,6 +197,7 @@
reactions_enabled: true,
is_nsfw: false,
content_warning: "",
tags: "",
};
window.BLANK_INITIAL_SETTINGS = JSON.stringify(
@ -238,12 +239,28 @@
window.POST_INITIAL_SETTINGS.content_warning,
"textarea",
],
[
["tags", "Tags"],
window.POST_INITIAL_SETTINGS.tags,
"input",
{
embed_html:
'<span class="fade">Tags should be separated by a comma.</span>',
},
],
];
trigger("ui::generate_settings_ui", [
document.getElementById("post_options"),
settings_fields,
window.POST_INITIAL_SETTINGS,
{
tags: (new_tags) => {
window.POST_INITIAL_SETTINGS.tags = new_tags
.split(",")
.map((t) => t.trim());
},
},
]);
}, 250);
</script>

View file

@ -253,6 +253,16 @@ and show_community and community.id != config.town_square or question %}
</span>
</details>
{% endif %}
<div class="flex flex-wrap gap-2 fade">
{% for tag in post.context.tags %}
<a
href="/@{{ owner.username }}?tag={{ tag }}"
class="flush fade"
>#{{ tag }}</a
>
{% endfor %}
</div>
</div>
</div>

View file

@ -168,6 +168,15 @@
settings.content_warning,
"textarea",
],
[
["tags", "Tags"],
settings.tags.join(", "),
"input",
{
embed_html:
'<span class="fade">Tags should be separated by a comma.</span>',
},
],
];
if (can_manage_pins) {
@ -186,7 +195,13 @@
]);
}
ui.generate_settings_ui(element, settings_fields, settings);
ui.generate_settings_ui(element, settings_fields, settings, {
tags: (new_tags) => {
settings.tags = new_tags
.split(",")
.map((t) => t.trim());
},
});
}, 250);
</script>
</div>

View file

@ -5,7 +5,7 @@ profile.settings.allow_anonymous_questions) %}
{{ components::create_question_form(receiver=profile.id,
header=profile.settings.motivational_header) }}
</div>
{% endif %} {% if pinned|length != 0 %}
{% endif %} {% if not tag and pinned|length != 0 %}
<div class="card-nest">
<div class="card small flex gap-2 items-center">
{{ icon "pin" }}
@ -29,8 +29,11 @@ profile.settings.allow_anonymous_questions) %}
<div class="card-nest">
<div class="card small flex gap-2 items-center">
{{ icon "clock" }}
{% if not tag %} {{ icon "clock" }}
<span>{{ text "auth:label.recent_posts" }}</span>
{% else %} {{ icon "tag" }}
<span>{{ text "auth:label.recent_with_tag" }}: <b>{{ tag }}</b></span>
{% endif %}
</div>
<div class="card flex flex-col gap-4">

View file

@ -858,7 +858,7 @@ media_theme_pref();
<label for="${option.key}"><b>${option.label.replaceAll("_", " ")}</b></label>
</div>
<div class="card">
<div class="card flex flex-col gap-2">
<${option.input_element_type || "input"}
type="text"
onchange="window.set_setting_field('${option.key}', event.target.value)"
@ -867,6 +867,8 @@ media_theme_pref();
id="${option.key}"
${option.input_element_type === "input" ? `value="${option.value}"/>` : ">"}
${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
${(option.attributes || { embed_html: "" }).embed_html}
</div>
</div>`;
});
@ -885,7 +887,7 @@ ${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
}
window.set_setting_field = (key, value) => {
if (settings_ref) {
if (settings_ref && !key_map[key]) {
settings_ref[key] = value;
} else {
key_map[key](value);

View file

@ -140,6 +140,8 @@ pub struct ProfileQuery {
pub page: usize,
#[serde(default)]
pub warning: bool,
#[serde(default)]
pub tag: String,
}
#[derive(Deserialize)]

View file

@ -198,40 +198,66 @@ pub async fn posts_request(
Vec::new()
};
let posts = match data
.0
.get_posts_by_user(other_user.id, 12, props.page, &user)
.await
{
Ok(p) => match data
let posts = if props.tag.is_empty() {
match data
.0
.fill_posts_with_community(
p,
if let Some(ref ua) = user { ua.id } else { 0 },
&ignore_users,
)
.get_posts_by_user(other_user.id, 12, props.page, &user)
.await
{
Ok(p) => p,
Ok(p) => match data
.0
.fill_posts_with_community(
p,
if let Some(ref ua) = user { ua.id } else { 0 },
&ignore_users,
)
.await
{
Ok(p) => p,
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
},
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
},
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
}
} else {
match data
.0
.get_posts_by_user_tag(other_user.id, &props.tag, 12, props.page, &user)
.await
{
Ok(p) => match data
.0
.fill_posts_with_community(
p,
if let Some(ref ua) = user { ua.id } else { 0 },
&ignore_users,
)
.await
{
Ok(p) => p,
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
},
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
}
};
let pinned = match data.0.get_pinned_posts_by_user(other_user.id).await {
Ok(p) => match data
.0
.fill_posts_with_community(
p,
if let Some(ref ua) = user { ua.id } else { 0 },
&ignore_users,
)
.await
{
Ok(p) => p,
let pinned = if props.tag.is_empty() {
match data.0.get_pinned_posts_by_user(other_user.id).await {
Ok(p) => match data
.0
.fill_posts_with_community(
p,
if let Some(ref ua) = user { ua.id } else { 0 },
&ignore_users,
)
.await
{
Ok(p) => Some(p),
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
},
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
},
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
}
} else {
None
};
let communities = match data.0.get_memberships_by_owner(other_user.id).await {
@ -282,6 +308,7 @@ pub async fn posts_request(
context.insert("posts", &posts);
context.insert("pinned", &pinned);
context.insert("page", &props.page);
context.insert("tag", &props.tag);
profile_context(
&mut context,
&user,