mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-01-07 02:31:32 +00:00
Merge remote-tracking branch 'origin/main' into combined_profile
This commit is contained in:
commit
5cf0bb834a
14 changed files with 115 additions and 15 deletions
|
@ -28,8 +28,10 @@ pub async fn list_person_saved(
|
|||
None
|
||||
};
|
||||
let page_back = data.page_back;
|
||||
let type_ = data.type_;
|
||||
|
||||
let saved = PersonSavedCombinedQuery {
|
||||
type_,
|
||||
page_after,
|
||||
page_back,
|
||||
}
|
||||
|
|
|
@ -19,6 +19,11 @@ pub async fn verify_email(
|
|||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||
let token = data.token.clone();
|
||||
let verification = EmailVerification::read_for_token(&mut context.pool(), &token).await?;
|
||||
let local_user_id = verification.local_user_id;
|
||||
let local_user_view = LocalUserView::read(&mut context.pool(), local_user_id).await?;
|
||||
|
||||
// Check if their email has already been verified once, before this
|
||||
let email_already_verified = local_user_view.local_user.email_verified;
|
||||
|
||||
let form = LocalUserUpdateForm {
|
||||
// necessary in case this is a new signup
|
||||
|
@ -27,18 +32,16 @@ pub async fn verify_email(
|
|||
email: Some(Some(verification.email)),
|
||||
..Default::default()
|
||||
};
|
||||
let local_user_id = verification.local_user_id;
|
||||
|
||||
LocalUser::update(&mut context.pool(), local_user_id, &form).await?;
|
||||
|
||||
EmailVerification::delete_old_tokens_for_local_user(&mut context.pool(), local_user_id).await?;
|
||||
|
||||
// send out notification about registration application to admins if enabled
|
||||
if site_view.local_site.application_email_admins {
|
||||
let local_user = LocalUserView::read(&mut context.pool(), local_user_id).await?;
|
||||
|
||||
// Send out notification about registration application to admins if enabled, and the user hasn't
|
||||
// already been verified.
|
||||
if site_view.local_site.application_email_admins && !email_already_verified {
|
||||
send_new_applicant_email_to_admins(
|
||||
&local_user.person.name,
|
||||
&local_user_view.person.name,
|
||||
&mut context.pool(),
|
||||
context.settings(),
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@ use lemmy_db_schema::{
|
|||
source::{login_token::LoginToken, site::Site},
|
||||
CommentSortType,
|
||||
ListingType,
|
||||
PersonContentType,
|
||||
PostListingMode,
|
||||
PostSortType,
|
||||
};
|
||||
|
@ -249,6 +250,8 @@ pub struct GetPersonDetailsResponse {
|
|||
///
|
||||
/// Either person_id, or username are required.
|
||||
pub struct ListPersonContent {
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub type_: Option<PersonContentType>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub person_id: Option<PersonId>,
|
||||
/// Example: dessalines , or dessalines@xyz.tld
|
||||
|
@ -275,6 +278,8 @@ pub struct ListPersonContentResponse {
|
|||
#[cfg_attr(feature = "full", ts(export))]
|
||||
/// Gets your saved posts and comments
|
||||
pub struct ListPersonSaved {
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub type_: Option<PersonContentType>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub page_cursor: Option<PersonSavedCombinedPaginationCursor>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
|
|
|
@ -97,6 +97,10 @@ pub struct GetPosts {
|
|||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub community_name: Option<String>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub saved_only: Option<bool>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub read_only: Option<bool>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub liked_only: Option<bool>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub disliked_only: Option<bool>,
|
||||
|
|
|
@ -32,7 +32,7 @@ use reqwest::{
|
|||
};
|
||||
use reqwest_middleware::ClientWithMiddleware;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::info;
|
||||
use tracing::{info, warn};
|
||||
use url::Url;
|
||||
use urlencoding::encode;
|
||||
use webpage::HTML;
|
||||
|
@ -173,15 +173,23 @@ pub async fn generate_post_link_metadata(
|
|||
metadata.opengraph_data.image.clone()
|
||||
};
|
||||
|
||||
// Attempt to generate a thumbnail depending on the instance settings. Either by proxying,
|
||||
// storing image persistently in pict-rs or returning the remote url directly as thumbnail.
|
||||
let thumbnail_url = if let (false, Some(url)) = (is_image_post, custom_thumbnail) {
|
||||
proxy_image_link(url, &context).await.ok()
|
||||
} else if let (true, Some(url)) = (allow_generate_thumbnail, image_url) {
|
||||
proxy_image_link(url.clone(), &context)
|
||||
.await
|
||||
.map_err(|e| warn!("Failed to proxy thumbnail: {e}"))
|
||||
.ok()
|
||||
.or(Some(url.into()))
|
||||
} else if let (true, Some(url)) = (allow_generate_thumbnail, image_url.clone()) {
|
||||
generate_pictrs_thumbnail(&url, &context)
|
||||
.await
|
||||
.map_err(|e| warn!("Failed to generate thumbnail: {e}"))
|
||||
.ok()
|
||||
.map(Into::into)
|
||||
.or(image_url)
|
||||
} else {
|
||||
metadata.opengraph_data.image.clone()
|
||||
image_url.clone()
|
||||
};
|
||||
|
||||
let form = PostUpdateForm {
|
||||
|
|
|
@ -9,7 +9,7 @@ use actix_web::web::{Json, Query};
|
|||
use lemmy_api_common::{
|
||||
comment::{GetComments, GetCommentsResponse},
|
||||
context::LemmyContext,
|
||||
utils::check_private_instance,
|
||||
utils::{check_conflicting_like_filters, check_private_instance},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{comment::Comment, community::Community},
|
||||
|
@ -19,7 +19,7 @@ use lemmy_db_views::{
|
|||
comment_view::CommentQuery,
|
||||
structs::{LocalUserView, SiteView},
|
||||
};
|
||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
pub async fn list_comments(
|
||||
|
@ -49,9 +49,7 @@ pub async fn list_comments(
|
|||
|
||||
let liked_only = data.liked_only;
|
||||
let disliked_only = data.disliked_only;
|
||||
if liked_only.unwrap_or_default() && disliked_only.unwrap_or_default() {
|
||||
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
|
||||
}
|
||||
check_conflicting_like_filters(liked_only, disliked_only)?;
|
||||
|
||||
let page = data.page;
|
||||
let limit = data.limit;
|
||||
|
|
|
@ -37,9 +37,11 @@ pub async fn list_person_content(
|
|||
None
|
||||
};
|
||||
let page_back = data.page_back;
|
||||
let type_ = data.type_;
|
||||
|
||||
let content = PersonContentCombinedQuery {
|
||||
creator_id: person_details_id,
|
||||
type_,
|
||||
page_after,
|
||||
page_back,
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ pub async fn list_posts(
|
|||
} else {
|
||||
data.community_id
|
||||
};
|
||||
let read_only = data.read_only;
|
||||
let show_hidden = data.show_hidden;
|
||||
let show_read = data.show_read;
|
||||
let show_nsfw = data.show_nsfw;
|
||||
|
@ -76,6 +77,7 @@ pub async fn list_posts(
|
|||
listing_type,
|
||||
sort,
|
||||
community_id,
|
||||
read_only,
|
||||
liked_only,
|
||||
disliked_only,
|
||||
page,
|
||||
|
|
|
@ -219,6 +219,16 @@ pub enum ModlogActionType {
|
|||
AdminAllowInstance,
|
||||
}
|
||||
|
||||
#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "full", derive(TS))]
|
||||
#[cfg_attr(feature = "full", ts(export))]
|
||||
/// A list of possible types for the various modlog actions.
|
||||
pub enum PersonContentType {
|
||||
All,
|
||||
Comments,
|
||||
Posts,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq, Hash,
|
||||
)]
|
||||
|
|
|
@ -45,6 +45,7 @@ use lemmy_db_schema::{
|
|||
community::CommunityFollower,
|
||||
},
|
||||
utils::{actions, actions_alias, functions::coalesce, get_conn, DbPool},
|
||||
PersonContentType,
|
||||
};
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
|
||||
|
@ -84,6 +85,8 @@ pub struct PaginationCursorData(PersonContentCombined);
|
|||
pub struct PersonContentCombinedQuery {
|
||||
pub creator_id: PersonId,
|
||||
#[new(default)]
|
||||
pub type_: Option<PersonContentType>,
|
||||
#[new(default)]
|
||||
pub page_after: Option<PaginationCursorData>,
|
||||
#[new(default)]
|
||||
pub page_back: Option<bool>,
|
||||
|
@ -210,6 +213,16 @@ impl PersonContentCombinedQuery {
|
|||
|
||||
let mut query = PaginatedQueryBuilder::new(query);
|
||||
|
||||
if let Some(type_) = self.type_ {
|
||||
query = match type_ {
|
||||
PersonContentType::All => query,
|
||||
PersonContentType::Comments => {
|
||||
query.filter(person_content_combined::comment_id.is_not_null())
|
||||
}
|
||||
PersonContentType::Posts => query.filter(person_content_combined::post_id.is_not_null()),
|
||||
}
|
||||
}
|
||||
|
||||
let page_after = self.page_after.map(|c| c.0);
|
||||
|
||||
if self.page_back.unwrap_or_default() {
|
||||
|
|
|
@ -42,6 +42,7 @@ use lemmy_db_schema::{
|
|||
community::CommunityFollower,
|
||||
},
|
||||
utils::{actions, actions_alias, functions::coalesce, get_conn, DbPool},
|
||||
PersonContentType,
|
||||
};
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
|
||||
|
@ -79,6 +80,7 @@ pub struct PaginationCursorData(PersonSavedCombined);
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct PersonSavedCombinedQuery {
|
||||
pub type_: Option<PersonContentType>,
|
||||
pub page_after: Option<PaginationCursorData>,
|
||||
pub page_back: Option<bool>,
|
||||
}
|
||||
|
@ -212,6 +214,16 @@ impl PersonSavedCombinedQuery {
|
|||
|
||||
let mut query = PaginatedQueryBuilder::new(query);
|
||||
|
||||
if let Some(type_) = self.type_ {
|
||||
query = match type_ {
|
||||
PersonContentType::All => query,
|
||||
PersonContentType::Comments => {
|
||||
query.filter(person_saved_combined::comment_id.is_not_null())
|
||||
}
|
||||
PersonContentType::Posts => query.filter(person_saved_combined::post_id.is_not_null()),
|
||||
}
|
||||
}
|
||||
|
||||
let page_after = self.page_after.map(|c| c.0);
|
||||
|
||||
if self.page_back.unwrap_or_default() {
|
||||
|
|
|
@ -306,6 +306,12 @@ fn queries<'a>() -> Queries<
|
|||
query = query.filter(post_aggregates::comments.eq(0));
|
||||
};
|
||||
|
||||
if o.read_only.unwrap_or_default() {
|
||||
query = query
|
||||
.filter(post_actions::read.is_not_null())
|
||||
.then_order_by(post_actions::read.desc())
|
||||
}
|
||||
|
||||
if !o.show_read.unwrap_or(o.local_user.show_read_posts()) {
|
||||
// Do not hide read posts when it is a user profile view
|
||||
// Or, only hide read posts on non-profile views
|
||||
|
@ -496,6 +502,7 @@ pub struct PostQuery<'a> {
|
|||
pub local_user: Option<&'a LocalUser>,
|
||||
pub search_term: Option<String>,
|
||||
pub url_only: Option<bool>,
|
||||
pub read_only: Option<bool>,
|
||||
pub liked_only: Option<bool>,
|
||||
pub disliked_only: Option<bool>,
|
||||
pub title_only: Option<bool>,
|
||||
|
@ -1192,6 +1199,34 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test_context(Data)]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn post_listing_read_only(data: &mut Data) -> LemmyResult<()> {
|
||||
let pool = &data.pool();
|
||||
let pool = &mut pool.into();
|
||||
|
||||
// Only mark the bot post as read
|
||||
// The read_only should only show the bot post
|
||||
let post_read_form =
|
||||
PostReadForm::new(data.inserted_bot_post.id, data.local_user_view.person.id);
|
||||
PostRead::mark_as_read(pool, &post_read_form).await?;
|
||||
|
||||
// Only read the post marked as read
|
||||
let read_read_post_listing = PostQuery {
|
||||
community_id: Some(data.inserted_community.id),
|
||||
read_only: Some(true),
|
||||
..data.default_post_query()
|
||||
}
|
||||
.list(&data.site, pool)
|
||||
.await?;
|
||||
|
||||
// This should only include the bot post, not the one you created
|
||||
assert_eq!(vec![POST_BY_BOT], names(&read_read_post_listing));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_context(Data)]
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
DROP INDEX idx_post_actions_on_read_read_not_null;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
CREATE INDEX idx_post_actions_on_read_read_not_null ON post_actions (person_id, read, post_id)
|
||||
WHERE
|
||||
read IS NOT NULL;
|
||||
|
Loading…
Reference in a new issue