add: "ask about this" from neospring

This commit is contained in:
trisua 2025-07-13 18:42:08 -04:00
parent f94570f74c
commit 2c83ed3d9d
9 changed files with 122 additions and 31 deletions

View file

@ -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<UserStack>,
);
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<Option<(Question, User)>> {
seen_questions: &mut HashMap<usize, FullQuestion>,
) -> Result<Option<FullQuestion>> {
if post.context.answering != 0 {
if let Some(q) = seen_questions.get(&post.context.answering) {
return Ok(Some(q.to_owned()));
}
// ...
let question = self.get_question_by_id(post.context.answering).await?;
if ignore_users.contains(&question.owner) {
@ -238,7 +245,11 @@ impl DataManager {
self.get_user_by_id_with_void(question.owner).await?
};
Ok(Some((question, user)))
let asking_about = self.get_question_asking_about(&question).await?;
let full_question = (question, user, asking_about);
seen_questions.insert(post.context.answering, full_question.to_owned());
Ok(Some(full_question))
} else {
Ok(None)
}
@ -322,7 +333,7 @@ impl DataManager {
Post,
User,
Option<(User, Post)>,
Option<(Question, User)>,
Option<(Question, User, Option<(User, Post)>)>,
Option<(Poll, bool, bool)>,
Option<UserStack>,
)>,
@ -332,6 +343,7 @@ impl DataManager {
let mut users: HashMap<usize, User> = HashMap::new();
let mut seen_user_follow_statuses: HashMap<(usize, usize), bool> = HashMap::new();
let mut seen_stacks: HashMap<usize, UserStack> = HashMap::new();
let mut seen_questions: HashMap<usize, FullQuestion> = HashMap::new();
let mut replying_posts: HashMap<usize, Post> = HashMap::new();
for post in posts {
@ -373,7 +385,8 @@ impl DataManager {
post.clone(),
ua.clone(),
reposting,
self.get_post_question(&post, ignore_users).await?,
self.get_post_question(&post, ignore_users, &mut seen_questions)
.await?,
self.get_post_poll(&post, user).await?,
stack,
));
@ -454,7 +467,8 @@ impl DataManager {
post.clone(),
ua,
reposting,
self.get_post_question(&post, ignore_users).await?,
self.get_post_question(&post, ignore_users, &mut seen_questions)
.await?,
self.get_post_poll(&post, user).await?,
stack,
));
@ -477,6 +491,7 @@ impl DataManager {
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_stacks: HashMap<usize, UserStack> = HashMap::new();
let mut seen_questions: HashMap<usize, FullQuestion> = HashMap::new();
let mut replying_posts: HashMap<usize, Post> = HashMap::new();
let mut memberships: HashMap<usize, CommunityMembership> = HashMap::new();
@ -544,7 +559,8 @@ impl DataManager {
ua.clone(),
community.to_owned(),
reposting,
self.get_post_question(&post, ignore_users).await?,
self.get_post_question(&post, ignore_users, &mut seen_questions)
.await?,
self.get_post_poll(&post, user).await?,
stack,
));
@ -643,7 +659,8 @@ impl DataManager {
ua,
community,
reposting,
self.get_post_question(&post, ignore_users).await?,
self.get_post_question(&post, ignore_users, &mut seen_questions)
.await?,
self.get_post_poll(&post, user).await?,
stack,
));
@ -716,8 +733,12 @@ impl DataManager {
}
// question
if let Some((_, ref mut x)) = post.4 {
if let Some((_, ref mut x, ref mut y)) = post.4 {
x.clean();
if y.is_some() {
y.as_mut().unwrap().0.clean();
}
}
// ...

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use oiseau::cache::Cache;
use tetratto_shared::unix_epoch_timestamp;
use crate::model::addr::RemoteAddr;
use crate::model::communities::Post;
use crate::model::communities_permissions::CommunityPermission;
use crate::model::uploads::{MediaType, MediaUpload};
use crate::model::{
@ -38,13 +39,26 @@ impl DataManager {
auto_method!(get_question_by_id()@get_question_from_row -> "SELECT * FROM questions WHERE id = $1" --name="question" --returns=Question --cache-key-tmpl="atto.question:{}");
/// Get the post a given question is asking about.
pub async fn get_question_asking_about(
&self,
question: &Question,
) -> Result<Option<(User, Post)>> {
Ok(if let Some(id) = question.context.asking_about {
let post = self.get_post_by_id(id).await?;
Some((self.get_user_by_id(post.owner).await?, post))
} else {
None
})
}
/// Fill the given vector of questions with their owner as well.
pub async fn fill_questions(
&self,
questions: Vec<Question>,
ignore_users: &[usize],
) -> Result<Vec<(Question, User)>> {
let mut out: Vec<(Question, User)> = Vec::new();
) -> Result<Vec<(Question, User, Option<(User, Post)>)>> {
let mut out: Vec<(Question, User, Option<(User, Post)>)> = Vec::new();
let mut seen_users: HashMap<usize, User> = HashMap::new();
for question in questions {
@ -53,7 +67,8 @@ impl DataManager {
}
if let Some(ua) = seen_users.get(&question.owner) {
out.push((question, ua.to_owned()));
let asking_about = self.get_question_asking_about(&question).await?;
out.push((question, ua.to_owned(), asking_about));
} else {
let user = if question.owner == 0 {
User::anonymous()
@ -62,7 +77,9 @@ impl DataManager {
};
seen_users.insert(question.owner, user.clone());
out.push((question, user));
let asking_about = self.get_question_asking_about(&question).await?;
out.push((question, user, asking_about));
}
}
@ -72,12 +89,17 @@ impl DataManager {
/// Filter to update questions to clean their owner for public APIs.
pub fn questions_owner_filter(
&self,
questions: &Vec<(Question, User)>,
) -> Vec<(Question, User)> {
let mut out: Vec<(Question, User)> = Vec::new();
questions: &Vec<(Question, User, Option<(User, Post)>)>,
) -> Vec<(Question, User, Option<(User, Post)>)> {
let mut out: Vec<(Question, User, Option<(User, Post)>)> = Vec::new();
for mut question in questions.clone() {
question.1.clean();
if question.2.is_some() {
question.2.as_mut().unwrap().0.clean();
}
out.push(question);
}

View file

@ -387,6 +387,9 @@ pub struct QuestionContext {
/// If the owner is shown as anonymous in the UI.
#[serde(default)]
pub mask_owner: bool,
/// The POST this question is asking about.
#[serde(default)]
pub asking_about: Option<usize>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]