Skip to content

Commit

Permalink
update moderator view (#3820)
Browse files Browse the repository at this point in the history
* update api tests for new moderator view

* chage moderator view to be a listing type in get posts

Note: Internally, the listing type is called ListingType.ModeratorView,
but it's called "Moderator View" in the api endpoint

* fix formatting

* add support for moderator view to list comments

* add api test for moderator view when listing comments

* fix api test formatting

* retry tests

* don't filter out blocked users and communities when using moderator view

* fix cargo tests failing

* fix formatting

* fix previous merge

* Adding ModeratorView to listing_type_enums

* Fixing fmt.

* Adding a default to ListingType.

* Upgrading to use new lemmy-js-client.

---------

Co-authored-by: Nutomic <me@nutomic.com>
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: Dessalines <tyhou13@gmx.com>
  • Loading branch information
4 people authored Aug 31, 2023
1 parent c93bde9 commit 384e55f
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 30 deletions.
2 changes: 1 addition & 1 deletion api_tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"eslint": "^8.40.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^29.5.0",
"lemmy-js-client": "0.19.0-rc.2",
"lemmy-js-client": "0.19.0-rc.3",
"prettier": "^3.0.0",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4"
Expand Down
42 changes: 39 additions & 3 deletions api_tests/src/community.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
registerUser,
API,
getPosts,
getComments,
createComment,
getCommunityByName,
} from "./shared";

Expand Down Expand Up @@ -245,40 +247,74 @@ test("moderator view", async () => {
client: alpha.client,
};
expect(otherUser.auth).not.toBe("");

let otherCommunity = (await createCommunity(otherUser)).community_view;
expect(otherCommunity.community.name).toBeDefined();
let otherPost = (await createPost(otherUser, otherCommunity.community.id))
.post_view;
expect(otherPost.post.id).toBeDefined();

let otherComment = (await createComment(otherUser, otherPost.post.id))
.comment_view;
expect(otherComment.comment.id).toBeDefined();

// create a community and post on alpha
let alphaCommunity = (await createCommunity(alpha)).community_view;
expect(alphaCommunity.community.name).toBeDefined();
let alphaPost = (await createPost(alpha, alphaCommunity.community.id))
.post_view;
expect(alphaPost.post.id).toBeDefined();

let alphaComment = (await createComment(otherUser, alphaPost.post.id))
.comment_view;
expect(alphaComment.comment.id).toBeDefined();

// other user also posts on alpha's community
let otherAlphaPost = (
await createPost(otherUser, alphaCommunity.community.id)
).post_view;
expect(otherAlphaPost.post.id).toBeDefined();

// alpha lists posts on home page, should contain all posts that were made
let posts = (await getPosts(alpha)).posts;
let otherAlphaComment = (
await createComment(otherUser, otherAlphaPost.post.id)
).comment_view;
expect(otherAlphaComment.comment.id).toBeDefined();

// alpha lists posts and comments on home page, should contain all posts that were made
let posts = (await getPosts(alpha, "All")).posts;
expect(posts).toBeDefined();
let postIds = posts.map(post => post.post.id);

let comments = (await getComments(alpha, undefined, "All")).comments;
expect(comments).toBeDefined();
let commentIds = comments.map(comment => comment.comment.id);

expect(postIds).toContain(otherPost.post.id);
expect(commentIds).toContain(otherComment.comment.id);

expect(postIds).toContain(alphaPost.post.id);
expect(commentIds).toContain(alphaComment.comment.id);

expect(postIds).toContain(otherAlphaPost.post.id);
expect(commentIds).toContain(otherAlphaComment.comment.id);

// in moderator view, alpha should not see otherPost, wich was posted on a community alpha doesn't moderate
posts = (await getPosts(alpha, true)).posts;
posts = (await getPosts(alpha, "ModeratorView")).posts;
expect(posts).toBeDefined();
postIds = posts.map(post => post.post.id);

comments = (await getComments(alpha, undefined, "ModeratorView")).comments;
expect(comments).toBeDefined();
commentIds = comments.map(comment => comment.comment.id);

expect(postIds).not.toContain(otherPost.post.id);
expect(commentIds).not.toContain(otherComment.comment.id);

expect(postIds).toContain(alphaPost.post.id);
expect(commentIds).toContain(alphaComment.comment.id);

expect(postIds).toContain(otherAlphaPost.post.id);
expect(commentIds).toContain(otherAlphaComment.comment.id);
});

test("Get community for different casing on domain", async () => {
Expand Down
15 changes: 9 additions & 6 deletions api_tests/src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
GetUnreadCount,
GetUnreadCountResponse,
LemmyHttp,
LocalUser,
} from "lemmy-js-client";
import { CreatePost } from "lemmy-js-client/dist/types/CreatePost";
import { DeletePost } from "lemmy-js-client/dist/types/DeletePost";
Expand Down Expand Up @@ -69,6 +68,7 @@ import { GetPostsResponse } from "lemmy-js-client/dist/types/GetPostsResponse";
import { GetPosts } from "lemmy-js-client/dist/types/GetPosts";
import { GetPersonDetailsResponse } from "lemmy-js-client/dist/types/GetPersonDetailsResponse";
import { GetPersonDetails } from "lemmy-js-client/dist/types/GetPersonDetails";
import { ListingType } from "lemmy-js-client/dist/types/ListingType";

export interface API {
client: LemmyHttp;
Expand Down Expand Up @@ -201,7 +201,9 @@ export async function setupLogins() {
try {
await createCommunity(alpha, "main");
await createCommunity(beta, "main");
} catch (_) {}
} catch (_) {
console.log("Communities already exist");
}
}

export async function createPost(
Expand Down Expand Up @@ -321,11 +323,12 @@ export async function getPost(

export async function getComments(
api: API,
post_id: number,
post_id?: number,
listingType: ListingType = "All",
): Promise<GetCommentsResponse> {
let form: GetComments = {
post_id: post_id,
type_: "All",
type_: listingType,
sort: "New",
auth: api.auth,
};
Expand Down Expand Up @@ -798,11 +801,11 @@ export async function listCommentReports(

export function getPosts(
api: API,
moderator_view = false,
listingType?: ListingType,
): Promise<GetPostsResponse> {
let form: GetPosts = {
moderator_view,
auth: api.auth,
type_: listingType,
};
return api.client.getPosts(form);
}
Expand Down
2 changes: 1 addition & 1 deletion api_tests/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"noImplicitAny": true,
"lib": ["es2017", "es7", "es6", "dom"],
"outDir": "./dist",
"target": "ES5",
"target": "ES2015",
"strictNullChecks": true,
"moduleResolution": "Node"
},
Expand Down
8 changes: 4 additions & 4 deletions api_tests/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2174,10 +2174,10 @@ kleur@^3.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==

lemmy-js-client@0.19.0-rc.2:
version "0.19.0-rc.2"
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-rc.2.tgz#c3cb511b27f92538909a2b91a0f8527b1abad958"
integrity sha512-FXuf8s7bpBVkHL/OGWDb/0aGIrJ7uv3d4Xt1h6zmNDhw6MmmuD8RXgCHiS2jqhxjAEp96Dpl1NFXbpmKpix7tQ==
lemmy-js-client@0.19.0-rc.3:
version "0.19.0-rc.3"
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-rc.3.tgz#1efbfd5ce492319227a41cb020fc1cf9b2e7c075"
integrity sha512-RmibQ3+YTvqsQ89II2I29pfPmVAWiSObGAU9Nc/AGYfyvaCya7f5+TirKwHdKA2eWDWLOTnD4rm6WgcgAwvhWw==
dependencies:
cross-fetch "^3.1.5"
form-data "^4.0.0"
Expand Down
1 change: 0 additions & 1 deletion crates/api_common/src/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ pub struct GetPosts {
pub saved_only: Option<bool>,
pub liked_only: Option<bool>,
pub disliked_only: Option<bool>,
pub moderator_view: Option<bool>,
pub auth: Option<Sensitive<String>>,
}

Expand Down
3 changes: 0 additions & 3 deletions crates/apub/src/api/list_posts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ pub async fn list_posts(
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
}

let moderator_view = data.moderator_view.unwrap_or_default();

let listing_type = Some(listing_type_with_default(
data.type_,
&local_site,
Expand All @@ -59,7 +57,6 @@ pub async fn list_posts(
saved_only,
liked_only,
disliked_only,
moderator_view,
page,
limit,
..Default::default()
Expand Down
12 changes: 10 additions & 2 deletions crates/db_schema/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ use strum_macros::{Display, EnumString};
#[cfg(feature = "full")]
use ts_rs::TS;

#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
#[derive(
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default,
)]
#[cfg_attr(feature = "full", derive(DbEnum, TS))]
#[cfg_attr(
feature = "full",
Expand All @@ -54,6 +56,7 @@ use ts_rs::TS;
#[cfg_attr(feature = "full", ts(export))]
/// The post sort types. See here for descriptions: https://join-lemmy.org/docs/en/users/03-votes-and-ranking.html
pub enum SortType {
#[default]
Active,
Hot,
New,
Expand Down Expand Up @@ -99,7 +102,9 @@ pub enum PersonSortType {
PostCount,
}

#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
#[derive(
EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default,
)]
#[cfg_attr(feature = "full", derive(DbEnum, TS))]
#[cfg_attr(
feature = "full",
Expand All @@ -112,9 +117,12 @@ pub enum ListingType {
/// Content from your own site, as well as all connected / federated sites.
All,
/// Content from your site only.
#[default]
Local,
/// Content only from communities you've subscribed to.
Subscribed,
/// Content that you can moderate (because you are a moderator of the community it is posted to)
ModeratorView,
}

#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
Expand Down
16 changes: 15 additions & 1 deletion crates/db_views/src/comment_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use lemmy_db_schema::{
community,
community_block,
community_follower,
community_moderator,
community_person_ban,
local_user_language,
person,
Expand Down Expand Up @@ -101,6 +102,14 @@ fn queries<'a>() -> Queries<
.and(comment_like::person_id.eq(person_id_join)),
),
)
.left_join(
community_moderator::table.on(
post::id
.eq(comment::post_id)
.and(post::community_id.eq(community_moderator::community_id))
.and(community_moderator::person_id.eq(person_id_join)),
),
)
};

let selection = (
Expand Down Expand Up @@ -186,6 +195,9 @@ fn queries<'a>() -> Queries<
.or(community_follower::person_id.eq(person_id_join)),
)
}
ListingType::ModeratorView => {
query = query.filter(community_moderator::person_id.is_not_null());
}
}
}

Expand Down Expand Up @@ -222,7 +234,9 @@ fn queries<'a>() -> Queries<
query = query.filter(person::bot_account.eq(false));
};

if options.local_user.is_some() {
if options.local_user.is_some()
&& options.listing_type.unwrap_or_default() != ListingType::ModeratorView
{
// Filter out the rows with missing languages
query = query.filter(local_user_language::language_id.is_not_null());

Expand Down
16 changes: 8 additions & 8 deletions crates/db_views/src/post_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ fn queries<'a>() -> Queries<
.or(community_follower::person_id.eq(person_id_join)),
)
}
ListingType::ModeratorView => {
query = query.filter(community_moderator::person_id.is_not_null());
}
}
}

Expand Down Expand Up @@ -295,10 +298,6 @@ fn queries<'a>() -> Queries<
if options.saved_only {
query = query.filter(post_saved::id.is_not_null());
}

if options.moderator_view {
query = query.filter(community_moderator::person_id.is_not_null());
}
// Only hide the read posts, if the saved_only is false. Otherwise ppl with the hide_read
// setting wont be able to see saved posts.
else if !options
Expand All @@ -318,15 +317,16 @@ fn queries<'a>() -> Queries<
query = query.filter(post_like::score.eq(-1));
}

if options.local_user.is_some() {
// Dont filter blocks or missing languages for moderator view type
if options.local_user.is_some()
&& options.listing_type.unwrap_or_default() != ListingType::ModeratorView
{
// Filter out the rows with missing languages
query = query.filter(local_user_language::language_id.is_not_null());

// Don't show blocked communities or persons
query = query.filter(community_block::person_id.is_null());
if !options.moderator_view {
query = query.filter(person_block::person_id.is_null());
}
query = query.filter(person_block::person_id.is_null());
}
let now = diesel::dsl::now.into_sql::<Timestamptz>();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
ALTER TABLE local_user
ALTER default_listing_type DROP DEFAULT;

ALTER TABLE local_site
ALTER default_post_listing_type DROP DEFAULT;

UPDATE
local_user
SET
default_listing_type = 'Local'
WHERE
default_listing_type = 'ModeratorView';

UPDATE
local_site
SET
default_post_listing_type = 'Local'
WHERE
default_post_listing_type = 'ModeratorView';

-- rename the old enum
ALTER TYPE listing_type_enum RENAME TO listing_type_enum__;

-- create the new enum
CREATE TYPE listing_type_enum AS ENUM (
'All',
'Local',
'Subscribed'
);

-- alter all your enum columns
ALTER TABLE local_user
ALTER COLUMN default_listing_type TYPE listing_type_enum
USING default_listing_type::text::listing_type_enum;

ALTER TABLE local_site
ALTER COLUMN default_post_listing_type TYPE listing_type_enum
USING default_post_listing_type::text::listing_type_enum;

-- Add back in the default
ALTER TABLE local_user
ALTER default_listing_type SET DEFAULT 'Local';

ALTER TABLE local_site
ALTER default_post_listing_type SET DEFAULT 'Local';

-- drop the old enum
DROP TYPE listing_type_enum__;

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Update the listing_type_enum
ALTER TYPE listing_type_enum
ADD VALUE 'ModeratorView';

0 comments on commit 384e55f

Please sign in to comment.