mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-29 12:51:03 +00:00
Renaming person_mention to person_comment_mention.
This commit is contained in:
parent
02ba54c589
commit
5b87cd8153
26 changed files with 349 additions and 254 deletions
|
@ -1,18 +1,18 @@
|
||||||
use actix_web::web::{Data, Json, Query};
|
use actix_web::web::{Data, Json, Query};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{GetPersonMentions, GetPersonMentionsResponse},
|
person::{GetPersonCommentMentions, GetPersonCommentMentionsResponse},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_db_views_actor::person_mention_view::PersonMentionQuery;
|
use lemmy_db_views_actor::person_comment_mention_view::PersonCommentMentionQuery;
|
||||||
use lemmy_utils::error::LemmyResult;
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn list_mentions(
|
pub async fn list_comment_mentions(
|
||||||
data: Query<GetPersonMentions>,
|
data: Query<GetPersonCommentMentions>,
|
||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
local_user_view: LocalUserView,
|
local_user_view: LocalUserView,
|
||||||
) -> LemmyResult<Json<GetPersonMentionsResponse>> {
|
) -> LemmyResult<Json<GetPersonCommentMentionsResponse>> {
|
||||||
let sort = data.sort;
|
let sort = data.sort;
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
|
@ -20,7 +20,7 @@ pub async fn list_mentions(
|
||||||
let person_id = Some(local_user_view.person.id);
|
let person_id = Some(local_user_view.person.id);
|
||||||
let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
|
let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
|
||||||
|
|
||||||
let mentions = PersonMentionQuery {
|
let comment_mentions = PersonCommentMentionQuery {
|
||||||
recipient_id: person_id,
|
recipient_id: person_id,
|
||||||
my_person_id: person_id,
|
my_person_id: person_id,
|
||||||
sort,
|
sort,
|
||||||
|
@ -32,5 +32,5 @@ pub async fn list_mentions(
|
||||||
.list(&mut context.pool())
|
.list(&mut context.pool())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(Json(GetPersonMentionsResponse { mentions }))
|
Ok(Json(GetPersonCommentMentionsResponse { comment_mentions }))
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ use actix_web::web::{Data, Json};
|
||||||
use lemmy_api_common::{context::LemmyContext, person::GetRepliesResponse};
|
use lemmy_api_common::{context::LemmyContext, person::GetRepliesResponse};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
comment_reply::CommentReply,
|
comment_reply::CommentReply,
|
||||||
person_mention::PersonMention,
|
person_comment_mention::PersonCommentMention,
|
||||||
private_message::PrivateMessage,
|
private_message::PrivateMessage,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
|
@ -20,8 +20,8 @@ pub async fn mark_all_notifications_read(
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
|
|
||||||
// Mark all user mentions as read
|
// Mark all comment mentions as read
|
||||||
PersonMention::mark_all_as_read(&mut context.pool(), person_id)
|
PersonCommentMention::mark_all_as_read(&mut context.pool(), person_id)
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
use actix_web::web::{Data, Json};
|
||||||
|
use lemmy_api_common::{
|
||||||
|
context::LemmyContext,
|
||||||
|
person::{MarkPersonCommentMentionAsRead, PersonCommentMentionResponse},
|
||||||
|
};
|
||||||
|
use lemmy_db_schema::{
|
||||||
|
source::person_comment_mention::{PersonCommentMention, PersonCommentMentionUpdateForm},
|
||||||
|
traits::Crud,
|
||||||
|
};
|
||||||
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
|
use lemmy_db_views_actor::structs::PersonCommentMentionView;
|
||||||
|
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(context))]
|
||||||
|
pub async fn mark_comment_mention_as_read(
|
||||||
|
data: Json<MarkPersonCommentMentionAsRead>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
local_user_view: LocalUserView,
|
||||||
|
) -> LemmyResult<Json<PersonCommentMentionResponse>> {
|
||||||
|
let person_comment_mention_id = data.person_comment_mention_id;
|
||||||
|
let read_person_comment_mention =
|
||||||
|
PersonCommentMention::read(&mut context.pool(), person_comment_mention_id).await?;
|
||||||
|
|
||||||
|
if local_user_view.person.id != read_person_comment_mention.recipient_id {
|
||||||
|
Err(LemmyErrorType::CouldntUpdateComment)?
|
||||||
|
}
|
||||||
|
|
||||||
|
let person_comment_mention_id = read_person_comment_mention.id;
|
||||||
|
let read = Some(data.read);
|
||||||
|
PersonCommentMention::update(
|
||||||
|
&mut context.pool(),
|
||||||
|
person_comment_mention_id,
|
||||||
|
&PersonCommentMentionUpdateForm { read },
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
|
|
||||||
|
let person_comment_mention_id = read_person_comment_mention.id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let person_comment_mention_view = PersonCommentMentionView::read(
|
||||||
|
&mut context.pool(),
|
||||||
|
person_comment_mention_id,
|
||||||
|
Some(person_id),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(PersonCommentMentionResponse {
|
||||||
|
person_comment_mention_view,
|
||||||
|
}))
|
||||||
|
}
|
|
@ -1,45 +0,0 @@
|
||||||
use actix_web::web::{Data, Json};
|
|
||||||
use lemmy_api_common::{
|
|
||||||
context::LemmyContext,
|
|
||||||
person::{MarkPersonMentionAsRead, PersonMentionResponse},
|
|
||||||
};
|
|
||||||
use lemmy_db_schema::{
|
|
||||||
source::person_mention::{PersonMention, PersonMentionUpdateForm},
|
|
||||||
traits::Crud,
|
|
||||||
};
|
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
|
||||||
use lemmy_db_views_actor::structs::PersonMentionView;
|
|
||||||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
|
||||||
pub async fn mark_person_mention_as_read(
|
|
||||||
data: Json<MarkPersonMentionAsRead>,
|
|
||||||
context: Data<LemmyContext>,
|
|
||||||
local_user_view: LocalUserView,
|
|
||||||
) -> LemmyResult<Json<PersonMentionResponse>> {
|
|
||||||
let person_mention_id = data.person_mention_id;
|
|
||||||
let read_person_mention = PersonMention::read(&mut context.pool(), person_mention_id).await?;
|
|
||||||
|
|
||||||
if local_user_view.person.id != read_person_mention.recipient_id {
|
|
||||||
Err(LemmyErrorType::CouldntUpdateComment)?
|
|
||||||
}
|
|
||||||
|
|
||||||
let person_mention_id = read_person_mention.id;
|
|
||||||
let read = Some(data.read);
|
|
||||||
PersonMention::update(
|
|
||||||
&mut context.pool(),
|
|
||||||
person_mention_id,
|
|
||||||
&PersonMentionUpdateForm { read },
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
|
||||||
|
|
||||||
let person_mention_id = read_person_mention.id;
|
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let person_mention_view =
|
|
||||||
PersonMentionView::read(&mut context.pool(), person_mention_id, Some(person_id)).await?;
|
|
||||||
|
|
||||||
Ok(Json(PersonMentionResponse {
|
|
||||||
person_mention_view,
|
|
||||||
}))
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
pub mod list_mentions;
|
pub mod list_comment_mentions;
|
||||||
pub mod list_replies;
|
pub mod list_replies;
|
||||||
pub mod mark_all_read;
|
pub mod mark_all_read;
|
||||||
pub mod mark_mention_read;
|
pub mod mark_comment_mention_read;
|
||||||
pub mod mark_reply_read;
|
pub mod mark_reply_read;
|
||||||
pub mod unread_count;
|
pub mod unread_count;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use actix_web::web::{Data, Json};
|
use actix_web::web::{Data, Json};
|
||||||
use lemmy_api_common::{context::LemmyContext, person::GetUnreadCountResponse};
|
use lemmy_api_common::{context::LemmyContext, person::GetUnreadCountResponse};
|
||||||
use lemmy_db_views::structs::{LocalUserView, PrivateMessageView};
|
use lemmy_db_views::structs::{LocalUserView, PrivateMessageView};
|
||||||
use lemmy_db_views_actor::structs::{CommentReplyView, PersonMentionView};
|
use lemmy_db_views_actor::structs::{CommentReplyView, PersonCommentMentionView};
|
||||||
use lemmy_utils::error::LemmyResult;
|
use lemmy_utils::error::LemmyResult;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
|
@ -12,14 +12,14 @@ pub async fn unread_count(
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
|
|
||||||
let replies =
|
let replies =
|
||||||
CommentReplyView::get_unread_replies(&mut context.pool(), &local_user_view.local_user).await?;
|
CommentReplyView::get_unread_count(&mut context.pool(), &local_user_view.local_user).await?;
|
||||||
|
|
||||||
let mentions =
|
let mentions =
|
||||||
PersonMentionView::get_unread_mentions(&mut context.pool(), &local_user_view.local_user)
|
PersonCommentMentionView::get_unread_count(&mut context.pool(), &local_user_view.local_user)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let private_messages =
|
let private_messages =
|
||||||
PrivateMessageView::get_unread_messages(&mut context.pool(), person_id).await?;
|
PrivateMessageView::get_unread_count(&mut context.pool(), person_id).await?;
|
||||||
|
|
||||||
Ok(Json(GetUnreadCountResponse {
|
Ok(Json(GetUnreadCountResponse {
|
||||||
replies,
|
replies,
|
||||||
|
|
|
@ -18,7 +18,7 @@ use lemmy_db_schema::{
|
||||||
comment::Comment,
|
comment::Comment,
|
||||||
comment_reply::{CommentReply, CommentReplyInsertForm},
|
comment_reply::{CommentReply, CommentReplyInsertForm},
|
||||||
person::Person,
|
person::Person,
|
||||||
person_mention::{PersonMention, PersonMentionInsertForm},
|
person_comment_mention::{PersonCommentMention, PersonCommentMentionInsertForm},
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
|
@ -127,7 +127,7 @@ pub async fn send_local_notifs(
|
||||||
// below by checking recipient ids
|
// below by checking recipient ids
|
||||||
recipient_ids.push(mention_user_view.local_user.id);
|
recipient_ids.push(mention_user_view.local_user.id);
|
||||||
|
|
||||||
let user_mention_form = PersonMentionInsertForm {
|
let person_comment_mention_form = PersonCommentMentionInsertForm {
|
||||||
recipient_id: mention_user_view.person.id,
|
recipient_id: mention_user_view.person.id,
|
||||||
comment_id,
|
comment_id,
|
||||||
read: None,
|
read: None,
|
||||||
|
@ -135,7 +135,7 @@ pub async fn send_local_notifs(
|
||||||
|
|
||||||
// Allow this to fail softly, since comment edits might re-update or replace it
|
// Allow this to fail softly, since comment edits might re-update or replace it
|
||||||
// Let the uniqueness handle this fail
|
// Let the uniqueness handle this fail
|
||||||
PersonMention::create(&mut context.pool(), &user_mention_form)
|
PersonCommentMention::create(&mut context.pool(), &person_comment_mention_form)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::{CommentReplyId, CommunityId, LanguageId, PersonId, PersonMentionId},
|
newtypes::{CommentReplyId, CommunityId, LanguageId, PersonCommentMentionId, PersonId},
|
||||||
sensitive::SensitiveString,
|
sensitive::SensitiveString,
|
||||||
source::{login_token::LoginToken, site::Site},
|
source::{login_token::LoginToken, site::Site},
|
||||||
CommentSortType,
|
CommentSortType,
|
||||||
|
@ -11,7 +11,7 @@ use lemmy_db_views::structs::{CommentView, LocalImageView, PostView};
|
||||||
use lemmy_db_views_actor::structs::{
|
use lemmy_db_views_actor::structs::{
|
||||||
CommentReplyView,
|
CommentReplyView,
|
||||||
CommunityModeratorView,
|
CommunityModeratorView,
|
||||||
PersonMentionView,
|
PersonCommentMentionView,
|
||||||
PersonView,
|
PersonView,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -293,7 +293,7 @@ pub struct GetRepliesResponse {
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
#[cfg_attr(feature = "full", derive(TS))]
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
/// Get mentions for your user.
|
/// Get mentions for your user.
|
||||||
pub struct GetPersonMentions {
|
pub struct GetPersonCommentMentions {
|
||||||
pub sort: Option<CommentSortType>,
|
pub sort: Option<CommentSortType>,
|
||||||
pub page: Option<i64>,
|
pub page: Option<i64>,
|
||||||
pub limit: Option<i64>,
|
pub limit: Option<i64>,
|
||||||
|
@ -304,16 +304,16 @@ pub struct GetPersonMentions {
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
#[cfg_attr(feature = "full", derive(TS))]
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
/// The response of mentions for your user.
|
/// The response of mentions for your user.
|
||||||
pub struct GetPersonMentionsResponse {
|
pub struct GetPersonCommentMentionsResponse {
|
||||||
pub mentions: Vec<PersonMentionView>,
|
pub comment_mentions: Vec<PersonCommentMentionView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
#[cfg_attr(feature = "full", derive(TS))]
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
/// Mark a person mention as read.
|
/// Mark a person mention as read.
|
||||||
pub struct MarkPersonMentionAsRead {
|
pub struct MarkPersonCommentMentionAsRead {
|
||||||
pub person_mention_id: PersonMentionId,
|
pub person_comment_mention_id: PersonCommentMentionId,
|
||||||
pub read: bool,
|
pub read: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,8 +321,8 @@ pub struct MarkPersonMentionAsRead {
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
#[cfg_attr(feature = "full", derive(TS))]
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
/// The response for a person mention action.
|
/// The response for a person mention action.
|
||||||
pub struct PersonMentionResponse {
|
pub struct PersonCommentMentionResponse {
|
||||||
pub person_mention_view: PersonMentionView,
|
pub person_comment_mention_view: PersonCommentMentionView,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -22,7 +22,7 @@ use lemmy_db_schema::{
|
||||||
comment::{Comment, CommentInsertForm, CommentLike, CommentLikeForm},
|
comment::{Comment, CommentInsertForm, CommentLike, CommentLikeForm},
|
||||||
comment_reply::{CommentReply, CommentReplyUpdateForm},
|
comment_reply::{CommentReply, CommentReplyUpdateForm},
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
person_mention::{PersonMention, PersonMentionUpdateForm},
|
person_comment_mention::{PersonCommentMention, PersonCommentMentionUpdateForm},
|
||||||
},
|
},
|
||||||
traits::{Crud, Likeable},
|
traits::{Crud, Likeable},
|
||||||
};
|
};
|
||||||
|
@ -174,17 +174,18 @@ pub async fn create_comment(
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateReplies)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateReplies)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the parent has PersonMentions mark them as read too
|
// If the parent has PersonCommentMentions mark them as read too
|
||||||
let person_mention =
|
let person_comment_mention =
|
||||||
PersonMention::read_by_comment_and_person(&mut context.pool(), parent_id, person_id).await;
|
PersonCommentMention::read_by_comment_and_person(&mut context.pool(), parent_id, person_id)
|
||||||
if let Ok(Some(mention)) = person_mention {
|
.await;
|
||||||
PersonMention::update(
|
if let Ok(Some(mention)) = person_comment_mention {
|
||||||
|
PersonCommentMention::update(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
mention.id,
|
mention.id,
|
||||||
&PersonMentionUpdateForm { read: Some(true) },
|
&PersonCommentMentionUpdateForm { read: Some(true) },
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdatePersonMentions)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdatePersonCommentMentions)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@ pub mod oauth_provider;
|
||||||
pub mod password_reset_request;
|
pub mod password_reset_request;
|
||||||
pub mod person;
|
pub mod person;
|
||||||
pub mod person_block;
|
pub mod person_block;
|
||||||
pub mod person_mention;
|
pub mod person_comment_mention;
|
||||||
|
pub mod person_post_mention;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
pub mod post_report;
|
pub mod post_report;
|
||||||
pub mod private_message;
|
pub mod private_message;
|
||||||
|
|
83
crates/db_schema/src/impls/person_comment_mention.rs
Normal file
83
crates/db_schema/src/impls/person_comment_mention.rs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
use crate::{
|
||||||
|
diesel::OptionalExtension,
|
||||||
|
newtypes::{CommentId, PersonCommentMentionId, PersonId},
|
||||||
|
schema::person_comment_mention,
|
||||||
|
source::person_comment_mention::{
|
||||||
|
PersonCommentMention,
|
||||||
|
PersonCommentMentionInsertForm,
|
||||||
|
PersonCommentMentionUpdateForm,
|
||||||
|
},
|
||||||
|
traits::Crud,
|
||||||
|
utils::{get_conn, DbPool},
|
||||||
|
};
|
||||||
|
use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl};
|
||||||
|
use diesel_async::RunQueryDsl;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Crud for PersonCommentMention {
|
||||||
|
type InsertForm = PersonCommentMentionInsertForm;
|
||||||
|
type UpdateForm = PersonCommentMentionUpdateForm;
|
||||||
|
type IdType = PersonCommentMentionId;
|
||||||
|
|
||||||
|
async fn create(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
person_comment_mention_form: &Self::InsertForm,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
// since the return here isnt utilized, we dont need to do an update
|
||||||
|
// but get_result doesn't return the existing row here
|
||||||
|
insert_into(person_comment_mention::table)
|
||||||
|
.values(person_comment_mention_form)
|
||||||
|
.on_conflict((
|
||||||
|
person_comment_mention::recipient_id,
|
||||||
|
person_comment_mention::comment_id,
|
||||||
|
))
|
||||||
|
.do_update()
|
||||||
|
.set(person_comment_mention_form)
|
||||||
|
.get_result::<Self>(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
person_comment_mention_id: PersonCommentMentionId,
|
||||||
|
person_comment_mention_form: &Self::UpdateForm,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
diesel::update(person_comment_mention::table.find(person_comment_mention_id))
|
||||||
|
.set(person_comment_mention_form)
|
||||||
|
.get_result::<Self>(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PersonCommentMention {
|
||||||
|
pub async fn mark_all_as_read(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
for_recipient_id: PersonId,
|
||||||
|
) -> Result<Vec<PersonCommentMention>, Error> {
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
diesel::update(
|
||||||
|
person_comment_mention::table
|
||||||
|
.filter(person_comment_mention::recipient_id.eq(for_recipient_id))
|
||||||
|
.filter(person_comment_mention::read.eq(false)),
|
||||||
|
)
|
||||||
|
.set(person_comment_mention::read.eq(true))
|
||||||
|
.get_results::<Self>(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn read_by_comment_and_person(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
for_comment_id: CommentId,
|
||||||
|
for_recipient_id: PersonId,
|
||||||
|
) -> Result<Option<Self>, Error> {
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
person_comment_mention::table
|
||||||
|
.filter(person_comment_mention::comment_id.eq(for_comment_id))
|
||||||
|
.filter(person_comment_mention::recipient_id.eq(for_recipient_id))
|
||||||
|
.first(conn)
|
||||||
|
.await
|
||||||
|
.optional()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,76 +0,0 @@
|
||||||
use crate::{
|
|
||||||
diesel::OptionalExtension,
|
|
||||||
newtypes::{CommentId, PersonId, PersonMentionId},
|
|
||||||
schema::person_mention,
|
|
||||||
source::person_mention::{PersonMention, PersonMentionInsertForm, PersonMentionUpdateForm},
|
|
||||||
traits::Crud,
|
|
||||||
utils::{get_conn, DbPool},
|
|
||||||
};
|
|
||||||
use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl};
|
|
||||||
use diesel_async::RunQueryDsl;
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl Crud for PersonMention {
|
|
||||||
type InsertForm = PersonMentionInsertForm;
|
|
||||||
type UpdateForm = PersonMentionUpdateForm;
|
|
||||||
type IdType = PersonMentionId;
|
|
||||||
|
|
||||||
async fn create(
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
person_mention_form: &Self::InsertForm,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
let conn = &mut get_conn(pool).await?;
|
|
||||||
// since the return here isnt utilized, we dont need to do an update
|
|
||||||
// but get_result doesn't return the existing row here
|
|
||||||
insert_into(person_mention::table)
|
|
||||||
.values(person_mention_form)
|
|
||||||
.on_conflict((person_mention::recipient_id, person_mention::comment_id))
|
|
||||||
.do_update()
|
|
||||||
.set(person_mention_form)
|
|
||||||
.get_result::<Self>(conn)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update(
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
person_mention_id: PersonMentionId,
|
|
||||||
person_mention_form: &Self::UpdateForm,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
let conn = &mut get_conn(pool).await?;
|
|
||||||
diesel::update(person_mention::table.find(person_mention_id))
|
|
||||||
.set(person_mention_form)
|
|
||||||
.get_result::<Self>(conn)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PersonMention {
|
|
||||||
pub async fn mark_all_as_read(
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
for_recipient_id: PersonId,
|
|
||||||
) -> Result<Vec<PersonMention>, Error> {
|
|
||||||
let conn = &mut get_conn(pool).await?;
|
|
||||||
diesel::update(
|
|
||||||
person_mention::table
|
|
||||||
.filter(person_mention::recipient_id.eq(for_recipient_id))
|
|
||||||
.filter(person_mention::read.eq(false)),
|
|
||||||
)
|
|
||||||
.set(person_mention::read.eq(true))
|
|
||||||
.get_results::<Self>(conn)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn read_by_comment_and_person(
|
|
||||||
pool: &mut DbPool<'_>,
|
|
||||||
for_comment_id: CommentId,
|
|
||||||
for_recipient_id: PersonId,
|
|
||||||
) -> Result<Option<Self>, Error> {
|
|
||||||
let conn = &mut get_conn(pool).await?;
|
|
||||||
person_mention::table
|
|
||||||
.filter(person_mention::comment_id.eq(for_comment_id))
|
|
||||||
.filter(person_mention::recipient_id.eq(for_recipient_id))
|
|
||||||
.first(conn)
|
|
||||||
.await
|
|
||||||
.optional()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -82,8 +82,14 @@ impl fmt::Display for PrivateMessageId {
|
||||||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
|
||||||
#[cfg_attr(feature = "full", derive(DieselNewType, TS))]
|
#[cfg_attr(feature = "full", derive(DieselNewType, TS))]
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
/// The person mention id.
|
/// The person comment mention id.
|
||||||
pub struct PersonMentionId(i32);
|
pub struct PersonCommentMentionId(i32);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
|
||||||
|
#[cfg_attr(feature = "full", derive(DieselNewType, TS))]
|
||||||
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
|
/// The person post mention id.
|
||||||
|
pub struct PersonPostMentionId(i32);
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
|
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
|
||||||
#[cfg_attr(feature = "full", derive(DieselNewType, TS))]
|
#[cfg_attr(feature = "full", derive(DieselNewType, TS))]
|
||||||
|
|
|
@ -719,16 +719,7 @@ diesel::table! {
|
||||||
}
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
person_follower (follower_id, person_id) {
|
person_comment_mention (id) {
|
||||||
person_id -> Int4,
|
|
||||||
follower_id -> Int4,
|
|
||||||
published -> Timestamptz,
|
|
||||||
pending -> Bool,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
diesel::table! {
|
|
||||||
person_mention (id) {
|
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
recipient_id -> Int4,
|
recipient_id -> Int4,
|
||||||
comment_id -> Int4,
|
comment_id -> Int4,
|
||||||
|
@ -737,6 +728,15 @@ diesel::table! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
person_follower (follower_id, person_id) {
|
||||||
|
person_id -> Int4,
|
||||||
|
follower_id -> Int4,
|
||||||
|
published -> Timestamptz,
|
||||||
|
pending -> Bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
person_post_aggregates (person_id, post_id) {
|
person_post_aggregates (person_id, post_id) {
|
||||||
person_id -> Int4,
|
person_id -> Int4,
|
||||||
|
@ -746,6 +746,16 @@ diesel::table! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
person_post_mention (id) {
|
||||||
|
id -> Int4,
|
||||||
|
recipient_id -> Int4,
|
||||||
|
post_id -> Int4,
|
||||||
|
read -> Bool,
|
||||||
|
published -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
post (id) {
|
post (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
|
@ -1049,10 +1059,12 @@ diesel::joinable!(password_reset_request -> local_user (local_user_id));
|
||||||
diesel::joinable!(person -> instance (instance_id));
|
diesel::joinable!(person -> instance (instance_id));
|
||||||
diesel::joinable!(person_aggregates -> person (person_id));
|
diesel::joinable!(person_aggregates -> person (person_id));
|
||||||
diesel::joinable!(person_ban -> person (person_id));
|
diesel::joinable!(person_ban -> person (person_id));
|
||||||
diesel::joinable!(person_mention -> comment (comment_id));
|
diesel::joinable!(person_comment_mention -> comment (comment_id));
|
||||||
diesel::joinable!(person_mention -> person (recipient_id));
|
diesel::joinable!(person_comment_mention -> person (recipient_id));
|
||||||
diesel::joinable!(person_post_aggregates -> person (person_id));
|
diesel::joinable!(person_post_aggregates -> person (person_id));
|
||||||
diesel::joinable!(person_post_aggregates -> post (post_id));
|
diesel::joinable!(person_post_aggregates -> post (post_id));
|
||||||
|
diesel::joinable!(person_post_mention -> person (recipient_id));
|
||||||
|
diesel::joinable!(person_post_mention -> post (post_id));
|
||||||
diesel::joinable!(post -> community (community_id));
|
diesel::joinable!(post -> community (community_id));
|
||||||
diesel::joinable!(post -> language (language_id));
|
diesel::joinable!(post -> language (language_id));
|
||||||
diesel::joinable!(post -> person (creator_id));
|
diesel::joinable!(post -> person (creator_id));
|
||||||
|
@ -1132,9 +1144,10 @@ diesel::allow_tables_to_appear_in_same_query!(
|
||||||
person_aggregates,
|
person_aggregates,
|
||||||
person_ban,
|
person_ban,
|
||||||
person_block,
|
person_block,
|
||||||
|
person_comment_mention,
|
||||||
person_follower,
|
person_follower,
|
||||||
person_mention,
|
|
||||||
person_post_aggregates,
|
person_post_aggregates,
|
||||||
|
person_post_mention,
|
||||||
post,
|
post,
|
||||||
post_aggregates,
|
post_aggregates,
|
||||||
post_hide,
|
post_hide,
|
||||||
|
|
|
@ -32,7 +32,8 @@ pub mod oauth_provider;
|
||||||
pub mod password_reset_request;
|
pub mod password_reset_request;
|
||||||
pub mod person;
|
pub mod person;
|
||||||
pub mod person_block;
|
pub mod person_block;
|
||||||
pub mod person_mention;
|
pub mod person_comment_mention;
|
||||||
|
pub mod person_post_mention;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
pub mod post_report;
|
pub mod post_report;
|
||||||
pub mod private_message;
|
pub mod private_message;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::newtypes::{CommentId, PersonId, PersonMentionId};
|
use crate::newtypes::{CommentId, PersonCommentMentionId, PersonId};
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use crate::schema::person_mention;
|
use crate::schema::person_comment_mention;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
|
@ -12,12 +12,12 @@ use ts_rs::TS;
|
||||||
derive(Queryable, Selectable, Associations, Identifiable, TS)
|
derive(Queryable, Selectable, Associations, Identifiable, TS)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "full", diesel(belongs_to(crate::source::comment::Comment)))]
|
#[cfg_attr(feature = "full", diesel(belongs_to(crate::source::comment::Comment)))]
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = person_mention))]
|
#[cfg_attr(feature = "full", diesel(table_name = person_comment_mention))]
|
||||||
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
/// A person mention.
|
/// A person mention.
|
||||||
pub struct PersonMention {
|
pub struct PersonCommentMention {
|
||||||
pub id: PersonMentionId,
|
pub id: PersonCommentMentionId,
|
||||||
pub recipient_id: PersonId,
|
pub recipient_id: PersonId,
|
||||||
pub comment_id: CommentId,
|
pub comment_id: CommentId,
|
||||||
pub read: bool,
|
pub read: bool,
|
||||||
|
@ -25,15 +25,15 @@ pub struct PersonMention {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = person_mention))]
|
#[cfg_attr(feature = "full", diesel(table_name = person_comment_mention))]
|
||||||
pub struct PersonMentionInsertForm {
|
pub struct PersonCommentMentionInsertForm {
|
||||||
pub recipient_id: PersonId,
|
pub recipient_id: PersonId,
|
||||||
pub comment_id: CommentId,
|
pub comment_id: CommentId,
|
||||||
pub read: Option<bool>,
|
pub read: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "full", derive(AsChangeset))]
|
#[cfg_attr(feature = "full", derive(AsChangeset))]
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = person_mention))]
|
#[cfg_attr(feature = "full", diesel(table_name = person_comment_mention))]
|
||||||
pub struct PersonMentionUpdateForm {
|
pub struct PersonCommentMentionUpdateForm {
|
||||||
pub read: Option<bool>,
|
pub read: Option<bool>,
|
||||||
}
|
}
|
|
@ -118,7 +118,7 @@ impl PrivateMessageView {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the number of unread messages
|
/// Gets the number of unread messages
|
||||||
pub async fn get_unread_messages(
|
pub async fn get_unread_count(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
my_person_id: PersonId,
|
my_person_id: PersonId,
|
||||||
) -> Result<i64, Error> {
|
) -> Result<i64, Error> {
|
||||||
|
@ -356,7 +356,7 @@ mod tests {
|
||||||
|
|
||||||
assert_length!(1, &timmy_messages);
|
assert_length!(1, &timmy_messages);
|
||||||
|
|
||||||
let timmy_unread_messages = PrivateMessageView::get_unread_messages(pool, timmy.id).await?;
|
let timmy_unread_messages = PrivateMessageView::get_unread_count(pool, timmy.id).await?;
|
||||||
assert_eq!(timmy_unread_messages, 1);
|
assert_eq!(timmy_unread_messages, 1);
|
||||||
|
|
||||||
cleanup(instance.id, pool).await
|
cleanup(instance.id, pool).await
|
||||||
|
@ -398,7 +398,7 @@ mod tests {
|
||||||
|
|
||||||
assert_length!(0, &timmy_messages);
|
assert_length!(0, &timmy_messages);
|
||||||
|
|
||||||
let timmy_unread_messages = PrivateMessageView::get_unread_messages(pool, timmy.id).await?;
|
let timmy_unread_messages = PrivateMessageView::get_unread_count(pool, timmy.id).await?;
|
||||||
assert_eq!(timmy_unread_messages, 0);
|
assert_eq!(timmy_unread_messages, 0);
|
||||||
cleanup(instance.id, pool).await
|
cleanup(instance.id, pool).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,7 @@ impl CommentReplyView {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the number of unread replies
|
/// Gets the number of unread replies
|
||||||
pub async fn get_unread_replies(
|
pub async fn get_unread_count(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
local_user: &LocalUser,
|
local_user: &LocalUser,
|
||||||
) -> Result<i64, Error> {
|
) -> Result<i64, Error> {
|
||||||
|
@ -389,7 +389,7 @@ mod tests {
|
||||||
CommentReply::update(pool, inserted_reply.id, &comment_reply_update_form).await?;
|
CommentReply::update(pool, inserted_reply.id, &comment_reply_update_form).await?;
|
||||||
|
|
||||||
// Test to make sure counts and blocks work correctly
|
// Test to make sure counts and blocks work correctly
|
||||||
let unread_replies = CommentReplyView::get_unread_replies(pool, &recipient_local_user).await?;
|
let unread_replies = CommentReplyView::get_unread_count(pool, &recipient_local_user).await?;
|
||||||
|
|
||||||
let query = CommentReplyQuery {
|
let query = CommentReplyQuery {
|
||||||
recipient_id: Some(recipient_id),
|
recipient_id: Some(recipient_id),
|
||||||
|
@ -412,7 +412,7 @@ mod tests {
|
||||||
PersonBlock::block(pool, &block_form).await?;
|
PersonBlock::block(pool, &block_form).await?;
|
||||||
|
|
||||||
let unread_replies_after_block =
|
let unread_replies_after_block =
|
||||||
CommentReplyView::get_unread_replies(pool, &recipient_local_user).await?;
|
CommentReplyView::get_unread_count(pool, &recipient_local_user).await?;
|
||||||
let replies_after_block = query.clone().list(pool).await?;
|
let replies_after_block = query.clone().list(pool).await?;
|
||||||
assert_eq!(0, unread_replies_after_block);
|
assert_eq!(0, unread_replies_after_block);
|
||||||
assert_eq!(0, replies_after_block.len());
|
assert_eq!(0, replies_after_block.len());
|
||||||
|
@ -440,7 +440,7 @@ mod tests {
|
||||||
let recipient_local_user_view = LocalUserView::read(pool, recipient_local_user.id).await?;
|
let recipient_local_user_view = LocalUserView::read(pool, recipient_local_user.id).await?;
|
||||||
|
|
||||||
let unread_replies_after_hide_bots =
|
let unread_replies_after_hide_bots =
|
||||||
CommentReplyView::get_unread_replies(pool, &recipient_local_user_view.local_user).await?;
|
CommentReplyView::get_unread_count(pool, &recipient_local_user_view.local_user).await?;
|
||||||
|
|
||||||
let mut query_without_bots = query.clone();
|
let mut query_without_bots = query.clone();
|
||||||
query_without_bots.show_bot_accounts = false;
|
query_without_bots.show_bot_accounts = false;
|
||||||
|
|
|
@ -9,7 +9,9 @@ pub mod community_person_ban_view;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
pub mod community_view;
|
pub mod community_view;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
pub mod person_mention_view;
|
pub mod person_comment_mention_view;
|
||||||
|
// #[cfg(feature = "full")]
|
||||||
|
// pub mod person_post_mention_view;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
pub mod person_view;
|
pub mod person_view;
|
||||||
pub mod structs;
|
pub mod structs;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::structs::PersonMentionView;
|
use crate::structs::PersonCommentMentionView;
|
||||||
use diesel::{
|
use diesel::{
|
||||||
dsl::{exists, not},
|
dsl::{exists, not},
|
||||||
pg::Pg,
|
pg::Pg,
|
||||||
|
@ -15,7 +15,7 @@ use diesel::{
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aliases,
|
aliases,
|
||||||
newtypes::{PersonId, PersonMentionId},
|
newtypes::{PersonCommentMentionId, PersonId},
|
||||||
schema::{
|
schema::{
|
||||||
comment,
|
comment,
|
||||||
comment_aggregates,
|
comment_aggregates,
|
||||||
|
@ -28,7 +28,7 @@ use lemmy_db_schema::{
|
||||||
local_user,
|
local_user,
|
||||||
person,
|
person,
|
||||||
person_block,
|
person_block,
|
||||||
person_mention,
|
person_comment_mention,
|
||||||
post,
|
post,
|
||||||
},
|
},
|
||||||
source::local_user::LocalUser,
|
source::local_user::LocalUser,
|
||||||
|
@ -37,8 +37,8 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
|
|
||||||
fn queries<'a>() -> Queries<
|
fn queries<'a>() -> Queries<
|
||||||
impl ReadFn<'a, PersonMentionView, (PersonMentionId, Option<PersonId>)>,
|
impl ReadFn<'a, PersonCommentMentionView, (PersonCommentMentionId, Option<PersonId>)>,
|
||||||
impl ListFn<'a, PersonMentionView, PersonMentionQuery>,
|
impl ListFn<'a, PersonCommentMentionView, PersonCommentMentionQuery>,
|
||||||
> {
|
> {
|
||||||
let is_creator_banned_from_community = exists(
|
let is_creator_banned_from_community = exists(
|
||||||
community_person_ban::table.filter(
|
community_person_ban::table.filter(
|
||||||
|
@ -116,7 +116,7 @@ fn queries<'a>() -> Queries<
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let all_joins = move |query: person_mention::BoxedQuery<'a, Pg>,
|
let all_joins = move |query: person_comment_mention::BoxedQuery<'a, Pg>,
|
||||||
my_person_id: Option<PersonId>| {
|
my_person_id: Option<PersonId>| {
|
||||||
let is_local_user_banned_from_community_selection: Box<
|
let is_local_user_banned_from_community_selection: Box<
|
||||||
dyn BoxableExpression<_, Pg, SqlType = sql_types::Bool>,
|
dyn BoxableExpression<_, Pg, SqlType = sql_types::Bool>,
|
||||||
|
@ -163,7 +163,7 @@ fn queries<'a>() -> Queries<
|
||||||
.inner_join(aliases::person1)
|
.inner_join(aliases::person1)
|
||||||
.inner_join(comment_aggregates::table.on(comment::id.eq(comment_aggregates::comment_id)))
|
.inner_join(comment_aggregates::table.on(comment::id.eq(comment_aggregates::comment_id)))
|
||||||
.select((
|
.select((
|
||||||
person_mention::all_columns,
|
person_comment_mention::all_columns,
|
||||||
comment::all_columns,
|
comment::all_columns,
|
||||||
person::all_columns,
|
person::all_columns,
|
||||||
post::all_columns,
|
post::all_columns,
|
||||||
|
@ -181,28 +181,35 @@ fn queries<'a>() -> Queries<
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let read =
|
let read = move |mut conn: DbConn<'a>,
|
||||||
move |mut conn: DbConn<'a>,
|
(person_comment_mention_id, my_person_id): (
|
||||||
(person_mention_id, my_person_id): (PersonMentionId, Option<PersonId>)| async move {
|
PersonCommentMentionId,
|
||||||
|
Option<PersonId>,
|
||||||
|
)| async move {
|
||||||
all_joins(
|
all_joins(
|
||||||
person_mention::table.find(person_mention_id).into_boxed(),
|
person_comment_mention::table
|
||||||
|
.find(person_comment_mention_id)
|
||||||
|
.into_boxed(),
|
||||||
my_person_id,
|
my_person_id,
|
||||||
)
|
)
|
||||||
.first(&mut conn)
|
.first(&mut conn)
|
||||||
.await
|
.await
|
||||||
};
|
};
|
||||||
|
|
||||||
let list = move |mut conn: DbConn<'a>, options: PersonMentionQuery| async move {
|
let list = move |mut conn: DbConn<'a>, options: PersonCommentMentionQuery| async move {
|
||||||
// These filters need to be kept in sync with the filters in
|
// These filters need to be kept in sync with the filters in
|
||||||
// PersonMentionView::get_unread_mentions()
|
// PersonCommentMentionView::get_unread_mentions()
|
||||||
let mut query = all_joins(person_mention::table.into_boxed(), options.my_person_id);
|
let mut query = all_joins(
|
||||||
|
person_comment_mention::table.into_boxed(),
|
||||||
|
options.my_person_id,
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(recipient_id) = options.recipient_id {
|
if let Some(recipient_id) = options.recipient_id {
|
||||||
query = query.filter(person_mention::recipient_id.eq(recipient_id));
|
query = query.filter(person_comment_mention::recipient_id.eq(recipient_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.unread_only {
|
if options.unread_only {
|
||||||
query = query.filter(person_mention::read.eq(false));
|
query = query.filter(person_comment_mention::read.eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !options.show_bot_accounts {
|
if !options.show_bot_accounts {
|
||||||
|
@ -229,33 +236,33 @@ fn queries<'a>() -> Queries<
|
||||||
query
|
query
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
.load::<PersonMentionView>(&mut conn)
|
.load::<PersonCommentMentionView>(&mut conn)
|
||||||
.await
|
.await
|
||||||
};
|
};
|
||||||
|
|
||||||
Queries::new(read, list)
|
Queries::new(read, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PersonMentionView {
|
impl PersonCommentMentionView {
|
||||||
pub async fn read(
|
pub async fn read(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
person_mention_id: PersonMentionId,
|
person_comment_mention_id: PersonCommentMentionId,
|
||||||
my_person_id: Option<PersonId>,
|
my_person_id: Option<PersonId>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
queries()
|
queries()
|
||||||
.read(pool, (person_mention_id, my_person_id))
|
.read(pool, (person_comment_mention_id, my_person_id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the number of unread mentions
|
/// Gets the number of unread mentions
|
||||||
pub async fn get_unread_mentions(
|
pub async fn get_unread_count(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
local_user: &LocalUser,
|
local_user: &LocalUser,
|
||||||
) -> Result<i64, Error> {
|
) -> Result<i64, Error> {
|
||||||
use diesel::dsl::count;
|
use diesel::dsl::count;
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
|
||||||
let mut query = person_mention::table
|
let mut query = person_comment_mention::table
|
||||||
.inner_join(comment::table)
|
.inner_join(comment::table)
|
||||||
.left_join(
|
.left_join(
|
||||||
person_block::table.on(
|
person_block::table.on(
|
||||||
|
@ -275,18 +282,18 @@ impl PersonMentionView {
|
||||||
query
|
query
|
||||||
// Don't count replies from blocked users
|
// Don't count replies from blocked users
|
||||||
.filter(person_block::person_id.is_null())
|
.filter(person_block::person_id.is_null())
|
||||||
.filter(person_mention::recipient_id.eq(local_user.person_id))
|
.filter(person_comment_mention::recipient_id.eq(local_user.person_id))
|
||||||
.filter(person_mention::read.eq(false))
|
.filter(person_comment_mention::read.eq(false))
|
||||||
.filter(comment::deleted.eq(false))
|
.filter(comment::deleted.eq(false))
|
||||||
.filter(comment::removed.eq(false))
|
.filter(comment::removed.eq(false))
|
||||||
.select(count(person_mention::id))
|
.select(count(person_comment_mention::id))
|
||||||
.first::<i64>(conn)
|
.first::<i64>(conn)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct PersonMentionQuery {
|
pub struct PersonCommentMentionQuery {
|
||||||
pub my_person_id: Option<PersonId>,
|
pub my_person_id: Option<PersonId>,
|
||||||
pub recipient_id: Option<PersonId>,
|
pub recipient_id: Option<PersonId>,
|
||||||
pub sort: Option<CommentSortType>,
|
pub sort: Option<CommentSortType>,
|
||||||
|
@ -296,8 +303,8 @@ pub struct PersonMentionQuery {
|
||||||
pub limit: Option<i64>,
|
pub limit: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PersonMentionQuery {
|
impl PersonCommentMentionQuery {
|
||||||
pub async fn list(self, pool: &mut DbPool<'_>) -> Result<Vec<PersonMentionView>, Error> {
|
pub async fn list(self, pool: &mut DbPool<'_>) -> Result<Vec<PersonCommentMentionView>, Error> {
|
||||||
queries().list(pool, self).await
|
queries().list(pool, self).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +312,10 @@ impl PersonMentionQuery {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::{person_mention_view::PersonMentionQuery, structs::PersonMentionView};
|
use crate::{
|
||||||
|
person_comment_mention_view::PersonCommentMentionQuery,
|
||||||
|
structs::PersonCommentMentionView,
|
||||||
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
comment::{Comment, CommentInsertForm},
|
comment::{Comment, CommentInsertForm},
|
||||||
|
@ -314,7 +324,11 @@ mod tests {
|
||||||
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
|
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
|
||||||
person::{Person, PersonInsertForm, PersonUpdateForm},
|
person::{Person, PersonInsertForm, PersonUpdateForm},
|
||||||
person_block::{PersonBlock, PersonBlockForm},
|
person_block::{PersonBlock, PersonBlockForm},
|
||||||
person_mention::{PersonMention, PersonMentionInsertForm, PersonMentionUpdateForm},
|
person_comment_mention::{
|
||||||
|
PersonCommentMention,
|
||||||
|
PersonCommentMentionInsertForm,
|
||||||
|
PersonCommentMentionUpdateForm,
|
||||||
|
},
|
||||||
post::{Post, PostInsertForm},
|
post::{Post, PostInsertForm},
|
||||||
},
|
},
|
||||||
traits::{Blockable, Crud},
|
traits::{Blockable, Crud},
|
||||||
|
@ -367,15 +381,15 @@ mod tests {
|
||||||
);
|
);
|
||||||
let inserted_comment = Comment::create(pool, &comment_form, None).await?;
|
let inserted_comment = Comment::create(pool, &comment_form, None).await?;
|
||||||
|
|
||||||
let person_mention_form = PersonMentionInsertForm {
|
let person_comment_mention_form = PersonCommentMentionInsertForm {
|
||||||
recipient_id: inserted_recipient.id,
|
recipient_id: inserted_recipient.id,
|
||||||
comment_id: inserted_comment.id,
|
comment_id: inserted_comment.id,
|
||||||
read: None,
|
read: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted_mention = PersonMention::create(pool, &person_mention_form).await?;
|
let inserted_mention = PersonCommentMention::create(pool, &person_comment_mention_form).await?;
|
||||||
|
|
||||||
let expected_mention = PersonMention {
|
let expected_mention = PersonCommentMention {
|
||||||
id: inserted_mention.id,
|
id: inserted_mention.id,
|
||||||
recipient_id: inserted_mention.recipient_id,
|
recipient_id: inserted_mention.recipient_id,
|
||||||
comment_id: inserted_mention.comment_id,
|
comment_id: inserted_mention.comment_id,
|
||||||
|
@ -383,17 +397,21 @@ mod tests {
|
||||||
published: inserted_mention.published,
|
published: inserted_mention.published,
|
||||||
};
|
};
|
||||||
|
|
||||||
let read_mention = PersonMention::read(pool, inserted_mention.id).await?;
|
let read_mention = PersonCommentMention::read(pool, inserted_mention.id).await?;
|
||||||
|
|
||||||
let person_mention_update_form = PersonMentionUpdateForm { read: Some(false) };
|
let person_comment_mention_update_form = PersonCommentMentionUpdateForm { read: Some(false) };
|
||||||
let updated_mention =
|
let updated_mention = PersonCommentMention::update(
|
||||||
PersonMention::update(pool, inserted_mention.id, &person_mention_update_form).await?;
|
pool,
|
||||||
|
inserted_mention.id,
|
||||||
|
&person_comment_mention_update_form,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Test to make sure counts and blocks work correctly
|
// Test to make sure counts and blocks work correctly
|
||||||
let unread_mentions =
|
let unread_mentions =
|
||||||
PersonMentionView::get_unread_mentions(pool, &recipient_local_user).await?;
|
PersonCommentMentionView::get_unread_count(pool, &recipient_local_user).await?;
|
||||||
|
|
||||||
let query = PersonMentionQuery {
|
let query = PersonCommentMentionQuery {
|
||||||
recipient_id: Some(recipient_id),
|
recipient_id: Some(recipient_id),
|
||||||
my_person_id: Some(recipient_id),
|
my_person_id: Some(recipient_id),
|
||||||
sort: None,
|
sort: None,
|
||||||
|
@ -414,7 +432,7 @@ mod tests {
|
||||||
PersonBlock::block(pool, &block_form).await?;
|
PersonBlock::block(pool, &block_form).await?;
|
||||||
|
|
||||||
let unread_mentions_after_block =
|
let unread_mentions_after_block =
|
||||||
PersonMentionView::get_unread_mentions(pool, &recipient_local_user).await?;
|
PersonCommentMentionView::get_unread_count(pool, &recipient_local_user).await?;
|
||||||
let mentions_after_block = query.clone().list(pool).await?;
|
let mentions_after_block = query.clone().list(pool).await?;
|
||||||
assert_eq!(0, unread_mentions_after_block);
|
assert_eq!(0, unread_mentions_after_block);
|
||||||
assert_eq!(0, mentions_after_block.len());
|
assert_eq!(0, mentions_after_block.len());
|
||||||
|
@ -442,7 +460,8 @@ mod tests {
|
||||||
let recipient_local_user_view = LocalUserView::read(pool, recipient_local_user.id).await?;
|
let recipient_local_user_view = LocalUserView::read(pool, recipient_local_user.id).await?;
|
||||||
|
|
||||||
let unread_mentions_after_hide_bots =
|
let unread_mentions_after_hide_bots =
|
||||||
PersonMentionView::get_unread_mentions(pool, &recipient_local_user_view.local_user).await?;
|
PersonCommentMentionView::get_unread_count(pool, &recipient_local_user_view.local_user)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut query_without_bots = query.clone();
|
let mut query_without_bots = query.clone();
|
||||||
query_without_bots.show_bot_accounts = false;
|
query_without_bots.show_bot_accounts = false;
|
|
@ -7,7 +7,7 @@ use lemmy_db_schema::{
|
||||||
comment_reply::CommentReply,
|
comment_reply::CommentReply,
|
||||||
community::Community,
|
community::Community,
|
||||||
person::Person,
|
person::Person,
|
||||||
person_mention::PersonMention,
|
person_comment_mention::PersonCommentMention,
|
||||||
post::Post,
|
post::Post,
|
||||||
},
|
},
|
||||||
SubscribedType,
|
SubscribedType,
|
||||||
|
@ -94,8 +94,8 @@ pub enum CommunitySortType {
|
||||||
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
/// A person mention view.
|
/// A person mention view.
|
||||||
pub struct PersonMentionView {
|
pub struct PersonCommentMentionView {
|
||||||
pub person_mention: PersonMention,
|
pub person_comment_mention: PersonCommentMention,
|
||||||
pub comment: Comment,
|
pub comment: Comment,
|
||||||
pub creator: Person,
|
pub creator: Person,
|
||||||
pub post: Post,
|
pub post: Post,
|
||||||
|
@ -112,6 +112,29 @@ pub struct PersonMentionView {
|
||||||
pub my_vote: Option<i16>,
|
pub my_vote: Option<i16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #[skip_serializing_none]
|
||||||
|
// #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
|
// #[cfg_attr(feature = "full", derive(TS, Queryable))]
|
||||||
|
// #[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
|
// #[cfg_attr(feature = "full", ts(export))]
|
||||||
|
// /// A person mention view.
|
||||||
|
// pub struct PersonPostMentionView {
|
||||||
|
// pub person_post_mention: PersonPostMention,
|
||||||
|
// pub creator: Person,
|
||||||
|
// pub post: Post,
|
||||||
|
// pub community: Community,
|
||||||
|
// pub recipient: Person,
|
||||||
|
// pub counts: CommentAggregates,
|
||||||
|
// pub creator_banned_from_community: bool,
|
||||||
|
// pub banned_from_community: bool,
|
||||||
|
// pub creator_is_moderator: bool,
|
||||||
|
// pub creator_is_admin: bool,
|
||||||
|
// pub subscribed: SubscribedType,
|
||||||
|
// pub saved: bool,
|
||||||
|
// pub creator_blocked: bool,
|
||||||
|
// pub my_vote: Option<i16>,
|
||||||
|
// }
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
||||||
#[cfg_attr(feature = "full", derive(TS, Queryable))]
|
#[cfg_attr(feature = "full", derive(TS, Queryable))]
|
||||||
|
|
|
@ -17,8 +17,8 @@ use lemmy_db_views::{
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::{
|
use lemmy_db_views_actor::{
|
||||||
comment_reply_view::CommentReplyQuery,
|
comment_reply_view::CommentReplyQuery,
|
||||||
person_mention_view::PersonMentionQuery,
|
person_comment_mention_view::PersonCommentMentionQuery,
|
||||||
structs::{CommentReplyView, PersonMentionView},
|
structs::{CommentReplyView, PersonCommentMentionView},
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
cache_header::cache_1hour,
|
cache_header::cache_1hour,
|
||||||
|
@ -395,7 +395,7 @@ async fn get_feed_inbox(context: &LemmyContext, jwt: &str) -> LemmyResult<Channe
|
||||||
.list(&mut context.pool())
|
.list(&mut context.pool())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mentions = PersonMentionQuery {
|
let comment_mentions = PersonCommentMentionQuery {
|
||||||
recipient_id: (Some(person_id)),
|
recipient_id: (Some(person_id)),
|
||||||
my_person_id: (Some(person_id)),
|
my_person_id: (Some(person_id)),
|
||||||
show_bot_accounts: (show_bot_accounts),
|
show_bot_accounts: (show_bot_accounts),
|
||||||
|
@ -407,7 +407,7 @@ async fn get_feed_inbox(context: &LemmyContext, jwt: &str) -> LemmyResult<Channe
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let protocol_and_hostname = context.settings().get_protocol_and_hostname();
|
let protocol_and_hostname = context.settings().get_protocol_and_hostname();
|
||||||
let items = create_reply_and_mention_items(replies, mentions, &protocol_and_hostname)?;
|
let items = create_reply_and_mention_items(replies, comment_mentions, &protocol_and_hostname)?;
|
||||||
|
|
||||||
let mut channel = Channel {
|
let mut channel = Channel {
|
||||||
namespaces: RSS_NAMESPACE.clone(),
|
namespaces: RSS_NAMESPACE.clone(),
|
||||||
|
@ -427,7 +427,7 @@ async fn get_feed_inbox(context: &LemmyContext, jwt: &str) -> LemmyResult<Channe
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
fn create_reply_and_mention_items(
|
fn create_reply_and_mention_items(
|
||||||
replies: Vec<CommentReplyView>,
|
replies: Vec<CommentReplyView>,
|
||||||
mentions: Vec<PersonMentionView>,
|
comment_mentions: Vec<PersonCommentMentionView>,
|
||||||
protocol_and_hostname: &str,
|
protocol_and_hostname: &str,
|
||||||
) -> LemmyResult<Vec<Item>> {
|
) -> LemmyResult<Vec<Item>> {
|
||||||
let mut reply_items: Vec<Item> = replies
|
let mut reply_items: Vec<Item> = replies
|
||||||
|
@ -444,7 +444,7 @@ fn create_reply_and_mention_items(
|
||||||
})
|
})
|
||||||
.collect::<LemmyResult<Vec<Item>>>()?;
|
.collect::<LemmyResult<Vec<Item>>>()?;
|
||||||
|
|
||||||
let mut mention_items: Vec<Item> = mentions
|
let mut comment_mention_items: Vec<Item> = comment_mentions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| {
|
.map(|m| {
|
||||||
let mention_url = format!("{}/comment/{}", protocol_and_hostname, m.comment.id);
|
let mention_url = format!("{}/comment/{}", protocol_and_hostname, m.comment.id);
|
||||||
|
@ -458,7 +458,7 @@ fn create_reply_and_mention_items(
|
||||||
})
|
})
|
||||||
.collect::<LemmyResult<Vec<Item>>>()?;
|
.collect::<LemmyResult<Vec<Item>>>()?;
|
||||||
|
|
||||||
reply_items.append(&mut mention_items);
|
reply_items.append(&mut comment_mention_items);
|
||||||
Ok(reply_items)
|
Ok(reply_items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ pub enum LemmyErrorType {
|
||||||
CouldntHidePost,
|
CouldntHidePost,
|
||||||
CouldntUpdateCommunity,
|
CouldntUpdateCommunity,
|
||||||
CouldntUpdateReplies,
|
CouldntUpdateReplies,
|
||||||
CouldntUpdatePersonMentions,
|
CouldntUpdatePersonCommentMentions,
|
||||||
CouldntCreatePost,
|
CouldntCreatePost,
|
||||||
CouldntCreatePrivateMessage,
|
CouldntCreatePrivateMessage,
|
||||||
CouldntUpdatePrivate,
|
CouldntUpdatePrivate,
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
-- Rename the person_mention table to person_comment_mention
|
||||||
|
ALTER TABLE person_comment_mention RENAME TO person_mention;
|
||||||
|
|
||||||
|
-- Drop the new table
|
||||||
|
DROP TABLE person_post_mention;
|
12
migrations/2024-11-02-161125_add_post_body_mention/up.sql
Normal file
12
migrations/2024-11-02-161125_add_post_body_mention/up.sql
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
-- Rename the person_mention table to person_comment_mention
|
||||||
|
ALTER TABLE person_mention RENAME TO person_comment_mention;
|
||||||
|
|
||||||
|
-- Create the new post_mention table
|
||||||
|
CREATE TABLE person_post_mention (
|
||||||
|
id serial PRIMARY KEY,
|
||||||
|
recipient_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||||
|
post_id int REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||||
|
read boolean DEFAULT FALSE NOT NULL,
|
||||||
|
published timestamp NOT NULL DEFAULT now(),
|
||||||
|
UNIQUE (recipient_id, post_id)
|
||||||
|
);
|
|
@ -34,10 +34,10 @@ use lemmy_api::{
|
||||||
login::login,
|
login::login,
|
||||||
logout::logout,
|
logout::logout,
|
||||||
notifications::{
|
notifications::{
|
||||||
list_mentions::list_mentions,
|
list_comment_mentions::list_comment_mentions,
|
||||||
list_replies::list_replies,
|
list_replies::list_replies,
|
||||||
mark_all_read::mark_all_notifications_read,
|
mark_all_read::mark_all_notifications_read,
|
||||||
mark_mention_read::mark_person_mention_as_read,
|
mark_comment_mention_read::mark_comment_mention_as_read,
|
||||||
mark_reply_read::mark_reply_as_read,
|
mark_reply_read::mark_reply_as_read,
|
||||||
unread_count::unread_count,
|
unread_count::unread_count,
|
||||||
},
|
},
|
||||||
|
@ -329,10 +329,10 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
web::scope("/user")
|
web::scope("/user")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("", web::get().to(read_person))
|
.route("", web::get().to(read_person))
|
||||||
.route("/mention", web::get().to(list_mentions))
|
.route("/comment_mention", web::get().to(list_comment_mentions))
|
||||||
.route(
|
.route(
|
||||||
"/mention/mark_as_read",
|
"/comment_mention/mark_as_read",
|
||||||
web::post().to(mark_person_mention_as_read),
|
web::post().to(mark_comment_mention_as_read),
|
||||||
)
|
)
|
||||||
.route("/replies", web::get().to(list_replies))
|
.route("/replies", web::get().to(list_replies))
|
||||||
// Admin action. I don't like that it's in /user
|
// Admin action. I don't like that it's in /user
|
||||||
|
|
Loading…
Reference in a new issue