From 6b6457cc54fea989513a31958244ad89abf3fb08 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 19 Sep 2024 04:03:58 -0400 Subject: [PATCH] Adding a default_comment_sort_type column for local_site and local_user. (#4469) * Adding a default_comment_sort_type column for local_site and local_user. - Renamed SortType to PostSortType in the DB and code. - Renamed references to default_sort_type to default_post_sort_type. - Fixes #4128 * Renaming migration to current date. * Simplifying PostSortType. --- crates/api/src/local_user/save_settings.rs | 6 +- crates/api_common/src/community.rs | 4 +- crates/api_common/src/person.rs | 14 +++-- crates/api_common/src/post.rs | 4 +- crates/api_common/src/site.rs | 21 ++++--- crates/api_crud/src/site/create.rs | 50 +++++++++++----- crates/api_crud/src/site/update.rs | 47 ++++++++++----- crates/apub/src/api/list_comments.rs | 8 ++- crates/apub/src/api/list_posts.rs | 4 +- crates/apub/src/api/mod.rs | 29 ++++++--- crates/apub/src/api/user_settings_backup.rs | 3 +- .../apub/src/collections/community_outbox.rs | 4 +- crates/db_perf/src/main.rs | 4 +- crates/db_schema/src/lib.rs | 16 +++-- crates/db_schema/src/schema.rs | 24 +++++--- crates/db_schema/src/source/local_site.rs | 15 +++-- crates/db_schema/src/source/local_user.rs | 13 ++-- crates/db_schema/src/utils.rs | 26 +++----- crates/db_views/src/post_view.rs | 59 ++++++++++--------- .../src/registration_application_view.rs | 3 +- crates/db_views_actor/src/community_view.rs | 6 +- crates/db_views_actor/src/person_view.rs | 17 +++--- crates/routes/src/feeds.rs | 16 ++--- .../down.sql | 19 ++++++ .../up.sql | 24 ++++++++ 25 files changed, 286 insertions(+), 150 deletions(-) create mode 100644 migrations/2024-09-16-000000_default_comment_sort_type/down.sql create mode 100644 migrations/2024-09-16-000000_default_comment_sort_type/up.sql diff --git a/crates/api/src/local_user/save_settings.rs b/crates/api/src/local_user/save_settings.rs index d5b6a7ec1..c62ab0e01 100644 --- a/crates/api/src/local_user/save_settings.rs +++ b/crates/api/src/local_user/save_settings.rs @@ -102,7 +102,8 @@ pub async fn save_user_settings( let local_user_id = local_user_view.local_user.id; let person_id = local_user_view.person.id; let default_listing_type = data.default_listing_type; - let default_sort_type = data.default_sort_type; + let default_post_sort_type = data.default_post_sort_type; + let default_comment_sort_type = data.default_comment_sort_type; let person_form = PersonUpdateForm { display_name, @@ -133,7 +134,8 @@ pub async fn save_user_settings( blur_nsfw: data.blur_nsfw, auto_expand: data.auto_expand, show_bot_accounts: data.show_bot_accounts, - default_sort_type, + default_post_sort_type, + default_comment_sort_type, default_listing_type, theme: data.theme.clone(), interface_language: data.interface_language.clone(), diff --git a/crates/api_common/src/community.rs b/crates/api_common/src/community.rs index 3dad04af5..e1c1c5d76 100644 --- a/crates/api_common/src/community.rs +++ b/crates/api_common/src/community.rs @@ -3,7 +3,7 @@ use lemmy_db_schema::{ source::site::Site, CommunityVisibility, ListingType, - SortType, + PostSortType, }; use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView, PersonView}; use serde::{Deserialize, Serialize}; @@ -74,7 +74,7 @@ pub struct CommunityResponse { /// Fetches a list of communities. pub struct ListCommunities { pub type_: Option, - pub sort: Option, + pub sort: Option, pub show_nsfw: Option, pub page: Option, pub limit: Option, diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index 64b09e132..40e8df4ce 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -5,7 +5,7 @@ use lemmy_db_schema::{ CommentSortType, ListingType, PostListingMode, - SortType, + PostSortType, }; use lemmy_db_views::structs::{CommentView, LocalImageView, PostView}; use lemmy_db_views_actor::structs::{ @@ -88,8 +88,14 @@ pub struct SaveUserSettings { pub auto_expand: Option, /// Your user's theme. pub theme: Option, - pub default_sort_type: Option, + /// The default post listing type, usually "local" pub default_listing_type: Option, + /// A post-view mode that changes how multiple post listings look. + pub post_listing_mode: Option, + /// The default post sort, usually "active" + pub default_post_sort_type: Option, + /// The default comment sort, usually "hot" + pub default_comment_sort_type: Option, /// The language of the lemmy interface pub interface_language: Option, /// A URL for your avatar. @@ -120,8 +126,6 @@ pub struct SaveUserSettings { pub open_links_in_new_tab: Option, /// Enable infinite scroll pub infinite_scroll_enabled: Option, - /// A post-view mode that changes how multiple post listings look. - pub post_listing_mode: Option, /// Whether to allow keyboard navigation (for browsing and interacting with posts and comments). pub enable_keyboard_navigation: Option, /// Whether user avatars or inline images in the UI that are gifs should be allowed to play or @@ -172,7 +176,7 @@ pub struct GetPersonDetails { pub person_id: Option, /// Example: dessalines , or dessalines@xyz.tld pub username: Option, - pub sort: Option, + pub sort: Option, pub page: Option, pub limit: Option, pub community_id: Option, diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs index 74369173b..44436fa84 100644 --- a/crates/api_common/src/post.rs +++ b/crates/api_common/src/post.rs @@ -2,7 +2,7 @@ use lemmy_db_schema::{ newtypes::{CommentId, CommunityId, DbUrl, LanguageId, PostId, PostReportId}, ListingType, PostFeatureType, - SortType, + PostSortType, }; use lemmy_db_views::structs::{PaginationCursor, PostReportView, PostView, VoteView}; use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView}; @@ -69,7 +69,7 @@ pub struct GetPostResponse { /// Get a list of posts. pub struct GetPosts { pub type_: Option, - pub sort: Option, + pub sort: Option, /// DEPRECATED, use page_cursor pub page: Option, pub limit: Option, diff --git a/crates/api_common/src/site.rs b/crates/api_common/src/site.rs index 6fa6e3700..f25dcf94b 100644 --- a/crates/api_common/src/site.rs +++ b/crates/api_common/src/site.rs @@ -20,12 +20,13 @@ use lemmy_db_schema::{ person::Person, tagline::Tagline, }, + CommentSortType, ListingType, ModlogActionType, PostListingMode, + PostSortType, RegistrationMode, SearchType, - SortType, }; use lemmy_db_views::structs::{ CommentView, @@ -74,7 +75,7 @@ pub struct Search { pub community_name: Option, pub creator_id: Option, pub type_: Option, - pub sort: Option, + pub sort: Option, pub listing_type: Option, pub page: Option, pub limit: Option, @@ -174,7 +175,9 @@ pub struct CreateSite { pub private_instance: Option, pub default_theme: Option, pub default_post_listing_type: Option, - pub default_sort_type: Option, + pub default_post_listing_mode: Option, + pub default_post_sort_type: Option, + pub default_comment_sort_type: Option, pub legal_information: Option, pub application_email_admins: Option, pub hide_modlog_mod_names: Option, @@ -203,7 +206,6 @@ pub struct CreateSite { pub registration_mode: Option, pub oauth_registration: Option, pub content_warning: Option, - pub default_post_listing_mode: Option, } #[skip_serializing_none] @@ -234,9 +236,14 @@ pub struct EditSite { pub private_instance: Option, /// The default theme. Usually "browser" pub default_theme: Option, + /// The default post listing type, usually "local" pub default_post_listing_type: Option, - /// The default sort, usually "active" - pub default_sort_type: Option, + /// Default value for listing mode, usually "list" + pub default_post_listing_mode: Option, + /// The default post sort, usually "active" + pub default_post_sort_type: Option, + /// The default comment sort, usually "hot" + pub default_comment_sort_type: Option, /// An optional page of legal information pub legal_information: Option, /// Whether to email admins when receiving a new application. @@ -291,8 +298,6 @@ pub struct EditSite { /// If present, nsfw content is visible by default. Should be displayed by frontends/clients /// when the site is first opened by a user. pub content_warning: Option, - /// Default value for [LocalUser.post_listing_mode] - pub default_post_listing_mode: Option, } #[derive(Debug, Serialize, Deserialize, Clone)] diff --git a/crates/api_crud/src/site/create.rs b/crates/api_crud/src/site/create.rs index 3d96d20cf..70c0e48e9 100644 --- a/crates/api_crud/src/site/create.rs +++ b/crates/api_crud/src/site/create.rs @@ -98,7 +98,8 @@ pub async fn create_site( private_instance: data.private_instance, default_theme: data.default_theme.clone(), default_post_listing_type: data.default_post_listing_type, - default_sort_type: data.default_sort_type, + default_post_sort_type: data.default_post_sort_type, + default_comment_sort_type: data.default_comment_sort_type, legal_information: diesel_string_update(data.legal_information.as_deref()), application_email_admins: data.application_email_admins, hide_modlog_mod_names: data.hide_modlog_mod_names, @@ -200,7 +201,13 @@ mod tests { use crate::site::create::validate_create_payload; use lemmy_api_common::site::CreateSite; - use lemmy_db_schema::{source::local_site::LocalSite, ListingType, RegistrationMode, SortType}; + use lemmy_db_schema::{ + source::local_site::LocalSite, + CommentSortType, + ListingType, + PostSortType, + RegistrationMode, + }; use lemmy_utils::error::LemmyErrorType; #[test] @@ -222,7 +229,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -246,7 +254,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -270,7 +279,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, Some(String::from("(zeta|alpha)")), None::, None::, @@ -294,7 +304,8 @@ mod tests { None::, None::, Some(ListingType::Subscribed), - None::, + None::, + None::, None::, None::, None::, @@ -318,7 +329,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, Some(true), Some(true), @@ -342,7 +354,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, Some(true), @@ -366,7 +379,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -424,7 +438,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -447,7 +462,8 @@ mod tests { Some(String::new()), Some(String::new()), Some(ListingType::All), - Some(SortType::Active), + Some(PostSortType::Active), + Some(CommentSortType::Hot), Some(String::new()), Some(false), Some(true), @@ -470,7 +486,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, Some(String::new()), None::, None::, @@ -493,7 +510,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -543,7 +561,8 @@ mod tests { site_description: Option, site_sidebar: Option, site_listing_type: Option, - site_sort_type: Option, + site_post_sort_type: Option, + site_comment_sort_type: Option, site_slur_filter_regex: Option, site_is_private: Option, site_is_federated: Option, @@ -564,7 +583,8 @@ mod tests { private_instance: site_is_private, default_theme: None, default_post_listing_type: site_listing_type, - default_sort_type: site_sort_type, + default_post_sort_type: site_post_sort_type, + default_comment_sort_type: site_comment_sort_type, legal_information: None, application_email_admins: None, hide_modlog_mod_names: None, diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index 7e9dc8f03..e0896bed5 100644 --- a/crates/api_crud/src/site/update.rs +++ b/crates/api_crud/src/site/update.rs @@ -107,7 +107,8 @@ pub async fn update_site( private_instance: data.private_instance, default_theme: data.default_theme.clone(), default_post_listing_type: data.default_post_listing_type, - default_sort_type: data.default_sort_type, + default_post_sort_type: data.default_post_sort_type, + default_comment_sort_type: data.default_comment_sort_type, legal_information: diesel_string_update(data.legal_information.as_deref()), application_email_admins: data.application_email_admins, hide_modlog_mod_names: data.hide_modlog_mod_names, @@ -252,7 +253,13 @@ mod tests { use crate::site::update::validate_update_payload; use lemmy_api_common::site::EditSite; - use lemmy_db_schema::{source::local_site::LocalSite, ListingType, RegistrationMode, SortType}; + use lemmy_db_schema::{ + source::local_site::LocalSite, + CommentSortType, + ListingType, + PostSortType, + RegistrationMode, + }; use lemmy_utils::error::LemmyErrorType; #[test] @@ -273,7 +280,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -297,7 +305,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, Some(String::from("(zeta|alpha)")), None::, None::, @@ -321,7 +330,8 @@ mod tests { None::, None::, Some(ListingType::Subscribed), - None::, + None::, + None::, None::, None::, None::, @@ -345,7 +355,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, Some(true), Some(true), @@ -369,7 +380,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, Some(true), @@ -393,7 +405,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -448,7 +461,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -471,7 +485,8 @@ mod tests { Some(String::new()), Some(String::new()), Some(ListingType::All), - Some(SortType::Active), + Some(PostSortType::Active), + Some(CommentSortType::Hot), Some(String::new()), Some(false), Some(true), @@ -494,7 +509,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, Some(String::new()), None::, None::, @@ -517,7 +533,8 @@ mod tests { None::, None::, None::, - None::, + None::, + None::, None::, None::, None::, @@ -566,7 +583,8 @@ mod tests { site_description: Option, site_sidebar: Option, site_listing_type: Option, - site_sort_type: Option, + site_post_sort_type: Option, + site_comment_sort_type: Option, site_slur_filter_regex: Option, site_is_private: Option, site_is_federated: Option, @@ -588,7 +606,8 @@ mod tests { private_instance: site_is_private, default_theme: None, default_post_listing_type: site_listing_type, - default_sort_type: site_sort_type, + default_post_sort_type: site_post_sort_type, + default_comment_sort_type: site_comment_sort_type, legal_information: None, application_email_admins: None, hide_modlog_mod_names: None, diff --git a/crates/apub/src/api/list_comments.rs b/crates/apub/src/api/list_comments.rs index 12d18110e..3223921bc 100644 --- a/crates/apub/src/api/list_comments.rs +++ b/crates/apub/src/api/list_comments.rs @@ -1,3 +1,4 @@ +use super::comment_sort_type_with_default; use crate::{ api::listing_type_with_default, fetcher::resolve_actor_identifier, @@ -35,7 +36,12 @@ pub async fn list_comments( } else { data.community_id }; - let sort = data.sort; + let local_user_ref = local_user_view.as_ref().map(|u| &u.local_user); + let sort = Some(comment_sort_type_with_default( + data.sort, + local_user_ref, + &local_site, + )); let max_depth = data.max_depth; let saved_only = data.saved_only; diff --git a/crates/apub/src/api/list_posts.rs b/crates/apub/src/api/list_posts.rs index cb2a37a3c..9b504dbe3 100644 --- a/crates/apub/src/api/list_posts.rs +++ b/crates/apub/src/api/list_posts.rs @@ -1,5 +1,5 @@ use crate::{ - api::{listing_type_with_default, sort_type_with_default}, + api::{listing_type_with_default, post_sort_type_with_default}, fetcher::resolve_actor_identifier, objects::community::ApubCommunity, }; @@ -57,7 +57,7 @@ pub async fn list_posts( community_id, )); - let sort = Some(sort_type_with_default( + let sort = Some(post_sort_type_with_default( data.sort, local_user, &local_site.local_site, diff --git a/crates/apub/src/api/mod.rs b/crates/apub/src/api/mod.rs index dab2ace06..580be3228 100644 --- a/crates/apub/src/api/mod.rs +++ b/crates/apub/src/api/mod.rs @@ -1,8 +1,9 @@ use lemmy_db_schema::{ newtypes::CommunityId, source::{local_site::LocalSite, local_user::LocalUser}, + CommentSortType, ListingType, - SortType, + PostSortType, }; pub mod list_comments; @@ -33,16 +34,30 @@ fn listing_type_with_default( } } -/// Returns a default instance-level sort type, if none is given by the user. +/// Returns a default instance-level post sort type, if none is given by the user. /// Order is type, local user default, then site default. -fn sort_type_with_default( - type_: Option, +fn post_sort_type_with_default( + type_: Option, local_user: Option<&LocalUser>, local_site: &LocalSite, -) -> SortType { +) -> PostSortType { type_.unwrap_or( local_user - .map(|u| u.default_sort_type) - .unwrap_or(local_site.default_sort_type), + .map(|u| u.default_post_sort_type) + .unwrap_or(local_site.default_post_sort_type), + ) +} + +/// Returns a default instance-level comment sort type, if none is given by the user. +/// Order is type, local user default, then site default. +fn comment_sort_type_with_default( + type_: Option, + local_user: Option<&LocalUser>, + local_site: &LocalSite, +) -> CommentSortType { + type_.unwrap_or( + local_user + .map(|u| u.default_comment_sort_type) + .unwrap_or(local_site.default_comment_sort_type), ) } diff --git a/crates/apub/src/api/user_settings_backup.rs b/crates/apub/src/api/user_settings_backup.rs index fdf8dc2ad..c94fee9b8 100644 --- a/crates/apub/src/api/user_settings_backup.rs +++ b/crates/apub/src/api/user_settings_backup.rs @@ -114,7 +114,8 @@ pub async fn import_settings( let local_user_form = LocalUserUpdateForm { show_nsfw: data.settings.as_ref().map(|s| s.show_nsfw), theme: data.settings.clone().map(|s| s.theme.clone()), - default_sort_type: data.settings.as_ref().map(|s| s.default_sort_type), + default_post_sort_type: data.settings.as_ref().map(|s| s.default_post_sort_type), + default_comment_sort_type: data.settings.as_ref().map(|s| s.default_comment_sort_type), default_listing_type: data.settings.as_ref().map(|s| s.default_listing_type), interface_language: data.settings.clone().map(|s| s.interface_language), show_avatars: data.settings.as_ref().map(|s| s.show_avatars), diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs index 38a66c62b..01199bc2b 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -18,7 +18,7 @@ use activitypub_federation::{ }; use futures::future::join_all; use lemmy_api_common::{context::LemmyContext, utils::generate_outbox_url}; -use lemmy_db_schema::{source::site::Site, utils::FETCH_LIMIT_MAX, SortType}; +use lemmy_db_schema::{source::site::Site, utils::FETCH_LIMIT_MAX, PostSortType}; use lemmy_db_views::post_view::PostQuery; use lemmy_utils::error::{LemmyError, LemmyResult}; use url::Url; @@ -39,7 +39,7 @@ impl Collection for ApubCommunityOutbox { let post_views = PostQuery { community_id: Some(owner.id), - sort: Some(SortType::New), + sort: Some(PostSortType::New), limit: Some(FETCH_LIMIT_MAX), ..Default::default() } diff --git a/crates/db_perf/src/main.rs b/crates/db_perf/src/main.rs index 8e03a0a1d..4abe14794 100644 --- a/crates/db_perf/src/main.rs +++ b/crates/db_perf/src/main.rs @@ -20,7 +20,7 @@ use lemmy_db_schema::{ }, traits::Crud, utils::{build_db_pool, get_conn, now}, - SortType, + PostSortType, }; use lemmy_db_views::{post_view::PostQuery, structs::PaginationCursor}; use lemmy_utils::error::{LemmyErrorExt2, LemmyResult}; @@ -151,7 +151,7 @@ async fn try_main() -> LemmyResult<()> { // TODO: include local_user let post_views = PostQuery { community_id: community_ids.as_slice().first().cloned(), - sort: Some(SortType::New), + sort: Some(PostSortType::New), limit: Some(20), page_after, ..Default::default() diff --git a/crates/db_schema/src/lib.rs b/crates/db_schema/src/lib.rs index c29ec6443..1e3d96a1d 100644 --- a/crates/db_schema/src/lib.rs +++ b/crates/db_schema/src/lib.rs @@ -58,13 +58,13 @@ use ts_rs::TS; #[cfg_attr(feature = "full", derive(DbEnum, TS))] #[cfg_attr( feature = "full", - ExistingTypePath = "crate::schema::sql_types::SortTypeEnum" + ExistingTypePath = "crate::schema::sql_types::PostSortTypeEnum" )] #[cfg_attr(feature = "full", DbValueStyle = "verbatim")] #[cfg_attr(feature = "full", ts(export))] // TODO add the controversial and scaled rankings to the doc below /// The post sort types. See here for descriptions: https://join-lemmy.org/docs/en/users/03-votes-and-ranking.html -pub enum SortType { +pub enum PostSortType { #[default] Active, Hot, @@ -87,11 +87,19 @@ pub enum SortType { Scaled, } -#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "full", derive(TS))] +#[derive( + EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default, Hash, +)] +#[cfg_attr(feature = "full", derive(DbEnum, TS))] +#[cfg_attr( + feature = "full", + ExistingTypePath = "crate::schema::sql_types::CommentSortTypeEnum" +)] +#[cfg_attr(feature = "full", DbValueStyle = "verbatim")] #[cfg_attr(feature = "full", ts(export))] /// The comment sort types. See here for descriptions: https://join-lemmy.org/docs/en/users/03-votes-and-ranking.html pub enum CommentSortType { + #[default] Hot, Top, New, diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index de3e4fa48..b5f68822c 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -5,6 +5,10 @@ pub mod sql_types { #[diesel(postgres_type(name = "actor_type_enum"))] pub struct ActorTypeEnum; + #[derive(diesel::sql_types::SqlType)] + #[diesel(postgres_type(name = "comment_sort_type_enum"))] + pub struct CommentSortTypeEnum; + #[derive(diesel::sql_types::SqlType)] #[diesel(postgres_type(name = "community_visibility"))] pub struct CommunityVisibility; @@ -22,12 +26,12 @@ pub mod sql_types { pub struct PostListingModeEnum; #[derive(diesel::sql_types::SqlType)] - #[diesel(postgres_type(name = "registration_mode_enum"))] - pub struct RegistrationModeEnum; + #[diesel(postgres_type(name = "post_sort_type_enum"))] + pub struct PostSortTypeEnum; #[derive(diesel::sql_types::SqlType)] - #[diesel(postgres_type(name = "sort_type_enum"))] - pub struct SortTypeEnum; + #[diesel(postgres_type(name = "registration_mode_enum"))] + pub struct RegistrationModeEnum; } diesel::table! { @@ -363,7 +367,8 @@ diesel::table! { use super::sql_types::ListingTypeEnum; use super::sql_types::RegistrationModeEnum; use super::sql_types::PostListingModeEnum; - use super::sql_types::SortTypeEnum; + use super::sql_types::PostSortTypeEnum; + use super::sql_types::CommentSortTypeEnum; local_site (id) { id -> Int4, @@ -391,7 +396,8 @@ diesel::table! { reports_email_admins -> Bool, federation_signed_fetch -> Bool, default_post_listing_mode -> PostListingModeEnum, - default_sort_type -> SortTypeEnum, + default_post_sort_type -> PostSortTypeEnum, + default_comment_sort_type -> CommentSortTypeEnum, oauth_registration -> Bool, } } @@ -429,9 +435,10 @@ diesel::table! { diesel::table! { use diesel::sql_types::*; - use super::sql_types::SortTypeEnum; + use super::sql_types::PostSortTypeEnum; use super::sql_types::ListingTypeEnum; use super::sql_types::PostListingModeEnum; + use super::sql_types::CommentSortTypeEnum; local_user (id) { id -> Int4, @@ -440,7 +447,7 @@ diesel::table! { email -> Nullable, show_nsfw -> Bool, theme -> Text, - default_sort_type -> SortTypeEnum, + default_post_sort_type -> PostSortTypeEnum, default_listing_type -> ListingTypeEnum, #[max_length = 20] interface_language -> Varchar, @@ -461,6 +468,7 @@ diesel::table! { enable_keyboard_navigation -> Bool, enable_animated_images -> Bool, collapse_bot_comments -> Bool, + default_comment_sort_type -> CommentSortTypeEnum, } } diff --git a/crates/db_schema/src/source/local_site.rs b/crates/db_schema/src/source/local_site.rs index 8dc81a9a5..001c8cc52 100644 --- a/crates/db_schema/src/source/local_site.rs +++ b/crates/db_schema/src/source/local_site.rs @@ -2,10 +2,11 @@ use crate::schema::local_site; use crate::{ newtypes::{LocalSiteId, SiteId}, + CommentSortType, ListingType, PostListingMode, + PostSortType, RegistrationMode, - SortType, }; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -66,8 +67,10 @@ pub struct LocalSite { pub federation_signed_fetch: bool, /// Default value for [LocalSite.post_listing_mode] pub default_post_listing_mode: PostListingMode, - /// Default value for [LocalUser.post_listing_mode] - pub default_sort_type: SortType, + /// Default value for [LocalUser.post_sort_type] + pub default_post_sort_type: PostSortType, + /// Default value for [LocalUser.comment_sort_type] + pub default_comment_sort_type: CommentSortType, /// Whether or not external auth methods can auto-register users. pub oauth_registration: bool, } @@ -100,7 +103,8 @@ pub struct LocalSiteInsertForm { pub reports_email_admins: Option, pub federation_signed_fetch: Option, pub default_post_listing_mode: Option, - pub default_sort_type: Option, + pub default_post_sort_type: Option, + pub default_comment_sort_type: Option, } #[derive(Clone, Default)] @@ -129,5 +133,6 @@ pub struct LocalSiteUpdateForm { pub updated: Option>>, pub federation_signed_fetch: Option, pub default_post_listing_mode: Option, - pub default_sort_type: Option, + pub default_post_sort_type: Option, + pub default_comment_sort_type: Option, } diff --git a/crates/db_schema/src/source/local_user.rs b/crates/db_schema/src/source/local_user.rs index e184d3605..876bfa487 100644 --- a/crates/db_schema/src/source/local_user.rs +++ b/crates/db_schema/src/source/local_user.rs @@ -3,9 +3,10 @@ use crate::schema::local_user; use crate::{ newtypes::{LocalUserId, PersonId}, sensitive::SensitiveString, + CommentSortType, ListingType, PostListingMode, - SortType, + PostSortType, }; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; @@ -29,7 +30,7 @@ pub struct LocalUser { /// Whether to show NSFW content. pub show_nsfw: bool, pub theme: String, - pub default_sort_type: SortType, + pub default_post_sort_type: PostSortType, pub default_listing_type: ListingType, pub interface_language: String, /// Whether to show avatars. @@ -63,6 +64,7 @@ pub struct LocalUser { pub enable_animated_images: bool, /// Whether to auto-collapse bot comments. pub collapse_bot_comments: bool, + pub default_comment_sort_type: CommentSortType, } #[derive(Clone, derive_new::new)] @@ -78,7 +80,7 @@ pub struct LocalUserInsertForm { #[new(default)] pub theme: Option, #[new(default)] - pub default_sort_type: Option, + pub default_post_sort_type: Option, #[new(default)] pub default_listing_type: Option, #[new(default)] @@ -117,6 +119,8 @@ pub struct LocalUserInsertForm { pub enable_animated_images: Option, #[new(default)] pub collapse_bot_comments: Option, + #[new(default)] + pub default_comment_sort_type: Option, } #[derive(Clone, Default)] @@ -127,7 +131,7 @@ pub struct LocalUserUpdateForm { pub email: Option>, pub show_nsfw: Option, pub theme: Option, - pub default_sort_type: Option, + pub default_post_sort_type: Option, pub default_listing_type: Option, pub interface_language: Option, pub show_avatars: Option, @@ -147,4 +151,5 @@ pub struct LocalUserUpdateForm { pub enable_keyboard_navigation: Option, pub enable_animated_images: Option, pub collapse_bot_comments: Option, + pub default_comment_sort_type: Option, } diff --git a/crates/db_schema/src/utils.rs b/crates/db_schema/src/utils.rs index a174e3cb9..a61a230fa 100644 --- a/crates/db_schema/src/utils.rs +++ b/crates/db_schema/src/utils.rs @@ -1,4 +1,4 @@ -use crate::{newtypes::DbUrl, CommentSortType, SortType}; +use crate::{newtypes::DbUrl, CommentSortType, PostSortType}; use chrono::{DateTime, TimeDelta, Utc}; use deadpool::Runtime; use diesel::{ @@ -481,23 +481,15 @@ pub fn naive_now() -> DateTime { Utc::now() } -pub fn post_to_comment_sort_type(sort: SortType) -> CommentSortType { +pub fn post_to_comment_sort_type(sort: PostSortType) -> CommentSortType { + use PostSortType::*; match sort { - SortType::Active | SortType::Hot | SortType::Scaled => CommentSortType::Hot, - SortType::New | SortType::NewComments | SortType::MostComments => CommentSortType::New, - SortType::Old => CommentSortType::Old, - SortType::Controversial => CommentSortType::Controversial, - SortType::TopHour - | SortType::TopSixHour - | SortType::TopTwelveHour - | SortType::TopDay - | SortType::TopAll - | SortType::TopWeek - | SortType::TopYear - | SortType::TopMonth - | SortType::TopThreeMonths - | SortType::TopSixMonths - | SortType::TopNineMonths => CommentSortType::Top, + Active | Hot | Scaled => CommentSortType::Hot, + New | NewComments | MostComments => CommentSortType::New, + Old => CommentSortType::Old, + Controversial => CommentSortType::Controversial, + TopHour | TopSixHour | TopTwelveHour | TopDay | TopAll | TopWeek | TopYear | TopMonth + | TopThreeMonths | TopSixMonths | TopNineMonths => CommentSortType::Top, } } diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index df6216bf7..acd8debf3 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -58,9 +58,10 @@ use lemmy_db_schema::{ ReverseTimestampKey, }, ListingType, - SortType, + PostSortType, }; use tracing::debug; +use PostSortType::*; fn queries<'a>() -> Queries< impl ReadFn<'a, PostView, (PostId, Option<&'a LocalUser>, bool)>, @@ -510,33 +511,33 @@ fn queries<'a>() -> Queries< let time = |interval| post_aggregates::published.gt(now() - interval); // then use the main sort - query = match options.sort.unwrap_or(SortType::Hot) { - SortType::Active => query.then_desc(key::hot_rank_active), - SortType::Hot => query.then_desc(key::hot_rank), - SortType::Scaled => query.then_desc(key::scaled_rank), - SortType::Controversial => query.then_desc(key::controversy_rank), - SortType::New => query.then_desc(key::published), - SortType::Old => query.then_desc(ReverseTimestampKey(key::published)), - SortType::NewComments => query.then_desc(key::newest_comment_time), - SortType::MostComments => query.then_desc(key::comments), - SortType::TopAll => query.then_desc(key::score), - SortType::TopYear => query.then_desc(key::score).filter(time(1.years())), - SortType::TopMonth => query.then_desc(key::score).filter(time(1.months())), - SortType::TopWeek => query.then_desc(key::score).filter(time(1.weeks())), - SortType::TopDay => query.then_desc(key::score).filter(time(1.days())), - SortType::TopHour => query.then_desc(key::score).filter(time(1.hours())), - SortType::TopSixHour => query.then_desc(key::score).filter(time(6.hours())), - SortType::TopTwelveHour => query.then_desc(key::score).filter(time(12.hours())), - SortType::TopThreeMonths => query.then_desc(key::score).filter(time(3.months())), - SortType::TopSixMonths => query.then_desc(key::score).filter(time(6.months())), - SortType::TopNineMonths => query.then_desc(key::score).filter(time(9.months())), + query = match options.sort.unwrap_or(Hot) { + Active => query.then_desc(key::hot_rank_active), + Hot => query.then_desc(key::hot_rank), + Scaled => query.then_desc(key::scaled_rank), + Controversial => query.then_desc(key::controversy_rank), + New => query.then_desc(key::published), + Old => query.then_desc(ReverseTimestampKey(key::published)), + NewComments => query.then_desc(key::newest_comment_time), + MostComments => query.then_desc(key::comments), + TopAll => query.then_desc(key::score), + TopYear => query.then_desc(key::score).filter(time(1.years())), + TopMonth => query.then_desc(key::score).filter(time(1.months())), + TopWeek => query.then_desc(key::score).filter(time(1.weeks())), + TopDay => query.then_desc(key::score).filter(time(1.days())), + TopHour => query.then_desc(key::score).filter(time(1.hours())), + TopSixHour => query.then_desc(key::score).filter(time(6.hours())), + TopTwelveHour => query.then_desc(key::score).filter(time(12.hours())), + TopThreeMonths => query.then_desc(key::score).filter(time(3.months())), + TopSixMonths => query.then_desc(key::score).filter(time(6.months())), + TopNineMonths => query.then_desc(key::score).filter(time(9.months())), }; // use publish as fallback. especially useful for hot rank which reaches zero after some days. // necessary because old posts can be fetched over federation and inserted with high post id - query = match options.sort.unwrap_or(SortType::Hot) { + query = match options.sort.unwrap_or(Hot) { // A second time-based sort would not be very useful - SortType::New | SortType::Old | SortType::NewComments => query, + New | Old | NewComments => query, _ => query.then_desc(key::published), }; @@ -608,7 +609,7 @@ pub struct PaginationCursorData(PostAggregates); #[derive(Clone, Default)] pub struct PostQuery<'a> { pub listing_type: Option, - pub sort: Option, + pub sort: Option, pub creator_id: Option, pub community_id: Option, // if true, the query should be handled as if community_id was not given except adding the @@ -770,7 +771,7 @@ mod tests { traits::{Bannable, Blockable, Crud, Joinable, Likeable}, utils::{build_db_pool, build_db_pool_for_tests, DbPool, RANK_DEFAULT}, CommunityVisibility, - SortType, + PostSortType, SubscribedType, }; use lemmy_utils::error::{LemmyErrorType, LemmyResult}; @@ -801,7 +802,7 @@ mod tests { impl Data { fn default_post_query(&self) -> PostQuery<'_> { PostQuery { - sort: Some(SortType::New), + sort: Some(PostSortType::New), local_user: Some(&self.local_user_view.local_user), ..Default::default() } @@ -1445,7 +1446,7 @@ mod tests { let options = PostQuery { community_id: Some(inserted_community.id), - sort: Some(SortType::MostComments), + sort: Some(PostSortType::MostComments), limit: Some(10), ..Default::default() }; @@ -1577,7 +1578,7 @@ mod tests { // Make sure it does come back with the show_hidden option let post_listings_show_hidden = PostQuery { - sort: Some(SortType::New), + sort: Some(PostSortType::New), local_user: Some(&data.local_user_view.local_user), show_hidden: Some(true), ..Default::default() @@ -1618,7 +1619,7 @@ mod tests { // Make sure it does come back with the show_nsfw option let post_listings_show_nsfw = PostQuery { - sort: Some(SortType::New), + sort: Some(PostSortType::New), show_nsfw: Some(true), local_user: Some(&data.local_user_view.local_user), ..Default::default() diff --git a/crates/db_views/src/registration_application_view.rs b/crates/db_views/src/registration_application_view.rs index 6f806be13..51e2ff1a6 100644 --- a/crates/db_views/src/registration_application_view.rs +++ b/crates/db_views/src/registration_application_view.rs @@ -246,7 +246,8 @@ mod tests { auto_expand: inserted_sara_local_user.auto_expand, blur_nsfw: inserted_sara_local_user.blur_nsfw, theme: inserted_sara_local_user.theme, - default_sort_type: inserted_sara_local_user.default_sort_type, + default_post_sort_type: inserted_sara_local_user.default_post_sort_type, + default_comment_sort_type: inserted_sara_local_user.default_comment_sort_type, default_listing_type: inserted_sara_local_user.default_listing_type, interface_language: inserted_sara_local_user.interface_language, show_avatars: inserted_sara_local_user.show_avatars, diff --git a/crates/db_views_actor/src/community_view.rs b/crates/db_views_actor/src/community_view.rs index 0e731878a..4e09c4c43 100644 --- a/crates/db_views_actor/src/community_view.rs +++ b/crates/db_views_actor/src/community_view.rs @@ -24,7 +24,7 @@ use lemmy_db_schema::{ source::{community::CommunityFollower, local_user::LocalUser, site::Site}, utils::{fuzzy_search, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn}, ListingType, - SortType, + PostSortType, }; fn queries<'a>() -> Queries< @@ -102,7 +102,7 @@ fn queries<'a>() -> Queries< }; let list = move |mut conn: DbConn<'a>, (options, site): (CommunityQuery<'a>, &'a Site)| async move { - use SortType::*; + use PostSortType::*; // The left join below will return None in this case let person_id_join = options.local_user.person_id().unwrap_or(PersonId(-1)); @@ -221,7 +221,7 @@ impl CommunityView { #[derive(Default)] pub struct CommunityQuery<'a> { pub listing_type: Option, - pub sort: Option, + pub sort: Option, pub local_user: Option<&'a LocalUser>, pub search_term: Option, pub is_mod_or_admin: bool, diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs index 7a2edfb44..fe9877d01 100644 --- a/crates/db_views_actor/src/person_view.rs +++ b/crates/db_views_actor/src/person_view.rs @@ -24,7 +24,7 @@ use lemmy_db_schema::{ ReadFn, }, ListingType, - SortType, + PostSortType, }; use serde::{Deserialize, Serialize}; use strum::{Display, EnumString}; @@ -46,12 +46,13 @@ enum PersonSortType { PostCount, } -fn post_to_person_sort_type(sort: SortType) -> PersonSortType { +fn post_to_person_sort_type(sort: PostSortType) -> PersonSortType { + use PostSortType::*; match sort { - SortType::Active | SortType::Hot | SortType::Controversial => PersonSortType::CommentScore, - SortType::New | SortType::NewComments => PersonSortType::New, - SortType::MostComments => PersonSortType::MostComments, - SortType::Old => PersonSortType::Old, + Active | Hot | Controversial => PersonSortType::CommentScore, + New | NewComments => PersonSortType::New, + MostComments => PersonSortType::MostComments, + Old => PersonSortType::Old, _ => PersonSortType::CommentScore, } } @@ -149,7 +150,7 @@ impl PersonView { #[derive(Default)] pub struct PersonQuery { - pub sort: Option, + pub sort: Option, pub search_term: Option, pub listing_type: Option, pub page: Option, @@ -246,7 +247,7 @@ mod tests { assert!(read.is_none()); let list = PersonQuery { - sort: Some(SortType::New), + sort: Some(PostSortType::New), ..Default::default() } .list(pool) diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 02114f382..80c1c7281 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -9,7 +9,7 @@ use lemmy_db_schema::{ CommentSortType, CommunityVisibility, ListingType, - SortType, + PostSortType, }; use lemmy_db_views::{ post_view::PostQuery, @@ -45,12 +45,12 @@ struct Params { } impl Params { - fn sort_type(&self) -> Result { + fn sort_type(&self) -> Result { let sort_query = self .sort .clone() - .unwrap_or_else(|| SortType::Hot.to_string()); - SortType::from_str(&sort_query).map_err(ErrorBadRequest) + .unwrap_or_else(|| PostSortType::Hot.to_string()); + PostSortType::from_str(&sort_query).map_err(ErrorBadRequest) } fn get_limit(&self) -> i64 { self.limit.unwrap_or(RSS_FETCH_LIMIT) @@ -147,7 +147,7 @@ async fn get_local_feed( async fn get_feed_data( context: &LemmyContext, listing_type: ListingType, - sort_type: SortType, + sort_type: PostSortType, limit: i64, page: i64, ) -> LemmyResult { @@ -251,7 +251,7 @@ async fn get_feed( #[tracing::instrument(skip_all)] async fn get_feed_user( context: &LemmyContext, - sort_type: &SortType, + sort_type: &PostSortType, limit: &i64, page: &i64, user_name: &str, @@ -289,7 +289,7 @@ async fn get_feed_user( #[tracing::instrument(skip_all)] async fn get_feed_community( context: &LemmyContext, - sort_type: &SortType, + sort_type: &PostSortType, limit: &i64, page: &i64, community_name: &str, @@ -334,7 +334,7 @@ async fn get_feed_community( #[tracing::instrument(skip_all)] async fn get_feed_front( context: &LemmyContext, - sort_type: &SortType, + sort_type: &PostSortType, limit: &i64, page: &i64, jwt: &str, diff --git a/migrations/2024-09-16-000000_default_comment_sort_type/down.sql b/migrations/2024-09-16-000000_default_comment_sort_type/down.sql new file mode 100644 index 000000000..2a7ba16ea --- /dev/null +++ b/migrations/2024-09-16-000000_default_comment_sort_type/down.sql @@ -0,0 +1,19 @@ +-- This file should undo anything in `up.sql` +-- Rename the post sort enum +ALTER TYPE post_sort_type_enum RENAME TO sort_type_enum; + +-- Rename the default post sort columns +ALTER TABLE local_user RENAME COLUMN default_post_sort_type TO default_sort_type; + +ALTER TABLE local_site RENAME COLUMN default_post_sort_type TO default_sort_type; + +-- Create the comment sort type enum +ALTER TABLE local_user + DROP COLUMN default_comment_sort_type; + +ALTER TABLE local_site + DROP COLUMN default_comment_sort_type; + +-- Drop the comment enum +DROP TYPE comment_sort_type_enum; + diff --git a/migrations/2024-09-16-000000_default_comment_sort_type/up.sql b/migrations/2024-09-16-000000_default_comment_sort_type/up.sql new file mode 100644 index 000000000..adea1896a --- /dev/null +++ b/migrations/2024-09-16-000000_default_comment_sort_type/up.sql @@ -0,0 +1,24 @@ +-- Rename the post sort enum +ALTER TYPE sort_type_enum RENAME TO post_sort_type_enum; + +-- Rename the default post sort columns +ALTER TABLE local_user RENAME COLUMN default_sort_type TO default_post_sort_type; + +ALTER TABLE local_site RENAME COLUMN default_sort_type TO default_post_sort_type; + +-- Create the comment sort type enum +CREATE TYPE comment_sort_type_enum AS ENUM ( + 'Hot', + 'Top', + 'New', + 'Old', + 'Controversial' +); + +-- Add the new default comment sort columns to local_user and local_site +ALTER TABLE local_user + ADD COLUMN default_comment_sort_type comment_sort_type_enum NOT NULL DEFAULT 'Hot'; + +ALTER TABLE local_site + ADD COLUMN default_comment_sort_type comment_sort_type_enum NOT NULL DEFAULT 'Hot'; +