Add ability to mark multiple posts as read. (#5178)
* Removing a few SuccessResponses for PostHide and MarkPostAsRead. - This also removes the pointless multiple post_ids. These can be done as individual calls on the front end anyway. - Fixes #4755 * Fixing federation tests. * Upgrading lemmy-js-client deps. * Add ability to mark several posts as read. Context: - https://github.com/LemmyNet/lemmy/pull/5043 - https://github.com/LemmyNet/lemmy/issues/4755 - https://github.com/LemmyNet/lemmy/pull/5160 * Fix ntfy to notify on success builds also. * Addressing PR comments.
This commit is contained in:
parent
a9d6d4e6e0
commit
7f4e26e29e
7 changed files with 70 additions and 22 deletions
|
@ -290,14 +290,14 @@ steps:
|
||||||
when:
|
when:
|
||||||
- event: tag
|
- event: tag
|
||||||
|
|
||||||
notify_on_failure:
|
notify_on_build:
|
||||||
image: alpine:3
|
image: alpine:3
|
||||||
commands:
|
commands:
|
||||||
- apk add curl
|
- apk add curl
|
||||||
- "curl -d'Lemmy CI build failed: ${CI_PIPELINE_URL}' ntfy.sh/lemmy_drone_ci"
|
- "curl -d'Lemmy CI build ${CI_PIPELINE_STATUS}: ${CI_PIPELINE_URL}' ntfy.sh/lemmy_drone_ci"
|
||||||
when:
|
when:
|
||||||
- event: [pull_request, tag]
|
- event: [pull_request, tag]
|
||||||
status: failure
|
status: [failure, success]
|
||||||
|
|
||||||
notify_on_tag_deploy:
|
notify_on_tag_deploy:
|
||||||
image: alpine:3
|
image: alpine:3
|
||||||
|
|
24
crates/api/src/post/mark_many_read.rs
Normal file
24
crates/api/src/post/mark_many_read.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
use actix_web::web::{Data, Json};
|
||||||
|
use lemmy_api_common::{context::LemmyContext, post::MarkManyPostsAsRead, SuccessResponse};
|
||||||
|
use lemmy_db_schema::source::post::PostRead;
|
||||||
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
|
use lemmy_utils::error::{LemmyErrorType, LemmyResult, MAX_API_PARAM_ELEMENTS};
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(context))]
|
||||||
|
pub async fn mark_posts_as_read(
|
||||||
|
data: Json<MarkManyPostsAsRead>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
local_user_view: LocalUserView,
|
||||||
|
) -> LemmyResult<Json<SuccessResponse>> {
|
||||||
|
let post_ids = &data.post_ids;
|
||||||
|
if post_ids.len() > MAX_API_PARAM_ELEMENTS {
|
||||||
|
Err(LemmyErrorType::TooManyItems)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
|
||||||
|
// Mark the posts as read
|
||||||
|
PostRead::mark_many_as_read(&mut context.pool(), post_ids, person_id).await?;
|
||||||
|
|
||||||
|
Ok(Json(SuccessResponse::default()))
|
||||||
|
}
|
|
@ -4,5 +4,6 @@ pub mod hide;
|
||||||
pub mod like;
|
pub mod like;
|
||||||
pub mod list_post_likes;
|
pub mod list_post_likes;
|
||||||
pub mod lock;
|
pub mod lock;
|
||||||
|
pub mod mark_many_read;
|
||||||
pub mod mark_read;
|
pub mod mark_read;
|
||||||
pub mod save;
|
pub mod save;
|
||||||
|
|
|
@ -200,6 +200,15 @@ pub struct MarkPostAsRead {
|
||||||
pub read: bool,
|
pub read: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[skip_serializing_none]
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "full", derive(TS))]
|
||||||
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
|
/// Mark several posts as read.
|
||||||
|
pub struct MarkManyPostsAsRead {
|
||||||
|
pub post_ids: Vec<PostId>,
|
||||||
|
}
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
#[cfg_attr(feature = "full", derive(TS))]
|
||||||
|
|
|
@ -100,10 +100,7 @@ pub async fn list_posts(
|
||||||
.unwrap_or(local_user.auto_mark_fetched_posts_as_read)
|
.unwrap_or(local_user.auto_mark_fetched_posts_as_read)
|
||||||
{
|
{
|
||||||
let post_ids = posts.iter().map(|p| p.post.id).collect::<Vec<PostId>>();
|
let post_ids = posts.iter().map(|p| p.post.id).collect::<Vec<PostId>>();
|
||||||
// TODO get rid of this in the next pr
|
PostRead::mark_many_as_read(&mut context.pool(), &post_ids, local_user.person_id).await?;
|
||||||
for post_id in post_ids {
|
|
||||||
PostRead::mark_as_read(&mut context.pool(), post_id, local_user.person_id).await?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,21 +338,7 @@ impl PostRead {
|
||||||
post_id: PostId,
|
post_id: PostId,
|
||||||
person_id: PersonId,
|
person_id: PersonId,
|
||||||
) -> LemmyResult<usize> {
|
) -> LemmyResult<usize> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
Self::mark_many_as_read(pool, &[post_id], person_id).await
|
||||||
|
|
||||||
let form = (
|
|
||||||
&PostReadForm { post_id, person_id },
|
|
||||||
post_actions::read.eq(now().nullable()),
|
|
||||||
);
|
|
||||||
|
|
||||||
insert_into(post_actions::table)
|
|
||||||
.values(form)
|
|
||||||
.on_conflict((post_actions::person_id, post_actions::post_id))
|
|
||||||
.do_update()
|
|
||||||
.set(form)
|
|
||||||
.execute(conn)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntMarkPostAsRead)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn mark_as_unread(
|
pub async fn mark_as_unread(
|
||||||
|
@ -372,6 +358,35 @@ impl PostRead {
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntMarkPostAsRead)
|
.with_lemmy_type(LemmyErrorType::CouldntMarkPostAsRead)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn mark_many_as_read(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
post_ids: &[PostId],
|
||||||
|
person_id: PersonId,
|
||||||
|
) -> LemmyResult<usize> {
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
|
||||||
|
let forms = post_ids
|
||||||
|
.iter()
|
||||||
|
.map(|post_id| {
|
||||||
|
(
|
||||||
|
PostReadForm {
|
||||||
|
post_id: *post_id,
|
||||||
|
person_id,
|
||||||
|
},
|
||||||
|
post_actions::read.eq(now().nullable()),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
insert_into(post_actions::table)
|
||||||
|
.values(forms)
|
||||||
|
.on_conflict((post_actions::person_id, post_actions::post_id))
|
||||||
|
.do_update()
|
||||||
|
.set(post_actions::read.eq(now().nullable()))
|
||||||
|
.execute(conn)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntMarkPostAsRead)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PostHide {
|
impl PostHide {
|
||||||
|
|
|
@ -60,6 +60,7 @@ use lemmy_api::{
|
||||||
like::like_post,
|
like::like_post,
|
||||||
list_post_likes::list_post_likes,
|
list_post_likes::list_post_likes,
|
||||||
lock::lock_post,
|
lock::lock_post,
|
||||||
|
mark_many_read::mark_posts_as_read,
|
||||||
mark_read::mark_post_as_read,
|
mark_read::mark_post_as_read,
|
||||||
save::save_post,
|
save::save_post,
|
||||||
},
|
},
|
||||||
|
@ -239,6 +240,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.route("/delete", web::post().to(delete_post))
|
.route("/delete", web::post().to(delete_post))
|
||||||
.route("/remove", web::post().to(remove_post))
|
.route("/remove", web::post().to(remove_post))
|
||||||
.route("/mark_as_read", web::post().to(mark_post_as_read))
|
.route("/mark_as_read", web::post().to(mark_post_as_read))
|
||||||
|
.route("/mark_many_as_read", web::post().to(mark_posts_as_read))
|
||||||
.route("/hide", web::post().to(hide_post))
|
.route("/hide", web::post().to(hide_post))
|
||||||
.route("/lock", web::post().to(lock_post))
|
.route("/lock", web::post().to(lock_post))
|
||||||
.route("/feature", web::post().to(feature_post))
|
.route("/feature", web::post().to(feature_post))
|
||||||
|
|
Loading…
Reference in a new issue