mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-03-13 15:02:44 +00:00
Changes to community visibility (#5478)
* Move community.hidden to visibility (fixes #5458) * fix up migration by dropping index * also add enum variant `LocalOnlyPublic`, rename `LocalOnly` to `LocalOnlyPrivate` fixes #5351 * fix column order in down.sql * wip * more wip * fixes * migration for modlog * fix migration * wip * db_schema compiling * make the code compile * lint * fix down migration * fix test * make hidden status federate * ts attr * fix * fix api test * update api client * review * Extracting filter_not_hidden_or_is_subscribed (#5497) * Extracting filter_not_hidden_or_is_subscribed * Cleanup. * Cleanup 2. * rename hidden to unlisted --------- Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
parent
d93bfdd2fa
commit
8ffeeca52d
39 changed files with 583 additions and 293 deletions
api_tests
crates
api/src/community
api_common/src
api_crud/src/community
apub/src
activities
http
objects
protocol/objects
db_schema
db_views/src
routes/src
utils/src
migrations/2025-03-11-124442_community-hidden-visibility
src
|
@ -29,7 +29,7 @@
|
|||
"eslint": "^9.20.0",
|
||||
"eslint-plugin-prettier": "^5.2.3",
|
||||
"jest": "^29.5.0",
|
||||
"lemmy-js-client": "0.20.0-remove-aggregate-tables.5",
|
||||
"lemmy-js-client": "0.20.0-move-community-hidden.3",
|
||||
"prettier": "^3.5.0",
|
||||
"ts-jest": "^29.1.0",
|
||||
"tsoa": "^6.6.0",
|
||||
|
|
|
@ -33,8 +33,8 @@ importers:
|
|||
specifier: ^29.5.0
|
||||
version: 29.7.0(@types/node@22.13.1)
|
||||
lemmy-js-client:
|
||||
specifier: 0.20.0-remove-aggregate-tables.5
|
||||
version: 0.20.0-remove-aggregate-tables.5
|
||||
specifier: 0.20.0-move-community-hidden.3
|
||||
version: 0.20.0-move-community-hidden.3
|
||||
prettier:
|
||||
specifier: ^3.5.0
|
||||
version: 3.5.0
|
||||
|
@ -1528,8 +1528,8 @@ packages:
|
|||
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
lemmy-js-client@0.20.0-remove-aggregate-tables.5:
|
||||
resolution: {integrity: sha512-A/p4LLWNiVp7fsQOctbFm/biBAunk0FIl5X79WJ/hRu/UiD1M+tCLGYPGdy308R+zscZsDNqECe1LYBenOFzOA==}
|
||||
lemmy-js-client@0.20.0-move-community-hidden.3:
|
||||
resolution: {integrity: sha512-X7bbSrnGGgupr//Qk2M1Z9nvFawNU4T116X+4/j912GO6KbQdWN7+10obbQJuoEYr15oCXwSaK8DLusofLxIig==}
|
||||
|
||||
leven@3.1.0:
|
||||
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||
|
@ -4169,7 +4169,7 @@ snapshots:
|
|||
|
||||
kleur@3.0.3: {}
|
||||
|
||||
lemmy-js-client@0.20.0-remove-aggregate-tables.5: {}
|
||||
lemmy-js-client@0.20.0-move-community-hidden.3: {}
|
||||
|
||||
leven@3.1.0: {}
|
||||
|
||||
|
|
|
@ -521,7 +521,7 @@ test("Content in local-only community doesn't federate", async () => {
|
|||
let communityRes = (await createCommunity(alpha)).community_view.community;
|
||||
let form: EditCommunity = {
|
||||
community_id: communityRes.id,
|
||||
visibility: "LocalOnly",
|
||||
visibility: "LocalOnlyPublic",
|
||||
};
|
||||
await editCommunity(alpha, form);
|
||||
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
use activitypub_federation::config::Data;
|
||||
use actix_web::web::Json;
|
||||
use lemmy_api_common::{
|
||||
community::HideCommunity,
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::is_admin,
|
||||
SuccessResponse,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
community::{Community, CommunityUpdateForm},
|
||||
mod_log::moderator::{ModHideCommunity, ModHideCommunityForm},
|
||||
},
|
||||
traits::Crud,
|
||||
};
|
||||
use lemmy_db_views::structs::LocalUserView;
|
||||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||
|
||||
pub async fn hide_community(
|
||||
data: Json<HideCommunity>,
|
||||
context: Data<LemmyContext>,
|
||||
local_user_view: LocalUserView,
|
||||
) -> LemmyResult<Json<SuccessResponse>> {
|
||||
// Verify its a admin (only admin can hide or unhide it)
|
||||
is_admin(&local_user_view)?;
|
||||
|
||||
let community_form = CommunityUpdateForm {
|
||||
hidden: Some(data.hidden),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mod_hide_community_form = ModHideCommunityForm {
|
||||
community_id: data.community_id,
|
||||
mod_person_id: local_user_view.person.id,
|
||||
reason: data.reason.clone(),
|
||||
hidden: Some(data.hidden),
|
||||
};
|
||||
|
||||
let community_id = data.community_id;
|
||||
let community = Community::update(&mut context.pool(), community_id, &community_form)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateCommunityHiddenStatus)?;
|
||||
|
||||
ModHideCommunity::create(&mut context.pool(), &mod_hide_community_form).await?;
|
||||
|
||||
ActivityChannel::submit_activity(
|
||||
SendActivityData::UpdateCommunity(local_user_view.person.clone(), community),
|
||||
&context,
|
||||
)?;
|
||||
|
||||
Ok(Json(SuccessResponse::default()))
|
||||
}
|
|
@ -2,7 +2,6 @@ pub mod add_mod;
|
|||
pub mod ban;
|
||||
pub mod block;
|
||||
pub mod follow;
|
||||
pub mod hide;
|
||||
pub mod pending_follows;
|
||||
pub mod random;
|
||||
pub mod transfer;
|
||||
|
|
|
@ -44,7 +44,6 @@ use lemmy_db_schema::{
|
|||
},
|
||||
traits::{Crud, Likeable},
|
||||
utils::DbPool,
|
||||
CommunityVisibility,
|
||||
FederationMode,
|
||||
RegistrationMode,
|
||||
};
|
||||
|
@ -1190,7 +1189,7 @@ pub fn read_auth_token(req: &HttpRequest) -> LemmyResult<Option<String>> {
|
|||
|
||||
pub fn send_webmention(post: Post, community: Community) {
|
||||
if let Some(url) = post.url.clone() {
|
||||
if community.visibility == CommunityVisibility::Public {
|
||||
if community.visibility.can_view_without_login() {
|
||||
spawn_try_task(async move {
|
||||
let mut webmention = Webmention::new::<Url>(post.ap_id.clone().into(), url.clone().into())?;
|
||||
webmention.set_checked(true);
|
||||
|
|
|
@ -9,13 +9,15 @@ pub mod list;
|
|||
pub mod remove;
|
||||
pub mod update;
|
||||
|
||||
/// For now only admins can make communities private, in order to prevent abuse.
|
||||
/// Need to implement admin approval for new communities to get rid of this.
|
||||
/// For now only admins can make communities private or hidden, in order to
|
||||
/// prevent abuse. Need to implement admin approval for new communities to
|
||||
/// get rid of this.
|
||||
fn check_community_visibility_allowed(
|
||||
visibility: Option<CommunityVisibility>,
|
||||
local_user_view: &LocalUserView,
|
||||
) -> LemmyResult<()> {
|
||||
if visibility == Some(lemmy_db_schema::CommunityVisibility::Private) {
|
||||
use CommunityVisibility::*;
|
||||
if visibility == Some(Private) || visibility == Some(Unlisted) {
|
||||
is_admin(local_user_view)?;
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -23,10 +23,7 @@ use activitypub_federation::{
|
|||
traits::{ActivityHandler, Actor},
|
||||
};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::{
|
||||
source::{activity::ActivitySendTargets, community::CommunityFollower},
|
||||
CommunityVisibility,
|
||||
};
|
||||
use lemmy_db_schema::source::{activity::ActivitySendTargets, community::CommunityFollower};
|
||||
use lemmy_utils::error::{FederationError, LemmyError, LemmyErrorType, LemmyResult};
|
||||
use serde_json::Value;
|
||||
use url::Url;
|
||||
|
@ -211,7 +208,7 @@ async fn can_accept_activity_in_community(
|
|||
) -> LemmyResult<()> {
|
||||
if let Some(community) = community {
|
||||
// Local only community can't federate
|
||||
if community.visibility == CommunityVisibility::LocalOnly {
|
||||
if !community.visibility.can_federate() {
|
||||
return Err(LemmyErrorType::NotFound.into());
|
||||
}
|
||||
if !community.local {
|
||||
|
|
|
@ -14,7 +14,6 @@ use lemmy_db_schema::{
|
|||
site::Site,
|
||||
},
|
||||
traits::Crud,
|
||||
CommunityVisibility,
|
||||
};
|
||||
use lemmy_db_views::structs::CommunityModeratorView;
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
|
@ -50,7 +49,7 @@ pub(crate) async fn send_activity_in_community(
|
|||
context: &Data<LemmyContext>,
|
||||
) -> LemmyResult<()> {
|
||||
// If community is local only, don't send anything out
|
||||
if community.visibility == CommunityVisibility::LocalOnly {
|
||||
if !community.visibility.can_federate() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ impl ActivityHandler for Follow {
|
|||
}
|
||||
|
||||
async fn receive(self, context: &Data<LemmyContext>) -> LemmyResult<()> {
|
||||
use CommunityVisibility::*;
|
||||
insert_received_activity(&self.id, context).await?;
|
||||
let actor = self.actor.dereference(context).await?;
|
||||
let object = self.object.dereference(context).await?;
|
||||
|
@ -111,10 +112,10 @@ impl ActivityHandler for Follow {
|
|||
}
|
||||
}
|
||||
let state = Some(match c.visibility {
|
||||
CommunityVisibility::Public => CommunityFollowerState::Accepted,
|
||||
CommunityVisibility::Private => CommunityFollowerState::ApprovalRequired,
|
||||
Public | Unlisted => CommunityFollowerState::Accepted,
|
||||
Private => CommunityFollowerState::ApprovalRequired,
|
||||
// Dont allow following local-only community via federation.
|
||||
CommunityVisibility::LocalOnly => return Err(LemmyErrorType::NotFound.into()),
|
||||
LocalOnlyPrivate | LocalOnlyPublic => return Err(LemmyErrorType::NotFound.into()),
|
||||
});
|
||||
let form = CommunityFollowerForm {
|
||||
state,
|
||||
|
|
|
@ -125,9 +125,8 @@ pub(crate) fn verify_visibility(to: &[Url], cc: &[Url], community: &Community) -
|
|||
use CommunityVisibility::*;
|
||||
let object_is_public = [to, cc].iter().any(|set| set.contains(&public()));
|
||||
match community.visibility {
|
||||
Public if !object_is_public => Err(FederationError::ObjectIsNotPublic)?,
|
||||
Public | Unlisted if !object_is_public => Err(FederationError::ObjectIsNotPublic)?,
|
||||
Private if object_is_public => Err(FederationError::ObjectIsNotPrivate)?,
|
||||
LocalOnly => Err(LemmyErrorType::NotFound.into()),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -280,7 +280,7 @@ pub(crate) mod tests {
|
|||
#[serial]
|
||||
async fn test_get_deleted_community() -> LemmyResult<()> {
|
||||
let context = LemmyContext::init_test_context().await;
|
||||
let (instance, _, path) = init(true, CommunityVisibility::LocalOnly, &context).await?;
|
||||
let (instance, _, path) = init(true, CommunityVisibility::Public, &context).await?;
|
||||
let request = TestRequest::default().to_http_request();
|
||||
|
||||
// should return tombstone
|
||||
|
@ -320,7 +320,7 @@ pub(crate) mod tests {
|
|||
#[serial]
|
||||
async fn test_get_local_only_community() -> LemmyResult<()> {
|
||||
let context = LemmyContext::init_test_context().await;
|
||||
let (instance, _, path) = init(false, CommunityVisibility::LocalOnly, &context).await?;
|
||||
let (instance, _, path) = init(false, CommunityVisibility::LocalOnlyPrivate, &context).await?;
|
||||
let request = TestRequest::default().to_http_request();
|
||||
|
||||
let res = get_apub_community_http(path.clone().into(), context.reset_request_count()).await;
|
||||
|
|
|
@ -122,7 +122,7 @@ pub(crate) async fn get_activity(
|
|||
/// Ensure that the community is public and not removed/deleted.
|
||||
fn check_community_fetchable(community: &Community) -> LemmyResult<()> {
|
||||
check_community_removed_or_deleted(community)?;
|
||||
if community.visibility == CommunityVisibility::LocalOnly {
|
||||
if !community.visibility.can_federate() {
|
||||
return Err(LemmyErrorType::NotFound.into());
|
||||
}
|
||||
Ok(())
|
||||
|
@ -137,12 +137,7 @@ async fn check_community_content_fetchable(
|
|||
use CommunityVisibility::*;
|
||||
check_community_removed_or_deleted(community)?;
|
||||
match community.visibility {
|
||||
// content in public community can always be fetched
|
||||
Public => Ok(()),
|
||||
// no federation for local only community
|
||||
LocalOnly => Err(LemmyErrorType::NotFound.into()),
|
||||
// for private community check http signature of request, if there is any approved follower
|
||||
// from the fetching instance then fetching is allowed
|
||||
Public | Unlisted => Ok(()),
|
||||
Private => {
|
||||
let signing_actor = signing_actor::<SiteOrCommunityOrUser>(request, None, context).await?;
|
||||
if community.local {
|
||||
|
@ -167,6 +162,7 @@ async fn check_community_content_fetchable(
|
|||
Err(LemmyErrorType::NotFound.into())
|
||||
}
|
||||
}
|
||||
LocalOnlyPublic | LocalOnlyPrivate => Err(LemmyErrorType::NotFound.into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ impl Object for ApubCommunity {
|
|||
posting_restricted_to_mods: Some(self.posting_restricted_to_mods),
|
||||
attributed_to: Some(generate_moderators_url(&self.ap_id)?.into()),
|
||||
manually_approves_followers: Some(self.visibility == CommunityVisibility::Private),
|
||||
discoverable: Some(self.visibility != CommunityVisibility::Unlisted),
|
||||
};
|
||||
Ok(group)
|
||||
}
|
||||
|
@ -148,6 +149,8 @@ impl Object for ApubCommunity {
|
|||
let banner = proxy_image_link_opt_apub(group.image.map(|i| i.url), context).await?;
|
||||
let visibility = Some(if group.manually_approves_followers.unwrap_or_default() {
|
||||
CommunityVisibility::Private
|
||||
} else if !group.discoverable.unwrap_or(true) {
|
||||
CommunityVisibility::Unlisted
|
||||
} else {
|
||||
CommunityVisibility::Public
|
||||
});
|
||||
|
|
|
@ -77,6 +77,8 @@ pub struct Group {
|
|||
pub(crate) manually_approves_followers: Option<bool>,
|
||||
pub(crate) published: Option<DateTime<Utc>>,
|
||||
pub(crate) updated: Option<DateTime<Utc>>,
|
||||
/// https://docs.joinmastodon.org/spec/activitypub/#discoverable
|
||||
pub(crate) discoverable: Option<bool>,
|
||||
}
|
||||
|
||||
impl Group {
|
||||
|
|
|
@ -595,7 +595,7 @@ CALL r.create_person_saved_combined_trigger ('comment');
|
|||
-- mod_ban
|
||||
-- mod_ban_from_community
|
||||
-- mod_feature_post
|
||||
-- mod_hide_community
|
||||
-- mod_change_community_visibility
|
||||
-- mod_lock_post
|
||||
-- mod_remove_comment
|
||||
-- mod_remove_community
|
||||
|
@ -646,7 +646,7 @@ CALL r.create_modlog_combined_trigger ('mod_ban_from_community');
|
|||
|
||||
CALL r.create_modlog_combined_trigger ('mod_feature_post');
|
||||
|
||||
CALL r.create_modlog_combined_trigger ('mod_hide_community');
|
||||
CALL r.create_modlog_combined_trigger ('mod_change_community_visibility');
|
||||
|
||||
CALL r.create_modlog_combined_trigger ('mod_lock_post');
|
||||
|
||||
|
|
|
@ -634,7 +634,6 @@ mod tests {
|
|||
inbox_url: inserted_community.inbox_url.clone(),
|
||||
moderators_url: None,
|
||||
featured_url: None,
|
||||
hidden: false,
|
||||
posting_restricted_to_mods: false,
|
||||
instance_id: inserted_instance.id,
|
||||
visibility: CommunityVisibility::Public,
|
||||
|
|
|
@ -4,8 +4,8 @@ use crate::{
|
|||
ModAddId,
|
||||
ModBanFromCommunityId,
|
||||
ModBanId,
|
||||
ModChangeCommunityVisibilityId,
|
||||
ModFeaturePostId,
|
||||
ModHideCommunityId,
|
||||
ModLockPostId,
|
||||
ModRemoveCommentId,
|
||||
ModRemoveCommunityId,
|
||||
|
@ -17,8 +17,8 @@ use crate::{
|
|||
mod_add_community,
|
||||
mod_ban,
|
||||
mod_ban_from_community,
|
||||
mod_change_community_visibility,
|
||||
mod_feature_post,
|
||||
mod_hide_community,
|
||||
mod_lock_post,
|
||||
mod_remove_comment,
|
||||
mod_remove_community,
|
||||
|
@ -34,10 +34,10 @@ use crate::{
|
|||
ModBanForm,
|
||||
ModBanFromCommunity,
|
||||
ModBanFromCommunityForm,
|
||||
ModChangeCommunityVisibility,
|
||||
ModChangeCommunityVisibilityForm,
|
||||
ModFeaturePost,
|
||||
ModFeaturePostForm,
|
||||
ModHideCommunity,
|
||||
ModHideCommunityForm,
|
||||
ModLockPost,
|
||||
ModLockPostForm,
|
||||
ModRemoveComment,
|
||||
|
@ -263,14 +263,14 @@ impl Crud for ModBan {
|
|||
}
|
||||
}
|
||||
|
||||
impl Crud for ModHideCommunity {
|
||||
type InsertForm = ModHideCommunityForm;
|
||||
type UpdateForm = ModHideCommunityForm;
|
||||
type IdType = ModHideCommunityId;
|
||||
impl Crud for ModChangeCommunityVisibility {
|
||||
type InsertForm = ModChangeCommunityVisibilityForm;
|
||||
type UpdateForm = ModChangeCommunityVisibilityForm;
|
||||
type IdType = ModChangeCommunityVisibilityId;
|
||||
|
||||
async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result<Self, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
insert_into(mod_hide_community::table)
|
||||
insert_into(mod_change_community_visibility::table)
|
||||
.values(form)
|
||||
.get_result::<Self>(conn)
|
||||
.await
|
||||
|
@ -282,7 +282,7 @@ impl Crud for ModHideCommunity {
|
|||
form: &Self::UpdateForm,
|
||||
) -> Result<Self, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
diesel::update(mod_hide_community::table.find(from_id))
|
||||
diesel::update(mod_change_community_visibility::table.find(from_id))
|
||||
.set(form)
|
||||
.get_result::<Self>(conn)
|
||||
.await
|
||||
|
|
|
@ -205,7 +205,7 @@ pub enum ModlogActionType {
|
|||
ModTransferCommunity,
|
||||
ModAdd,
|
||||
ModBan,
|
||||
ModHideCommunity,
|
||||
ModChangeCommunityVisibility,
|
||||
AdminPurgePerson,
|
||||
AdminPurgeCommunity,
|
||||
AdminPurgePost,
|
||||
|
@ -277,12 +277,28 @@ pub enum CommunityVisibility {
|
|||
/// Public community, any local or federated user can interact.
|
||||
#[default]
|
||||
Public,
|
||||
/// Unfederated community, only local users can interact.
|
||||
LocalOnly,
|
||||
/// Community is hidden and doesn't appear in community list. Post from the community
|
||||
/// are not shown in Local and All feeds, except for subscribed users.
|
||||
Unlisted,
|
||||
/// Unfederated community, only local users can interact (with or without login).
|
||||
LocalOnlyPublic,
|
||||
/// Unfederated community, only logged-in local users can interact.
|
||||
LocalOnlyPrivate,
|
||||
/// Users need to be approved by mods before they are able to browse or post.
|
||||
Private,
|
||||
}
|
||||
|
||||
impl CommunityVisibility {
|
||||
pub fn can_federate(&self) -> bool {
|
||||
use CommunityVisibility::*;
|
||||
self != &LocalOnlyPublic && self != &LocalOnlyPrivate
|
||||
}
|
||||
pub fn can_view_without_login(&self) -> bool {
|
||||
use CommunityVisibility::*;
|
||||
self == &Public || self == &LocalOnlyPublic
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default, Hash,
|
||||
)]
|
||||
|
|
|
@ -295,7 +295,7 @@ pub struct ModBanId(pub i32);
|
|||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
|
||||
#[cfg_attr(feature = "full", derive(DieselNewType, TS))]
|
||||
#[cfg_attr(feature = "full", ts(export))]
|
||||
pub struct ModHideCommunityId(pub i32);
|
||||
pub struct ModChangeCommunityVisibilityId(pub i32);
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
|
||||
#[cfg_attr(feature = "full", derive(DieselNewType, TS))]
|
||||
|
|
|
@ -204,7 +204,6 @@ diesel::table! {
|
|||
followers_url -> Nullable<Varchar>,
|
||||
#[max_length = 255]
|
||||
inbox_url -> Varchar,
|
||||
hidden -> Bool,
|
||||
posting_restricted_to_mods -> Bool,
|
||||
instance_id -> Int4,
|
||||
#[max_length = 255]
|
||||
|
@ -435,6 +434,7 @@ diesel::table! {
|
|||
comment_downvotes -> FederationModeEnum,
|
||||
disable_donation_dialog -> Bool,
|
||||
default_post_time_range_seconds -> Nullable<Int4>,
|
||||
disallow_nsfw_content -> Bool,
|
||||
users -> Int8,
|
||||
posts -> Int8,
|
||||
comments -> Int8,
|
||||
|
@ -443,7 +443,6 @@ diesel::table! {
|
|||
users_active_week -> Int8,
|
||||
users_active_month -> Int8,
|
||||
users_active_half_year -> Int8,
|
||||
disallow_nsfw_content -> Bool,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,6 +587,20 @@ diesel::table! {
|
|||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
use diesel::sql_types::*;
|
||||
use super::sql_types::CommunityVisibility;
|
||||
|
||||
mod_change_community_visibility (id) {
|
||||
id -> Int4,
|
||||
community_id -> Int4,
|
||||
mod_person_id -> Int4,
|
||||
published -> Timestamptz,
|
||||
reason -> Nullable<Text>,
|
||||
visibility -> CommunityVisibility,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
mod_feature_post (id) {
|
||||
id -> Int4,
|
||||
|
@ -599,17 +612,6 @@ diesel::table! {
|
|||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
mod_hide_community (id) {
|
||||
id -> Int4,
|
||||
community_id -> Int4,
|
||||
mod_person_id -> Int4,
|
||||
published -> Timestamptz,
|
||||
reason -> Nullable<Text>,
|
||||
hidden -> Bool,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
mod_lock_post (id) {
|
||||
id -> Int4,
|
||||
|
@ -678,12 +680,12 @@ diesel::table! {
|
|||
mod_ban_id -> Nullable<Int4>,
|
||||
mod_ban_from_community_id -> Nullable<Int4>,
|
||||
mod_feature_post_id -> Nullable<Int4>,
|
||||
mod_hide_community_id -> Nullable<Int4>,
|
||||
mod_lock_post_id -> Nullable<Int4>,
|
||||
mod_remove_comment_id -> Nullable<Int4>,
|
||||
mod_remove_community_id -> Nullable<Int4>,
|
||||
mod_remove_post_id -> Nullable<Int4>,
|
||||
mod_transfer_community_id -> Nullable<Int4>,
|
||||
mod_change_community_visibility_id -> Nullable<Int4>,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1107,10 +1109,10 @@ diesel::joinable!(local_user_language -> local_user (local_user_id));
|
|||
diesel::joinable!(login_token -> local_user (user_id));
|
||||
diesel::joinable!(mod_add_community -> community (community_id));
|
||||
diesel::joinable!(mod_ban_from_community -> community (community_id));
|
||||
diesel::joinable!(mod_change_community_visibility -> community (community_id));
|
||||
diesel::joinable!(mod_change_community_visibility -> person (mod_person_id));
|
||||
diesel::joinable!(mod_feature_post -> person (mod_person_id));
|
||||
diesel::joinable!(mod_feature_post -> post (post_id));
|
||||
diesel::joinable!(mod_hide_community -> community (community_id));
|
||||
diesel::joinable!(mod_hide_community -> person (mod_person_id));
|
||||
diesel::joinable!(mod_lock_post -> person (mod_person_id));
|
||||
diesel::joinable!(mod_lock_post -> post (post_id));
|
||||
diesel::joinable!(mod_remove_comment -> comment (comment_id));
|
||||
|
@ -1130,8 +1132,8 @@ diesel::joinable!(modlog_combined -> mod_add (mod_add_id));
|
|||
diesel::joinable!(modlog_combined -> mod_add_community (mod_add_community_id));
|
||||
diesel::joinable!(modlog_combined -> mod_ban (mod_ban_id));
|
||||
diesel::joinable!(modlog_combined -> mod_ban_from_community (mod_ban_from_community_id));
|
||||
diesel::joinable!(modlog_combined -> mod_change_community_visibility (mod_change_community_visibility_id));
|
||||
diesel::joinable!(modlog_combined -> mod_feature_post (mod_feature_post_id));
|
||||
diesel::joinable!(modlog_combined -> mod_hide_community (mod_hide_community_id));
|
||||
diesel::joinable!(modlog_combined -> mod_lock_post (mod_lock_post_id));
|
||||
diesel::joinable!(modlog_combined -> mod_remove_comment (mod_remove_comment_id));
|
||||
diesel::joinable!(modlog_combined -> mod_remove_community (mod_remove_community_id));
|
||||
|
@ -1214,8 +1216,8 @@ diesel::allow_tables_to_appear_in_same_query!(
|
|||
mod_add_community,
|
||||
mod_ban,
|
||||
mod_ban_from_community,
|
||||
mod_change_community_visibility,
|
||||
mod_feature_post,
|
||||
mod_hide_community,
|
||||
mod_lock_post,
|
||||
mod_remove_comment,
|
||||
mod_remove_community,
|
||||
|
|
|
@ -9,8 +9,8 @@ use crate::newtypes::{
|
|||
ModAddId,
|
||||
ModBanFromCommunityId,
|
||||
ModBanId,
|
||||
ModChangeCommunityVisibilityId,
|
||||
ModFeaturePostId,
|
||||
ModHideCommunityId,
|
||||
ModLockPostId,
|
||||
ModRemoveCommentId,
|
||||
ModRemoveCommunityId,
|
||||
|
@ -48,7 +48,7 @@ pub struct ModlogCombined {
|
|||
pub mod_ban_id: Option<ModBanId>,
|
||||
pub mod_ban_from_community_id: Option<ModBanFromCommunityId>,
|
||||
pub mod_feature_post_id: Option<ModFeaturePostId>,
|
||||
pub mod_hide_community_id: Option<ModHideCommunityId>,
|
||||
pub mod_change_community_visibility_id: Option<ModChangeCommunityVisibilityId>,
|
||||
pub mod_lock_post_id: Option<ModLockPostId>,
|
||||
pub mod_remove_comment_id: Option<ModRemoveCommentId>,
|
||||
pub mod_remove_community_id: Option<ModRemoveCommunityId>,
|
||||
|
|
|
@ -61,8 +61,6 @@ pub struct Community {
|
|||
#[cfg_attr(feature = "full", ts(skip))]
|
||||
#[serde(skip, default = "placeholder_apub_url")]
|
||||
pub inbox_url: DbUrl,
|
||||
/// Whether the community is hidden.
|
||||
pub hidden: bool,
|
||||
/// Whether posting is restricted to mods only.
|
||||
pub posting_restricted_to_mods: bool,
|
||||
pub instance_id: InstanceId,
|
||||
|
@ -140,8 +138,6 @@ pub struct CommunityInsertForm {
|
|||
#[new(default)]
|
||||
pub featured_url: Option<DbUrl>,
|
||||
#[new(default)]
|
||||
pub hidden: Option<bool>,
|
||||
#[new(default)]
|
||||
pub posting_restricted_to_mods: Option<bool>,
|
||||
#[new(default)]
|
||||
pub visibility: Option<CommunityVisibility>,
|
||||
|
@ -171,7 +167,6 @@ pub struct CommunityUpdateForm {
|
|||
pub inbox_url: Option<DbUrl>,
|
||||
pub moderators_url: Option<DbUrl>,
|
||||
pub featured_url: Option<DbUrl>,
|
||||
pub hidden: Option<bool>,
|
||||
pub posting_restricted_to_mods: Option<bool>,
|
||||
pub visibility: Option<CommunityVisibility>,
|
||||
pub description: Option<Option<String>>,
|
||||
|
|
|
@ -89,6 +89,8 @@ pub struct LocalSite {
|
|||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
/// A default time range limit to apply to post sorts, in seconds.
|
||||
pub default_post_time_range_seconds: Option<i32>,
|
||||
/// Block NSFW content being created
|
||||
pub disallow_nsfw_content: bool,
|
||||
pub users: i64,
|
||||
pub posts: i64,
|
||||
pub comments: i64,
|
||||
|
@ -101,8 +103,6 @@ pub struct LocalSite {
|
|||
pub users_active_month: i64,
|
||||
/// The number of users with any activity in the last half year.
|
||||
pub users_active_half_year: i64,
|
||||
/// Block NSFW content being created
|
||||
pub disallow_nsfw_content: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, derive_new::new)]
|
||||
|
|
|
@ -1,34 +1,37 @@
|
|||
use crate::newtypes::{
|
||||
CommentId,
|
||||
CommunityId,
|
||||
ModAddCommunityId,
|
||||
ModAddId,
|
||||
ModBanFromCommunityId,
|
||||
ModBanId,
|
||||
ModFeaturePostId,
|
||||
ModHideCommunityId,
|
||||
ModLockPostId,
|
||||
ModRemoveCommentId,
|
||||
ModRemoveCommunityId,
|
||||
ModRemovePostId,
|
||||
ModTransferCommunityId,
|
||||
PersonId,
|
||||
PostId,
|
||||
};
|
||||
#[cfg(feature = "full")]
|
||||
use crate::schema::{
|
||||
mod_add,
|
||||
mod_add_community,
|
||||
mod_ban,
|
||||
mod_ban_from_community,
|
||||
mod_change_community_visibility,
|
||||
mod_feature_post,
|
||||
mod_hide_community,
|
||||
mod_lock_post,
|
||||
mod_remove_comment,
|
||||
mod_remove_community,
|
||||
mod_remove_post,
|
||||
mod_transfer_community,
|
||||
};
|
||||
use crate::{
|
||||
newtypes::{
|
||||
CommentId,
|
||||
CommunityId,
|
||||
ModAddCommunityId,
|
||||
ModAddId,
|
||||
ModBanFromCommunityId,
|
||||
ModBanId,
|
||||
ModChangeCommunityVisibilityId,
|
||||
ModFeaturePostId,
|
||||
ModLockPostId,
|
||||
ModRemoveCommentId,
|
||||
ModRemoveCommunityId,
|
||||
ModRemovePostId,
|
||||
ModTransferCommunityId,
|
||||
PersonId,
|
||||
PostId,
|
||||
},
|
||||
CommunityVisibility,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
|
@ -210,29 +213,28 @@ pub struct ModBan {
|
|||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = mod_hide_community))]
|
||||
pub struct ModHideCommunityForm {
|
||||
#[cfg_attr(feature = "full", diesel(table_name = mod_change_community_visibility))]
|
||||
pub struct ModChangeCommunityVisibilityForm {
|
||||
pub community_id: CommunityId,
|
||||
pub mod_person_id: PersonId,
|
||||
pub hidden: Option<bool>,
|
||||
pub reason: Option<String>,
|
||||
pub visibility: CommunityVisibility,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "full", derive(Queryable, Selectable, Identifiable, TS))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = mod_hide_community))]
|
||||
#[cfg_attr(feature = "full", diesel(table_name = mod_change_community_visibility))]
|
||||
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||
#[cfg_attr(feature = "full", ts(export))]
|
||||
/// When a community is hidden from public view.
|
||||
pub struct ModHideCommunity {
|
||||
pub id: ModHideCommunityId,
|
||||
pub struct ModChangeCommunityVisibility {
|
||||
pub id: ModChangeCommunityVisibilityId,
|
||||
pub community_id: CommunityId,
|
||||
pub mod_person_id: PersonId,
|
||||
pub published: DateTime<Utc>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub reason: Option<String>,
|
||||
pub hidden: bool,
|
||||
pub visibility: CommunityVisibility,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
use crate::structs::{
|
||||
AdminAllowInstanceView,
|
||||
AdminBlockInstanceView,
|
||||
AdminPurgeCommentView,
|
||||
AdminPurgeCommunityView,
|
||||
AdminPurgePersonView,
|
||||
AdminPurgePostView,
|
||||
ModAddCommunityView,
|
||||
ModAddView,
|
||||
ModBanFromCommunityView,
|
||||
ModBanView,
|
||||
ModFeaturePostView,
|
||||
ModHideCommunityView,
|
||||
ModLockPostView,
|
||||
ModRemoveCommentView,
|
||||
ModRemoveCommunityView,
|
||||
ModRemovePostView,
|
||||
ModTransferCommunityView,
|
||||
ModlogCombinedView,
|
||||
ModlogCombinedViewInternal,
|
||||
use crate::{
|
||||
structs::{
|
||||
AdminAllowInstanceView,
|
||||
AdminBlockInstanceView,
|
||||
AdminPurgeCommentView,
|
||||
AdminPurgeCommunityView,
|
||||
AdminPurgePersonView,
|
||||
AdminPurgePostView,
|
||||
ModAddCommunityView,
|
||||
ModAddView,
|
||||
ModBanFromCommunityView,
|
||||
ModBanView,
|
||||
ModChangeCommunityVisibilityView,
|
||||
ModFeaturePostView,
|
||||
ModLockPostView,
|
||||
ModRemoveCommentView,
|
||||
ModRemoveCommunityView,
|
||||
ModRemovePostView,
|
||||
ModTransferCommunityView,
|
||||
ModlogCombinedView,
|
||||
ModlogCombinedViewInternal,
|
||||
},
|
||||
utils::{filter_is_subscribed, filter_not_hidden_or_is_subscribed},
|
||||
};
|
||||
use diesel::{
|
||||
BoolExpressionMethods,
|
||||
|
@ -49,8 +52,8 @@ use lemmy_db_schema::{
|
|||
mod_add_community,
|
||||
mod_ban,
|
||||
mod_ban_from_community,
|
||||
mod_change_community_visibility,
|
||||
mod_feature_post,
|
||||
mod_hide_community,
|
||||
mod_lock_post,
|
||||
mod_remove_comment,
|
||||
mod_remove_community,
|
||||
|
@ -103,7 +106,7 @@ impl ModlogCombinedViewInternal {
|
|||
.or(mod_ban::mod_person_id.eq(person::id))
|
||||
.or(mod_ban_from_community::mod_person_id.eq(person::id))
|
||||
.or(mod_feature_post::mod_person_id.eq(person::id))
|
||||
.or(mod_hide_community::mod_person_id.eq(person::id))
|
||||
.or(mod_change_community_visibility::mod_person_id.eq(person::id))
|
||||
.or(mod_lock_post::mod_person_id.eq(person::id))
|
||||
.or(mod_remove_comment::mod_person_id.eq(person::id))
|
||||
.or(mod_remove_community::mod_person_id.eq(person::id))
|
||||
|
@ -167,7 +170,7 @@ impl ModlogCombinedViewInternal {
|
|||
.is_not_null()
|
||||
.and(post::community_id.eq(community::id)),
|
||||
)
|
||||
.or(mod_hide_community::community_id.eq(community::id))
|
||||
.or(mod_change_community_visibility::community_id.eq(community::id))
|
||||
.or(
|
||||
mod_lock_post::id
|
||||
.is_not_null()
|
||||
|
@ -211,7 +214,7 @@ impl ModlogCombinedViewInternal {
|
|||
.left_join(mod_ban::table)
|
||||
.left_join(mod_ban_from_community::table)
|
||||
.left_join(mod_feature_post::table)
|
||||
.left_join(mod_hide_community::table)
|
||||
.left_join(mod_change_community_visibility::table)
|
||||
.left_join(mod_lock_post::table)
|
||||
.left_join(mod_remove_comment::table)
|
||||
.left_join(mod_remove_community::table)
|
||||
|
@ -230,24 +233,25 @@ impl ModlogCombinedViewInternal {
|
|||
impl PaginationCursorBuilder for ModlogCombinedView {
|
||||
type CursorData = ModlogCombined;
|
||||
fn to_cursor(&self) -> PaginationCursor {
|
||||
use ModlogCombinedView::*;
|
||||
let (prefix, id) = match &self {
|
||||
ModlogCombinedView::AdminAllowInstance(v) => ('A', v.admin_allow_instance.id.0),
|
||||
ModlogCombinedView::AdminBlockInstance(v) => ('B', v.admin_block_instance.id.0),
|
||||
ModlogCombinedView::AdminPurgeComment(v) => ('C', v.admin_purge_comment.id.0),
|
||||
ModlogCombinedView::AdminPurgeCommunity(v) => ('D', v.admin_purge_community.id.0),
|
||||
ModlogCombinedView::AdminPurgePerson(v) => ('E', v.admin_purge_person.id.0),
|
||||
ModlogCombinedView::AdminPurgePost(v) => ('F', v.admin_purge_post.id.0),
|
||||
ModlogCombinedView::ModAdd(v) => ('G', v.mod_add.id.0),
|
||||
ModlogCombinedView::ModAddCommunity(v) => ('H', v.mod_add_community.id.0),
|
||||
ModlogCombinedView::ModBan(v) => ('I', v.mod_ban.id.0),
|
||||
ModlogCombinedView::ModBanFromCommunity(v) => ('J', v.mod_ban_from_community.id.0),
|
||||
ModlogCombinedView::ModFeaturePost(v) => ('K', v.mod_feature_post.id.0),
|
||||
ModlogCombinedView::ModHideCommunity(v) => ('L', v.mod_hide_community.id.0),
|
||||
ModlogCombinedView::ModLockPost(v) => ('M', v.mod_lock_post.id.0),
|
||||
ModlogCombinedView::ModRemoveComment(v) => ('N', v.mod_remove_comment.id.0),
|
||||
ModlogCombinedView::ModRemoveCommunity(v) => ('O', v.mod_remove_community.id.0),
|
||||
ModlogCombinedView::ModRemovePost(v) => ('P', v.mod_remove_post.id.0),
|
||||
ModlogCombinedView::ModTransferCommunity(v) => ('Q', v.mod_transfer_community.id.0),
|
||||
AdminAllowInstance(v) => ('A', v.admin_allow_instance.id.0),
|
||||
AdminBlockInstance(v) => ('B', v.admin_block_instance.id.0),
|
||||
AdminPurgeComment(v) => ('C', v.admin_purge_comment.id.0),
|
||||
AdminPurgeCommunity(v) => ('D', v.admin_purge_community.id.0),
|
||||
AdminPurgePerson(v) => ('E', v.admin_purge_person.id.0),
|
||||
AdminPurgePost(v) => ('F', v.admin_purge_post.id.0),
|
||||
ModAdd(v) => ('G', v.mod_add.id.0),
|
||||
ModAddCommunity(v) => ('H', v.mod_add_community.id.0),
|
||||
ModBan(v) => ('I', v.mod_ban.id.0),
|
||||
ModBanFromCommunity(v) => ('J', v.mod_ban_from_community.id.0),
|
||||
ModFeaturePost(v) => ('K', v.mod_feature_post.id.0),
|
||||
ModChangeCommunityVisibility(v) => ('L', v.mod_change_community_visibility.id.0),
|
||||
ModLockPost(v) => ('M', v.mod_lock_post.id.0),
|
||||
ModRemoveComment(v) => ('N', v.mod_remove_comment.id.0),
|
||||
ModRemoveCommunity(v) => ('O', v.mod_remove_community.id.0),
|
||||
ModRemovePost(v) => ('P', v.mod_remove_post.id.0),
|
||||
ModTransferCommunity(v) => ('Q', v.mod_transfer_community.id.0),
|
||||
};
|
||||
PaginationCursor::new(prefix, id)
|
||||
}
|
||||
|
@ -275,7 +279,7 @@ impl PaginationCursorBuilder for ModlogCombinedView {
|
|||
'I' => query.filter(modlog_combined::mod_ban_id.eq(id)),
|
||||
'J' => query.filter(modlog_combined::mod_ban_from_community_id.eq(id)),
|
||||
'K' => query.filter(modlog_combined::mod_feature_post_id.eq(id)),
|
||||
'L' => query.filter(modlog_combined::mod_hide_community_id.eq(id)),
|
||||
'L' => query.filter(modlog_combined::mod_change_community_visibility_id.eq(id)),
|
||||
'M' => query.filter(modlog_combined::mod_lock_post_id.eq(id)),
|
||||
'N' => query.filter(modlog_combined::mod_remove_comment_id.eq(id)),
|
||||
'O' => query.filter(modlog_combined::mod_remove_community_id.eq(id)),
|
||||
|
@ -355,7 +359,9 @@ impl ModlogCombinedQuery<'_> {
|
|||
}
|
||||
ModAdd => query.filter(modlog_combined::mod_add_id.is_not_null()),
|
||||
ModBan => query.filter(modlog_combined::mod_ban_id.is_not_null()),
|
||||
ModHideCommunity => query.filter(modlog_combined::mod_hide_community_id.is_not_null()),
|
||||
ModChangeCommunityVisibility => {
|
||||
query.filter(modlog_combined::mod_change_community_visibility_id.is_not_null())
|
||||
}
|
||||
AdminPurgePerson => query.filter(modlog_combined::admin_purge_person_id.is_not_null()),
|
||||
AdminPurgeCommunity => {
|
||||
query.filter(modlog_combined::admin_purge_community_id.is_not_null())
|
||||
|
@ -367,13 +373,12 @@ impl ModlogCombinedQuery<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
let is_subscribed = community_actions::followed.is_not_null();
|
||||
query = match self.listing_type.unwrap_or(ListingType::All) {
|
||||
ListingType::All => query,
|
||||
ListingType::Subscribed => query.filter(is_subscribed),
|
||||
ListingType::Subscribed => query.filter(filter_is_subscribed()),
|
||||
ListingType::Local => query
|
||||
.filter(community::local.eq(true))
|
||||
.filter(community::hidden.eq(false).or(is_subscribed)),
|
||||
.filter(filter_not_hidden_or_is_subscribed()),
|
||||
ListingType::ModeratorView => query.filter(community_actions::became_moderator.is_not_null()),
|
||||
};
|
||||
|
||||
|
@ -507,14 +512,16 @@ impl InternalToCombinedView for ModlogCombinedViewInternal {
|
|||
community,
|
||||
post,
|
||||
}))
|
||||
} else if let (Some(mod_hide_community), Some(community)) =
|
||||
(v.mod_hide_community, v.community.clone())
|
||||
} else if let (Some(mod_change_community_visibility), Some(community)) =
|
||||
(v.mod_change_community_visibility, v.community.clone())
|
||||
{
|
||||
Some(ModlogCombinedView::ModHideCommunity(ModHideCommunityView {
|
||||
mod_hide_community,
|
||||
admin: v.moderator,
|
||||
community,
|
||||
}))
|
||||
Some(ModlogCombinedView::ModChangeCommunityVisibility(
|
||||
ModChangeCommunityVisibilityView {
|
||||
mod_change_community_visibility,
|
||||
moderator: v.moderator,
|
||||
community,
|
||||
},
|
||||
))
|
||||
} else if let (Some(mod_lock_post), Some(other_person), Some(community), Some(post)) = (
|
||||
v.mod_lock_post,
|
||||
v.other_person.clone(),
|
||||
|
@ -626,10 +633,10 @@ mod tests {
|
|||
ModBanForm,
|
||||
ModBanFromCommunity,
|
||||
ModBanFromCommunityForm,
|
||||
ModChangeCommunityVisibility,
|
||||
ModChangeCommunityVisibilityForm,
|
||||
ModFeaturePost,
|
||||
ModFeaturePostForm,
|
||||
ModHideCommunity,
|
||||
ModHideCommunityForm,
|
||||
ModLockPost,
|
||||
ModLockPostForm,
|
||||
ModRemoveComment,
|
||||
|
@ -647,6 +654,7 @@ mod tests {
|
|||
},
|
||||
traits::Crud,
|
||||
utils::{build_db_pool_for_tests, DbPool},
|
||||
CommunityVisibility,
|
||||
ModlogActionType,
|
||||
};
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
|
@ -778,43 +786,49 @@ mod tests {
|
|||
};
|
||||
AdminPurgePost::create(pool, &form).await?;
|
||||
|
||||
let form = ModHideCommunityForm {
|
||||
let form = ModChangeCommunityVisibilityForm {
|
||||
mod_person_id: data.timmy.id,
|
||||
community_id: data.community.id,
|
||||
hidden: Some(true),
|
||||
visibility: CommunityVisibility::Unlisted,
|
||||
reason: None,
|
||||
};
|
||||
ModHideCommunity::create(pool, &form).await?;
|
||||
ModChangeCommunityVisibility::create(pool, &form).await?;
|
||||
|
||||
// A 2nd mod hide community, but to a different community, and with jessica
|
||||
let form = ModHideCommunityForm {
|
||||
let form = ModChangeCommunityVisibilityForm {
|
||||
mod_person_id: data.jessica.id,
|
||||
community_id: data.community_2.id,
|
||||
hidden: Some(true),
|
||||
visibility: CommunityVisibility::Unlisted,
|
||||
reason: None,
|
||||
};
|
||||
ModHideCommunity::create(pool, &form).await?;
|
||||
ModChangeCommunityVisibility::create(pool, &form).await?;
|
||||
|
||||
let modlog = ModlogCombinedQuery::default().list(pool).await?;
|
||||
assert_eq!(8, modlog.len());
|
||||
|
||||
if let ModlogCombinedView::ModHideCommunity(v) = &modlog[0] {
|
||||
assert_eq!(data.community_2.id, v.mod_hide_community.community_id);
|
||||
if let ModlogCombinedView::ModChangeCommunityVisibility(v) = &modlog[0] {
|
||||
assert_eq!(
|
||||
data.community_2.id,
|
||||
v.mod_change_community_visibility.community_id
|
||||
);
|
||||
assert_eq!(data.community_2.id, v.community.id);
|
||||
assert_eq!(
|
||||
data.jessica.id,
|
||||
v.admin.as_ref().map(|a| a.id).unwrap_or(PersonId(-1))
|
||||
v.moderator.as_ref().map(|a| a.id).unwrap_or(PersonId(-1))
|
||||
);
|
||||
} else {
|
||||
panic!("wrong type");
|
||||
}
|
||||
|
||||
if let ModlogCombinedView::ModHideCommunity(v) = &modlog[1] {
|
||||
assert_eq!(data.community.id, v.mod_hide_community.community_id);
|
||||
if let ModlogCombinedView::ModChangeCommunityVisibility(v) = &modlog[1] {
|
||||
assert_eq!(
|
||||
data.community.id,
|
||||
v.mod_change_community_visibility.community_id
|
||||
);
|
||||
assert_eq!(data.community.id, v.community.id);
|
||||
assert_eq!(
|
||||
data.timmy.id,
|
||||
v.admin.as_ref().map(|a| a.id).unwrap_or(PersonId(-1))
|
||||
v.moderator.as_ref().map(|a| a.id).unwrap_or(PersonId(-1))
|
||||
);
|
||||
} else {
|
||||
panic!("wrong type");
|
||||
|
@ -906,7 +920,7 @@ mod tests {
|
|||
|
||||
// Filter by type
|
||||
let modlog_type_filter = ModlogCombinedQuery {
|
||||
type_: Some(ModlogActionType::ModHideCommunity),
|
||||
type_: Some(ModlogActionType::ModChangeCommunityVisibility),
|
||||
..Default::default()
|
||||
}
|
||||
.list(pool)
|
||||
|
@ -915,23 +929,29 @@ mod tests {
|
|||
// 2 of these, one is jessicas
|
||||
assert_eq!(2, modlog_type_filter.len());
|
||||
|
||||
if let ModlogCombinedView::ModHideCommunity(v) = &modlog_type_filter[0] {
|
||||
assert_eq!(data.community_2.id, v.mod_hide_community.community_id);
|
||||
if let ModlogCombinedView::ModChangeCommunityVisibility(v) = &modlog_type_filter[0] {
|
||||
assert_eq!(
|
||||
data.community_2.id,
|
||||
v.mod_change_community_visibility.community_id
|
||||
);
|
||||
assert_eq!(data.community_2.id, v.community.id);
|
||||
assert_eq!(
|
||||
data.jessica.id,
|
||||
v.admin.as_ref().map(|a| a.id).unwrap_or(PersonId(-1))
|
||||
v.moderator.as_ref().map(|a| a.id).unwrap_or(PersonId(-1))
|
||||
);
|
||||
} else {
|
||||
panic!("wrong type");
|
||||
}
|
||||
|
||||
if let ModlogCombinedView::ModHideCommunity(v) = &modlog_type_filter[1] {
|
||||
assert_eq!(data.community.id, v.mod_hide_community.community_id);
|
||||
if let ModlogCombinedView::ModChangeCommunityVisibility(v) = &modlog_type_filter[1] {
|
||||
assert_eq!(
|
||||
data.community.id,
|
||||
v.mod_change_community_visibility.community_id
|
||||
);
|
||||
assert_eq!(data.community.id, v.community.id);
|
||||
assert_eq!(
|
||||
data.timmy.id,
|
||||
v.admin.as_ref().map(|a| a.id).unwrap_or(PersonId(-1))
|
||||
v.moderator.as_ref().map(|a| a.id).unwrap_or(PersonId(-1))
|
||||
);
|
||||
} else {
|
||||
panic!("wrong type");
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use crate::structs::{
|
||||
CommentView,
|
||||
CommunityView,
|
||||
LocalUserView,
|
||||
PersonView,
|
||||
PostView,
|
||||
SearchCombinedView,
|
||||
SearchCombinedViewInternal,
|
||||
use crate::{
|
||||
structs::{
|
||||
CommentView,
|
||||
CommunityView,
|
||||
LocalUserView,
|
||||
PersonView,
|
||||
PostView,
|
||||
SearchCombinedView,
|
||||
SearchCombinedViewInternal,
|
||||
},
|
||||
utils::{filter_is_subscribed, filter_not_hidden_or_is_subscribed},
|
||||
};
|
||||
use diesel::{
|
||||
dsl::not,
|
||||
|
@ -350,24 +353,19 @@ impl SearchCombinedQuery {
|
|||
};
|
||||
|
||||
// Listing type
|
||||
let is_subscribed = community_actions::followed.is_not_null();
|
||||
match self.listing_type.unwrap_or_default() {
|
||||
ListingType::Subscribed => query = query.filter(is_subscribed),
|
||||
ListingType::Subscribed => query = query.filter(filter_is_subscribed()),
|
||||
ListingType::Local => {
|
||||
query = query.filter(
|
||||
community::local
|
||||
.eq(true)
|
||||
.and(community::hidden.eq(false).or(is_subscribed))
|
||||
.and(filter_not_hidden_or_is_subscribed())
|
||||
.or(search_combined::person_id.is_not_null().and(person::local)),
|
||||
);
|
||||
}
|
||||
ListingType::All => {
|
||||
query = query.filter(
|
||||
community::hidden
|
||||
.eq(false)
|
||||
.or(is_subscribed)
|
||||
.or(search_combined::person_id.is_not_null()),
|
||||
)
|
||||
query = query
|
||||
.filter(filter_not_hidden_or_is_subscribed().or(search_combined::person_id.is_not_null()))
|
||||
}
|
||||
ListingType::ModeratorView => {
|
||||
query = query.filter(community_actions::became_moderator.is_not_null());
|
||||
|
|
|
@ -972,7 +972,6 @@ mod tests {
|
|||
description: None,
|
||||
updated: None,
|
||||
banner: None,
|
||||
hidden: false,
|
||||
posting_restricted_to_mods: false,
|
||||
published: data.inserted_community.published,
|
||||
instance_id: data.inserted_instance.id,
|
||||
|
@ -1012,7 +1011,7 @@ mod tests {
|
|||
pool,
|
||||
data.inserted_community.id,
|
||||
&CommunityUpdateForm {
|
||||
visibility: Some(CommunityVisibility::LocalOnly),
|
||||
visibility: Some(CommunityVisibility::LocalOnlyPrivate),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use crate::structs::{CommunityModeratorView, CommunitySortType, CommunityView, PersonView};
|
||||
use crate::{
|
||||
structs::{CommunityModeratorView, CommunitySortType, CommunityView, PersonView},
|
||||
utils::{filter_is_subscribed, filter_not_hidden_or_is_subscribed},
|
||||
};
|
||||
use diesel::{
|
||||
result::Error,
|
||||
BoolExpressionMethods,
|
||||
|
@ -13,11 +16,7 @@ use lemmy_db_schema::{
|
|||
impls::local_user::LocalUserOptionHelper,
|
||||
newtypes::{CommunityId, PersonId},
|
||||
schema::{community, community_actions, instance_actions, local_user},
|
||||
source::{
|
||||
community::{Community, CommunityFollowerState},
|
||||
local_user::LocalUser,
|
||||
site::Site,
|
||||
},
|
||||
source::{community::Community, local_user::LocalUser, site::Site},
|
||||
utils::{functions::lower, get_conn, limit_and_offset, now, seconds_to_pg_interval, DbPool},
|
||||
ListingType,
|
||||
};
|
||||
|
@ -130,22 +129,18 @@ impl CommunityQuery<'_> {
|
|||
|
||||
// Hide deleted and removed for non-admins or mods
|
||||
if !o.is_mod_or_admin {
|
||||
query = query.filter(Community::hide_removed_and_deleted()).filter(
|
||||
community::hidden
|
||||
.eq(false)
|
||||
.or(community_actions::follow_state.is_not_null()),
|
||||
);
|
||||
query = query
|
||||
.filter(Community::hide_removed_and_deleted())
|
||||
.filter(filter_not_hidden_or_is_subscribed());
|
||||
}
|
||||
|
||||
let is_subscribed = community_actions::follow_state.eq(Some(CommunityFollowerState::Accepted));
|
||||
|
||||
if let Some(listing_type) = o.listing_type {
|
||||
query = match listing_type {
|
||||
ListingType::All => query.filter(community::hidden.eq(false).or(is_subscribed)),
|
||||
ListingType::Subscribed => query.filter(is_subscribed),
|
||||
ListingType::All => query.filter(filter_not_hidden_or_is_subscribed()),
|
||||
ListingType::Subscribed => query.filter(filter_is_subscribed()),
|
||||
ListingType::Local => query
|
||||
.filter(community::local.eq(true))
|
||||
.filter(community::hidden.eq(false).or(is_subscribed)),
|
||||
.filter(filter_not_hidden_or_is_subscribed()),
|
||||
ListingType::ModeratorView => {
|
||||
query.filter(community_actions::became_moderator.is_not_null())
|
||||
}
|
||||
|
@ -386,7 +381,7 @@ mod tests {
|
|||
pool,
|
||||
data.communities[0].id,
|
||||
&CommunityUpdateForm {
|
||||
visibility: Some(CommunityVisibility::LocalOnly),
|
||||
visibility: Some(CommunityVisibility::LocalOnlyPrivate),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
structs::{PostPaginationCursor, PostView},
|
||||
utils::filter_blocked,
|
||||
utils::{filter_blocked, filter_is_subscribed, filter_not_hidden_or_is_subscribed},
|
||||
};
|
||||
use diesel::{
|
||||
debug_query,
|
||||
|
@ -460,15 +460,14 @@ impl<'a> PostQuery<'a> {
|
|||
query = query.filter(post::creator_id.eq(creator_id));
|
||||
}
|
||||
|
||||
let is_subscribed = community_actions::followed.is_not_null();
|
||||
match o.listing_type.unwrap_or_default() {
|
||||
ListingType::Subscribed => query = query.filter(is_subscribed),
|
||||
ListingType::Subscribed => query = query.filter(filter_is_subscribed()),
|
||||
ListingType::Local => {
|
||||
query = query
|
||||
.filter(community::local.eq(true))
|
||||
.filter(community::hidden.eq(false).or(is_subscribed));
|
||||
.filter(filter_not_hidden_or_is_subscribed());
|
||||
}
|
||||
ListingType::All => query = query.filter(community::hidden.eq(false).or(is_subscribed)),
|
||||
ListingType::All => query = query.filter(filter_not_hidden_or_is_subscribed()),
|
||||
ListingType::ModeratorView => {
|
||||
query = query.filter(community_actions::became_moderator.is_not_null());
|
||||
}
|
||||
|
@ -1564,7 +1563,7 @@ mod tests {
|
|||
pool,
|
||||
data.community.id,
|
||||
&CommunityUpdateForm {
|
||||
hidden: Some(true),
|
||||
visibility: Some(CommunityVisibility::Unlisted),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -2010,7 +2009,6 @@ mod tests {
|
|||
description: None,
|
||||
updated: None,
|
||||
banner: None,
|
||||
hidden: false,
|
||||
posting_restricted_to_mods: false,
|
||||
published: inserted_community.published,
|
||||
instance_id: data.instance.id,
|
||||
|
@ -2056,7 +2054,7 @@ mod tests {
|
|||
pool,
|
||||
data.community.id,
|
||||
&CommunityUpdateForm {
|
||||
visibility: Some(CommunityVisibility::LocalOnly),
|
||||
visibility: Some(CommunityVisibility::LocalOnlyPrivate),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
|
|
@ -53,8 +53,8 @@ use lemmy_db_schema::{
|
|||
ModAddCommunity,
|
||||
ModBan,
|
||||
ModBanFromCommunity,
|
||||
ModChangeCommunityVisibility,
|
||||
ModFeaturePost,
|
||||
ModHideCommunity,
|
||||
ModLockPost,
|
||||
ModRemoveComment,
|
||||
ModRemoveCommunity,
|
||||
|
@ -867,11 +867,11 @@ pub struct ModBanView {
|
|||
#[cfg_attr(feature = "full", derive(TS, Queryable))]
|
||||
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||
#[cfg_attr(feature = "full", ts(export))]
|
||||
/// When a community is hidden from public view.
|
||||
pub struct ModHideCommunityView {
|
||||
pub mod_hide_community: ModHideCommunity,
|
||||
/// When the visibility of a community is changed
|
||||
pub struct ModChangeCommunityVisibilityView {
|
||||
pub mod_change_community_visibility: ModChangeCommunityVisibility,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub admin: Option<Person>,
|
||||
pub moderator: Option<Person>,
|
||||
pub community: Community,
|
||||
}
|
||||
|
||||
|
@ -1068,7 +1068,7 @@ pub(crate) struct ModlogCombinedViewInternal {
|
|||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub mod_feature_post: Option<ModFeaturePost>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub mod_hide_community: Option<ModHideCommunity>,
|
||||
pub mod_change_community_visibility: Option<ModChangeCommunityVisibility>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
pub mod_lock_post: Option<ModLockPost>,
|
||||
#[cfg_attr(feature = "full", diesel(embed))]
|
||||
|
@ -1118,7 +1118,7 @@ pub enum ModlogCombinedView {
|
|||
ModBan(ModBanView),
|
||||
ModBanFromCommunity(ModBanFromCommunityView),
|
||||
ModFeaturePost(ModFeaturePostView),
|
||||
ModHideCommunity(ModHideCommunityView),
|
||||
ModChangeCommunityVisibility(ModChangeCommunityVisibilityView),
|
||||
ModLockPost(ModLockPostView),
|
||||
ModRemoveComment(ModRemoveCommentView),
|
||||
ModRemoveCommunity(ModRemoveCommunityView),
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
use diesel::{BoolExpressionMethods, ExpressionMethods};
|
||||
use lemmy_db_schema::schema::{community_actions, instance_actions, person_actions};
|
||||
use diesel::{
|
||||
helper_types::{Eq, NotEq, Or},
|
||||
BoolExpressionMethods,
|
||||
ExpressionMethods,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
schema::{community, community_actions, instance_actions, person_actions},
|
||||
source::community::CommunityFollowerState,
|
||||
CommunityVisibility,
|
||||
};
|
||||
|
||||
/// Hide all content from blocked communities and persons. Content from blocked instances is also
|
||||
/// hidden, unless the user followed the community explicitly.
|
||||
|
@ -11,3 +19,17 @@ pub(crate) fn filter_blocked() -> _ {
|
|||
.and(community_actions::blocked.is_null())
|
||||
.and(person_actions::blocked.is_null())
|
||||
}
|
||||
|
||||
type IsSubscribedType =
|
||||
Eq<lemmy_db_schema::schema::community_actions::follow_state, Option<CommunityFollowerState>>;
|
||||
|
||||
pub(crate) fn filter_is_subscribed() -> IsSubscribedType {
|
||||
community_actions::follow_state.eq(Some(CommunityFollowerState::Accepted))
|
||||
}
|
||||
|
||||
type IsNotHiddenType = NotEq<lemmy_db_schema::schema::community::visibility, CommunityVisibility>;
|
||||
|
||||
pub(crate) fn filter_not_hidden_or_is_subscribed() -> Or<IsNotHiddenType, IsSubscribedType> {
|
||||
let not_hidden = community::visibility.ne(CommunityVisibility::Unlisted);
|
||||
not_hidden.or(filter_is_subscribed())
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use lemmy_api_common::{
|
|||
use lemmy_db_schema::{
|
||||
source::{community::Community, person::Person},
|
||||
traits::ApubActor,
|
||||
CommunityVisibility,
|
||||
ListingType,
|
||||
PostSortType,
|
||||
};
|
||||
|
@ -274,7 +273,7 @@ async fn get_feed_community(
|
|||
let community = Community::read_from_name(&mut context.pool(), community_name, false)
|
||||
.await?
|
||||
.ok_or(LemmyErrorType::NotFound)?;
|
||||
if community.visibility != CommunityVisibility::Public {
|
||||
if !community.visibility.can_view_without_login() {
|
||||
return Err(LemmyErrorType::NotFound.into());
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ use lemmy_api_common::{context::LemmyContext, LemmyErrorType};
|
|||
use lemmy_db_schema::{
|
||||
source::{community::Community, person::Person},
|
||||
traits::ApubActor,
|
||||
CommunityVisibility,
|
||||
};
|
||||
use lemmy_utils::{
|
||||
cache_header::cache_3days,
|
||||
|
@ -57,7 +56,7 @@ async fn get_webfinger_response(
|
|||
.ok()
|
||||
.flatten()
|
||||
.and_then(|c| {
|
||||
if c.visibility == CommunityVisibility::Public {
|
||||
if c.visibility.can_federate() {
|
||||
let id: Url = c.ap_id.into();
|
||||
Some(id)
|
||||
} else {
|
||||
|
|
|
@ -98,7 +98,6 @@ pub enum LemmyErrorType {
|
|||
CommunityUserAlreadyBanned,
|
||||
CommunityBlockAlreadyExists,
|
||||
CommunityFollowerAlreadyExists,
|
||||
CouldntUpdateCommunityHiddenStatus,
|
||||
PersonBlockAlreadyExists,
|
||||
UserAlreadyExists,
|
||||
CouldntLikePost,
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
-- recreate columns in the original order
|
||||
ALTER TABLE community
|
||||
ADD COLUMN hidden bool DEFAULT FALSE NOT NULL,
|
||||
ADD COLUMN posting_restricted_to_mods_new bool NOT NULL DEFAULT FALSE,
|
||||
ADD COLUMN instance_id_new int NOT NULL,
|
||||
ADD COLUMN moderators_url_new varchar(255),
|
||||
ADD COLUMN featured_url_new varchar(255),
|
||||
ADD COLUMN visibility_new community_visibility NOT NULL DEFAULT 'Public',
|
||||
ADD COLUMN description_new varchar(150),
|
||||
ADD COLUMN random_number_new smallint NOT NULL DEFAULT random_smallint (),
|
||||
ADD COLUMN subscribers_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN posts_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN comments_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_day_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_week_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_month_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN users_active_half_year_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN hot_rank_new double precision NOT NULL DEFAULT 0.0001,
|
||||
ADD COLUMN subscribers_local_new bigint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN report_count_new smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN unresolved_report_count_new smallint NOT NULL DEFAULT 0,
|
||||
ADD COLUMN interactions_month_new bigint NOT NULL DEFAULT 0;
|
||||
|
||||
UPDATE
|
||||
community
|
||||
SET
|
||||
(posting_restricted_to_mods_new,
|
||||
instance_id_new,
|
||||
moderators_url_new,
|
||||
featured_url_new,
|
||||
visibility_new,
|
||||
description_new,
|
||||
random_number_new,
|
||||
subscribers_new,
|
||||
posts_new,
|
||||
comments_new,
|
||||
users_active_day_new,
|
||||
users_active_week_new,
|
||||
users_active_month_new,
|
||||
users_active_half_year_new,
|
||||
hot_rank_new,
|
||||
subscribers_local_new,
|
||||
report_count_new,
|
||||
unresolved_report_count_new,
|
||||
interactions_month_new) = (posting_restricted_to_mods,
|
||||
instance_id,
|
||||
moderators_url,
|
||||
featured_url,
|
||||
visibility,
|
||||
description,
|
||||
random_number,
|
||||
subscribers,
|
||||
posts,
|
||||
comments,
|
||||
users_active_day,
|
||||
users_active_week,
|
||||
users_active_month,
|
||||
users_active_half_year,
|
||||
hot_rank,
|
||||
subscribers_local,
|
||||
report_count,
|
||||
unresolved_report_count,
|
||||
interactions_month);
|
||||
|
||||
ALTER TABLE community
|
||||
DROP COLUMN posting_restricted_to_mods,
|
||||
DROP COLUMN instance_id,
|
||||
DROP COLUMN moderators_url,
|
||||
DROP COLUMN featured_url,
|
||||
DROP COLUMN visibility,
|
||||
DROP COLUMN description,
|
||||
DROP COLUMN random_number,
|
||||
DROP COLUMN subscribers,
|
||||
DROP COLUMN posts,
|
||||
DROP COLUMN comments,
|
||||
DROP COLUMN users_active_day,
|
||||
DROP COLUMN users_active_week,
|
||||
DROP COLUMN users_active_month,
|
||||
DROP COLUMN users_active_half_year,
|
||||
DROP COLUMN hot_rank,
|
||||
DROP COLUMN subscribers_local,
|
||||
DROP COLUMN report_count,
|
||||
DROP COLUMN unresolved_report_count,
|
||||
DROP COLUMN interactions_month;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN posting_restricted_to_mods_new TO posting_restricted_to_mods;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN instance_id_new TO instance_id;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN moderators_url_new TO moderators_url;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN featured_url_new TO featured_url;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN visibility_new TO visibility;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN description_new TO description;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN random_number_new TO random_number;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN subscribers_new TO subscribers;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN posts_new TO posts;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN comments_new TO comments;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN users_active_day_new TO users_active_day;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN users_active_week_new TO users_active_week;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN users_active_month_new TO users_active_month;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN users_active_half_year_new TO users_active_half_year;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN hot_rank_new TO hot_rank;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN subscribers_local_new TO subscribers_local;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN report_count_new TO report_count;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN unresolved_report_count_new TO unresolved_report_count;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN interactions_month_new TO interactions_month;
|
||||
|
||||
ALTER TABLE community
|
||||
ADD CONSTRAINT community_featured_url_key UNIQUE (featured_url),
|
||||
ADD CONSTRAINT community_moderators_url_key UNIQUE (moderators_url),
|
||||
ADD CONSTRAINT community_instance_id_fkey FOREIGN KEY (instance_id) REFERENCES instance (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
-- same changes as up.sql, but the other way round
|
||||
UPDATE
|
||||
community
|
||||
SET
|
||||
(hidden,
|
||||
visibility) = (TRUE,
|
||||
'Public')
|
||||
WHERE
|
||||
visibility = 'Unlisted';
|
||||
|
||||
ALTER TYPE community_visibility RENAME VALUE 'LocalOnlyPrivate' TO 'LocalOnly';
|
||||
|
||||
ALTER TYPE community_visibility RENAME TO community_visibility__;
|
||||
|
||||
CREATE TYPE community_visibility AS enum (
|
||||
'Public',
|
||||
'LocalOnly',
|
||||
'Private'
|
||||
);
|
||||
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN visibility DROP DEFAULT;
|
||||
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN visibility TYPE community_visibility
|
||||
USING visibility::text::community_visibility;
|
||||
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN visibility SET DEFAULT 'Public';
|
||||
|
||||
CREATE INDEX idx_community_random_number ON community (random_number) INCLUDE (local, nsfw)
|
||||
WHERE
|
||||
NOT (deleted OR removed OR visibility = 'Private');
|
||||
|
||||
CREATE INDEX idx_community_nonzero_hotrank ON community USING btree (published)
|
||||
WHERE (hot_rank <> (0)::double precision);
|
||||
|
||||
CREATE INDEX idx_community_subscribers ON community USING btree (subscribers DESC);
|
||||
|
||||
CREATE INDEX idx_community_users_active_month ON community USING btree (users_active_month DESC);
|
||||
|
||||
CREATE INDEX idx_community_hot ON public.community USING btree (hot_rank DESC);
|
||||
|
||||
REINDEX TABLE community;
|
||||
|
||||
-- revert modlog table changes
|
||||
CREATE TABLE mod_hide_community (
|
||||
id serial PRIMARY KEY,
|
||||
community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
mod_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
published timestamptz NOT NULL DEFAULT now(),
|
||||
reason text,
|
||||
hidden boolean DEFAULT FALSE NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE modlog_combined
|
||||
DROP COLUMN mod_change_community_visibility_id,
|
||||
ADD COLUMN mod_hide_community_id int REFERENCES mod_hide_community ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD COLUMN mod_lock_post_id_new int,
|
||||
ADD COLUMN mod_remove_comment_id_new int,
|
||||
ADD COLUMN mod_remove_community_id_new int,
|
||||
ADD COLUMN mod_remove_post_id_new int,
|
||||
ADD COLUMN mod_transfer_community_id_new int;
|
||||
|
||||
UPDATE
|
||||
modlog_combined
|
||||
SET
|
||||
(mod_lock_post_id_new,
|
||||
mod_remove_comment_id_new,
|
||||
mod_remove_community_id_new,
|
||||
mod_remove_post_id_new,
|
||||
mod_transfer_community_id_new) = (mod_lock_post_id,
|
||||
mod_remove_comment_id,
|
||||
mod_remove_community_id,
|
||||
mod_remove_post_id,
|
||||
mod_transfer_community_id);
|
||||
|
||||
ALTER TABLE modlog_combined
|
||||
DROP COLUMN mod_lock_post_id,
|
||||
DROP COLUMN mod_remove_comment_id,
|
||||
DROP COLUMN mod_remove_community_id,
|
||||
DROP COLUMN mod_remove_post_id,
|
||||
DROP COLUMN mod_transfer_community_id;
|
||||
|
||||
ALTER TABLE modlog_combined RENAME COLUMN mod_lock_post_id_new TO mod_lock_post_id;
|
||||
|
||||
ALTER TABLE modlog_combined RENAME COLUMN mod_remove_comment_id_new TO mod_remove_comment_id;
|
||||
|
||||
ALTER TABLE modlog_combined RENAME COLUMN mod_remove_community_id_new TO mod_remove_community_id;
|
||||
|
||||
ALTER TABLE modlog_combined RENAME COLUMN mod_remove_post_id_new TO mod_remove_post_id;
|
||||
|
||||
ALTER TABLE modlog_combined RENAME COLUMN mod_transfer_community_id_new TO mod_transfer_community_id;
|
||||
|
||||
ALTER TABLE modlog_combined
|
||||
ADD CONSTRAINT modlog_combined_mod_hide_community_id_key UNIQUE (mod_hide_community_id),
|
||||
ADD CONSTRAINT modlog_combined_mod_lock_post_id_key UNIQUE (mod_lock_post_id),
|
||||
ADD CONSTRAINT modlog_combined_mod_remove_comment_id_key UNIQUE (mod_remove_comment_id),
|
||||
ADD CONSTRAINT modlog_combined_mod_remove_community_id_key UNIQUE (mod_remove_community_id),
|
||||
ADD CONSTRAINT modlog_combined_mod_remove_post_id_key UNIQUE (mod_remove_post_id),
|
||||
ADD CONSTRAINT modlog_combined_mod_transfer_community_id_key UNIQUE (mod_transfer_community_id),
|
||||
ADD CONSTRAINT modlog_combined_mod_lock_post_id_fkey FOREIGN KEY (mod_lock_post_id) REFERENCES mod_lock_post (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT modlog_combined_mod_remove_comment_id_fkey FOREIGN KEY (mod_remove_comment_id) REFERENCES mod_remove_comment (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT modlog_combined_mod_remove_community_id_fkey FOREIGN KEY (mod_remove_community_id) REFERENCES mod_remove_community (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT modlog_combined_mod_remove_post_id_fkey FOREIGN KEY (mod_remove_post_id) REFERENCES mod_remove_post (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT modlog_combined_mod_transfer_community_id_fkey FOREIGN KEY (mod_transfer_community_id) REFERENCES mod_transfer_community (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT modlog_combined_check CHECK ((num_nonnulls (admin_allow_instance_id, admin_block_instance_id, admin_purge_comment_id, admin_purge_community_id, admin_purge_person_id, admin_purge_post_id, mod_add_id, mod_add_community_id, mod_ban_id, mod_ban_from_community_id, mod_feature_post_id, mod_hide_community_id, mod_lock_post_id, mod_remove_comment_id, mod_remove_community_id, mod_remove_post_id, mod_transfer_community_id) = 1));
|
||||
|
||||
DROP TABLE mod_change_community_visibility;
|
||||
|
||||
DROP TYPE community_visibility__;
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
-- Change community.visibility to allow values:
|
||||
-- ('Public', 'LocalOnlyPublic', 'LocalOnlyPrivate','Private', 'Hidden')
|
||||
-- rename old enum and add new one
|
||||
ALTER TYPE community_visibility RENAME TO community_visibility__;
|
||||
|
||||
CREATE TYPE community_visibility AS enum (
|
||||
'Public',
|
||||
'LocalOnlyPublic',
|
||||
'LocalOnly',
|
||||
'Private',
|
||||
'Unlisted'
|
||||
);
|
||||
|
||||
-- drop default value and index which reference old enum
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN visibility DROP DEFAULT;
|
||||
|
||||
DROP INDEX idx_community_random_number;
|
||||
|
||||
-- change the column type
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN visibility TYPE community_visibility
|
||||
USING visibility::text::community_visibility;
|
||||
|
||||
-- add default and index back in
|
||||
ALTER TABLE community
|
||||
ALTER COLUMN visibility SET DEFAULT 'Public';
|
||||
|
||||
CREATE INDEX idx_community_random_number ON community (random_number) INCLUDE (local, nsfw)
|
||||
WHERE
|
||||
NOT (deleted OR removed OR visibility = 'Private' OR visibility = 'Unlisted');
|
||||
|
||||
DROP TYPE community_visibility__ CASCADE;
|
||||
|
||||
ALTER TYPE community_visibility RENAME VALUE 'LocalOnly' TO 'LocalOnlyPrivate';
|
||||
|
||||
-- write hidden value to visibility column
|
||||
UPDATE
|
||||
community
|
||||
SET
|
||||
visibility = 'Unlisted'
|
||||
WHERE
|
||||
hidden;
|
||||
|
||||
-- drop the old hidden column
|
||||
ALTER TABLE community
|
||||
DROP COLUMN hidden;
|
||||
|
||||
-- change modlog tables
|
||||
ALTER TABLE modlog_combined
|
||||
DROP COLUMN mod_hide_community_id;
|
||||
|
||||
DROP TABLE mod_hide_community;
|
||||
|
||||
CREATE TABLE mod_change_community_visibility (
|
||||
id serial PRIMARY KEY,
|
||||
community_id int REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
mod_person_id int REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||
published timestamptz NOT NULL DEFAULT now(),
|
||||
reason text,
|
||||
visibility community_visibility NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE modlog_combined
|
||||
ADD COLUMN mod_change_community_visibility_id int REFERENCES mod_change_community_visibility (id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
ADD CONSTRAINT modlog_combined_check CHECK ((num_nonnulls (admin_allow_instance_id, admin_block_instance_id, admin_purge_comment_id, admin_purge_community_id, admin_purge_person_id, admin_purge_post_id, mod_add_id, mod_add_community_id, mod_ban_id, mod_ban_from_community_id, mod_feature_post_id, mod_change_community_visibility_id, mod_lock_post_id, mod_remove_comment_id, mod_remove_community_id, mod_remove_post_id, mod_transfer_community_id) = 1));
|
||||
|
|
@ -11,7 +11,6 @@ use lemmy_api::{
|
|||
ban::ban_from_community,
|
||||
block::user_block_community,
|
||||
follow::follow_community,
|
||||
hide::hide_community,
|
||||
transfer::transfer_community,
|
||||
},
|
||||
local_user::{
|
||||
|
@ -184,7 +183,6 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_community))
|
||||
.route("", put().to(update_community))
|
||||
.route("/hide", put().to(hide_community))
|
||||
.route("/list", get().to(list_communities))
|
||||
.route("/follow", post().to(follow_community))
|
||||
.route("/block", post().to(user_block_community))
|
||||
|
|
|
@ -11,7 +11,6 @@ use lemmy_api::{
|
|||
ban::ban_from_community,
|
||||
block::user_block_community,
|
||||
follow::follow_community,
|
||||
hide::hide_community,
|
||||
pending_follows::{
|
||||
approve::post_pending_follows_approve,
|
||||
count::get_pending_follows_count,
|
||||
|
@ -215,7 +214,6 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
.route("", get().to(get_community))
|
||||
.route("", put().to(update_community))
|
||||
.route("/random", get().to(get_random_community))
|
||||
.route("/hide", put().to(hide_community))
|
||||
.route("/list", get().to(list_communities))
|
||||
.route("/follow", post().to(follow_community))
|
||||
.route("/report", post().to(create_community_report))
|
||||
|
|
Loading…
Reference in a new issue