Skip to content

Commit

Permalink
feat: add a way to get subreddit contributors
Browse files Browse the repository at this point in the history
Actually closes thislooksfun#49 this time.
  • Loading branch information
thislooksfun committed Mar 27, 2022
1 parent c394254 commit b0f7cef
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/reddit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export { Subreddit } from "./subreddit/object";
export type { SubredditType } from "./subreddit/types";
export type { SearchSort, SearchSyntax, Size, TimeRange } from "./types";
export { UserControls } from "./user/controls";
export type { ModeratorActionedUserData } from "./user/moderator-actioned/base";
export { ModeratorActionedUser } from "./user/moderator-actioned/base";
export type { UserData } from "./user/object/base-object";
export { User } from "./user/object/base-object";
export type { MyUserData } from "./user/object/my-user";
Expand Down
19 changes: 19 additions & 0 deletions src/reddit/subreddit/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import type {
SearchSyntax,
TimeRange,
} from "../types";
import type { ModeratorActionedUser } from "../user/moderator-actioned/base";
import type { SubredditData } from "./object";

import { BaseControls } from "../base-controls";
import { CommentListing } from "../comment/listing/listing";
import { fakeListingAfter } from "../listing/util";
import { PostListing } from "../post/listing";
import { PostOrCommentListing } from "../post-or-comment/listing";
import { ModeratorActionedUserListing } from "../user/moderator-actioned/base";
import { assertKind, fromRedditData } from "../util";
import { Subreddit } from "./object";

Expand Down Expand Up @@ -157,6 +159,23 @@ export class SubredditControls extends BaseControls {
await this.gateway.post("api/leavecontributor", { id: subredditId });
}

/**
* Get the list of approved contributors for a subreddit.
*
* @note Due to the way Reddit implements Listings, this will only contain the
* first 1000 contributors.
*
* @param subreddit The name of the subreddit to get contributors for.
*
* @returns A listing of approved contributors.
*/
getContributors(subreddit: string): Listing<ModeratorActionedUser> {
return new ModeratorActionedUserListing(fakeListingAfter(""), {
request: { url: `r/${subreddit}/about/contributors`, query: {} },
client: this.client,
});
}

/**
* Add a user to the list of approved wiki editors.
*
Expand Down
13 changes: 13 additions & 0 deletions src/reddit/subreddit/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { ContentData } from "../content";
import type { Listing } from "../listing/listing";
import type { Post } from "../post/object";
import type { SearchSort, SearchSyntax, Size, TimeRange } from "../types";
import type { ModeratorActionedUser } from "../user/moderator-actioned/base";
import type {
BanOptions,
LinkPostOptions,
Expand Down Expand Up @@ -869,6 +870,18 @@ export class Subreddit extends Content implements SubredditData {
await this.controls.leaveContributor(`t5_${this.id}`);
}

/**
* Get the list of approved contributors for this subreddit.
*
* @note Due to the way Reddit implements Listings, this will only contain the
* first 1000 contributors.
*
* @returns A listing of approved contributors.
*/
getContributors(): Listing<ModeratorActionedUser> {
return this.controls.getContributors(this.displayName);
}

/**
* Add a user to the list of approved wiki editors.
*
Expand Down
64 changes: 64 additions & 0 deletions src/reddit/user/moderator-actioned/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type {
Fetcher,
ListingContext,
RedditListing,
} from "../../listing/listing";

import { Listing, Pager } from "../../listing/listing";
import { fromRedditData } from "../../util";

/** The data specific to a ModeratorActionedUser. */
export interface ModeratorActionedUserData {
/** The unix timestamp when the action occurred. */
date: number;

/** The ID of this user. */
id: string;

/** The username of this user. */
name: string;

// TODO: document or remove.
// relId: string;
}

/** A user that a moderator has taken some action on (like banning). */
export class ModeratorActionedUser implements ModeratorActionedUserData {
date: number;
id: string;
name: string;

/** @internal */
constructor(data: ModeratorActionedUserData) {
this.date = data.date;
this.id = data.id;
this.name = data.name;
}
}

// #region listing
class ModeratorActionedUserPager extends Pager<ModeratorActionedUser> {
async fetch(context: ListingContext): Promise<ModeratorActionedUserListing> {
const pg = await this.nextPage(context);
return new ModeratorActionedUserListing(pg, context);
}
}

/** @internal */
export class ModeratorActionedUserListing extends Listing<ModeratorActionedUser> {
constructor(l: RedditListing, context: ListingContext) {
let fetcher: Fetcher<ModeratorActionedUser> | undefined;

if (l.after != undefined) {
fetcher = new ModeratorActionedUserPager(l.after);
}

const users: ModeratorActionedUser[] = [];
for (const c of l.children) {
users.push(new ModeratorActionedUser(fromRedditData(c)));
}

super(context, users, fetcher);
}
}
// #endregion listing

0 comments on commit b0f7cef

Please sign in to comment.