diff --git a/crates/app/src/langs/en-US.toml b/crates/app/src/langs/en-US.toml
index abc24e1..788ca48 100644
--- a/crates/app/src/langs/en-US.toml
+++ b/crates/app/src/langs/en-US.toml
@@ -131,6 +131,7 @@ version = "1.0.0"
"communities:label.edit_content" = "Edit content"
"communities:label.repost" = "Repost"
"communities:label.quote_post" = "Quote post"
+"communities:label.ask_about_this" = "Ask about this"
"communities:label.search_results" = "Search results"
"communities:label.query" = "Query"
"communities:label.join_new" = "Join new"
diff --git a/crates/app/src/public/html/components.lisp b/crates/app/src/public/html/components.lisp
index bd03879..0ce8821 100644
--- a/crates/app/src/public/html/components.lisp
+++ b/crates/app/src/public/html/components.lisp
@@ -118,7 +118,7 @@
(div
("class" "card-nest post_outer:{{ post.id }} post_outer")
("is_repost" "{{ is_repost }}")
- (text "{% if question -%} {{ self::question(question=question[0], owner=question[1], profile=owner) }} {% else %}")
+ (text "{% if question -%} {{ self::question(question=question[0], owner=question[1], asking_about=question[2], profile=owner) }} {% else %}")
(div
("class" "card small")
(a
@@ -321,7 +321,6 @@
("class" "button camo small")
("target" "_blank")
(text "{{ icon \"external-link\" }}"))
- (text "{% if user -%}")
(div
("class" "dropdown")
(button
@@ -335,6 +334,7 @@
(b
("class" "title")
(text "{{ text \"general:label.share\" }}"))
+ (text "{% if user -%}")
(button
("onclick" "trigger('me::repost', ['{{ post.id }}', '', '{{ config.town_square }}', true])")
(text "{{ icon \"repeat-2\" }}")
@@ -357,7 +357,14 @@
(span
(text "BlueSky")))
(text "{%- endif %}")
- (text "{% if user.id != post.owner -%}")
+ (a
+ ("class" "button")
+ ("href" "/@{{ owner.username }}?asking_about={{ post.id }}")
+ (icon (text "reply"))
+ (span
+ (str (text "communities:label.ask_about_this"))))
+ (text "{%- endif %}")
+ (text "{% if user and user.id != post.owner -%}")
(b
("class" "title")
(text "{{ text \"general:label.safety\" }}"))
@@ -367,12 +374,12 @@
(text "{{ icon \"flag\" }}")
(span
(text "{{ text \"general:action.report\" }}")))
- (text "{%- endif %} {% if (user.id == post.owner) or is_helper or can_manage_post %}")
+ (text "{%- endif %} {% if user and (user.id == post.owner) or is_helper or can_manage_post %}")
(b
("class" "title")
(text "{{ text \"general:action.manage\" }}"))
; forge stuff
- (text "{% if community and community.is_forge -%} {% if post.is_open -%}")
+ (text "{% if user and community and community.is_forge -%} {% if post.is_open -%}")
(button
("class" "green")
("onclick" "trigger('me::update_open', ['{{ post.id }}', false])")
@@ -388,7 +395,7 @@
(text "{{ text \"forge:action.reopen\" }}")))
(text "{%- endif %} {%- endif %}")
; owner stuff
- (text "{% if user.id == post.owner -%}")
+ (text "{% if user and user.id == post.owner -%}")
(a
("href" "/post/{{ post.id }}#/edit")
(text "{{ icon \"pen\" }}")
@@ -420,8 +427,7 @@
(text "{{ icon \"undo\" }}")
(span
(text "{{ text \"general:action.restore\" }}")))
- (text "{%- endif %} {%- endif %}")))
- (text "{%- endif %}"))))
+ (text "{%- endif %} {%- endif %}"))))))
(text "{% if community and show_community and community.id != config.town_square or question %}"))
(text "{%- endif %} {%- endmacro %} {% macro post_media(upload_ids) -%} {% if upload_ids|length > 0 -%}")
@@ -630,7 +636,7 @@
--{{ css }}: {{ color|color }} !important;
}"))
-(text "{%- endif %} {%- endmacro %} {% macro question(question, owner, show_community=true, secondary=false, profile=false) -%}")
+(text "{%- endif %} {%- endmacro %} {% macro question(question, owner, asking_about=false, show_community=true, secondary=false, profile=false) -%}")
(div
("class" "card question {% if secondary -%}secondary{%- endif %} flex gap-2")
(text "{% if owner.id == 0 or question.context.mask_owner -%}")
@@ -700,6 +706,10 @@
(text "{{ question.content|markdown|safe }}"))
; question drawings
(text "{{ self::post_media(upload_ids=question.drawings) }}")
+ ; asking about
+ (text "{% if asking_about -%}")
+ (text "{{ self::post(post=asking_about[1], owner=asking_about[0], secondary=not secondary, show_community=false) }}")
+ (text "{%- endif %}")
; anonymous user ip thing
; this is only shown if the post author is anonymous AND we are a helper
(text "{% if is_helper and (owner.id == 0 or question.context.mask_owner) -%}")
@@ -736,6 +746,7 @@
("class" "no_p_margin")
(text "{% if header -%} {{ header|markdown|safe }} {% else %} {{ text \"requests:label.ask_question\" }} {%- endif %}")))
(form
+ ("id" "create_question_form")
("class" "card flex flex-col gap-2")
("onsubmit" "create_question_from_form(event)")
(div
@@ -822,6 +833,15 @@
(script
(text "globalThis.gerald = null;
+ // asking about
+ globalThis.asking_about = new URLSearchParams(window.location.search).get(\"asking_about\");
+
+ if (asking_about) {
+ document.getElementById(\"create_question_form\").innerHTML +=
+ `
Asking about: ${asking_about} (cancel)`;
+ }
+
+ // ...
async function create_question_from_form(e) {
e.preventDefault();
await trigger(\"atto::debounce\", [\"questions::create\"]);
@@ -843,7 +863,8 @@
receiver: \"{{ receiver }}\",
community: \"{{ community }}\",
is_global: \"{{ is_global }}\" == \"true\",
- mask_owner: (e.target.mask_owner || { checked:false }).checked
+ mask_owner: (e.target.mask_owner || { checked:false }).checked,
+ asking_about,
}),
);
@@ -872,7 +893,7 @@
(text "{%- endmacro %} {% macro global_question(question, can_manage_questions=false, secondary=false, show_community=true) -%}")
(div
("class" "card-nest")
- (text "{{ self::question(question=question[0], owner=question[1], show_community=show_community) }}")
+ (text "{{ self::question(question=question[0], owner=question[1], asking_about=false, show_community=show_community) }}")
(div
("class" "small card flex justify-between flex-wrap gap-2{% if secondary -%} secondary{%- endif %}")
(div
diff --git a/crates/app/src/public/html/misc/requests.lisp b/crates/app/src/public/html/misc/requests.lisp
index 9ba68d2..b9700f0 100644
--- a/crates/app/src/public/html/misc/requests.lisp
+++ b/crates/app/src/public/html/misc/requests.lisp
@@ -92,7 +92,7 @@
(text "{%- endif %} {% endfor %} {% for question in questions %}")
(div
("class" "card-nest")
- (text "{{ components::question(question=question[0], owner=question[1], profile=user) }}")
+ (text "{{ components::question(question=question[0], owner=question[1], asking_about=question[2], profile=user) }}")
(form
("class" "card flex flex-col gap-2")
("onsubmit" "answer_question_from_form(event, '{{ question[0].id }}')")
diff --git a/crates/app/src/routes/api/v1/communities/questions.rs b/crates/app/src/routes/api/v1/communities/questions.rs
index 1d1a7ba..e67b91b 100644
--- a/crates/app/src/routes/api/v1/communities/questions.rs
+++ b/crates/app/src/routes/api/v1/communities/questions.rs
@@ -96,6 +96,13 @@ pub async fn create_request(
props.context.mask_owner = true;
}
+ if !req.asking_about.is_empty() && !req.is_global {
+ props.context.asking_about = match req.asking_about.parse::() {
+ Ok(x) => Some(x),
+ Err(e) => return Json(Error::MiscError(e.to_string()).into()),
+ }
+ }
+
match data
.create_question(props, drawings.iter().map(|x| x.to_vec()).collect())
.await
diff --git a/crates/app/src/routes/api/v1/mod.rs b/crates/app/src/routes/api/v1/mod.rs
index 38f915e..d4e19c1 100644
--- a/crates/app/src/routes/api/v1/mod.rs
+++ b/crates/app/src/routes/api/v1/mod.rs
@@ -865,6 +865,8 @@ pub struct CreateQuestion {
pub community: String,
#[serde(default)]
pub mask_owner: bool,
+ #[serde(default)]
+ pub asking_about: String,
}
#[derive(Deserialize)]
diff --git a/crates/app/src/routes/pages/communities.rs b/crates/app/src/routes/pages/communities.rs
index 30d2ce0..59dc982 100644
--- a/crates/app/src/routes/pages/communities.rs
+++ b/crates/app/src/routes/pages/communities.rs
@@ -1,3 +1,5 @@
+use std::collections::HashMap;
+
use super::{render_error, PaginatedQuery, RepostsQuery, SearchedQuery};
use crate::{
assets::initial_context, check_user_blocked_or_private, get_lang, get_user_from_token, State,
@@ -798,7 +800,11 @@ pub async fn post_request(
let (_, reposting) = data.0.get_post_reposting(&post, &ignore_users, &user).await;
// check question
- let question = match data.0.get_post_question(&post, &ignore_users).await {
+ let question = match data
+ .0
+ .get_post_question(&post, &ignore_users, &mut HashMap::new())
+ .await
+ {
Ok(q) => q,
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
};
@@ -918,7 +924,11 @@ pub async fn reposts_request(
let reposting = data.0.get_post_reposting(&post, &ignore_users, &user).await;
// check question
- let question = match data.0.get_post_question(&post, &ignore_users).await {
+ let question = match data
+ .0
+ .get_post_question(&post, &ignore_users, &mut HashMap::new())
+ .await
+ {
Ok(q) => q,
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
};
@@ -1069,7 +1079,11 @@ pub async fn likes_request(
.await;
// check question
- let question = match data.0.get_post_question(&post, &ignore_users).await {
+ let question = match data
+ .0
+ .get_post_question(&post, &ignore_users, &mut HashMap::new())
+ .await
+ {
Ok(q) => q,
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
};
diff --git a/crates/core/src/database/posts.rs b/crates/core/src/database/posts.rs
index f17bbea..701c053 100644
--- a/crates/core/src/database/posts.rs
+++ b/crates/core/src/database/posts.rs
@@ -22,10 +22,11 @@ pub type FullPost = (
User,
Community,
Option<(User, Post)>,
- Option<(Question, User)>,
+ Option<(Question, User, Option<(User, Post)>)>,
Option<(Poll, bool, bool)>,
Option,
);
+pub type FullQuestion = (Question, User, Option<(User, Post)>);
macro_rules! private_post_replying {
($post:ident, $replying_posts:ident, $ua1:ident, $data:ident) => {
@@ -224,8 +225,14 @@ impl DataManager {
&self,
post: &Post,
ignore_users: &[usize],
- ) -> Result