// This bypasses errors, so that the client can hit the error on its own,
// in order to remove the jwt on the browser. Necessary for wrong jwts
let site: GetSiteResponse | undefined = undefined;
- let routeData: any[] = [];
+ let routeData: Record<string, any> = {};
let errorPageData: ErrorPageData | undefined;
try {
let try_site: any = await client.getSite(getSiteForm);
};
if (activeRoute?.fetchInitialData) {
- routeData = await Promise.all([
- ...activeRoute.fetchInitialData(initialFetchReq),
- ]);
+ const routeDataKeysAndVals = await Promise.all(
+ Object.entries(activeRoute.fetchInitialData(initialFetchReq)).map(
+ async ([key, val]) => [key, await val]
+ )
+ );
+
+ routeData = routeDataKeysAndVals.reduce((acc, [key, val]) => {
+ acc[key] = val;
+
+ return acc;
+ }, {});
}
}
} catch (error) {
errorPageData = getErrorPageData(error, site);
}
+ const error = Object.values(routeData).find(val => val?.error)?.error;
+
// Redirect to the 404 if there's an API error
- if (routeData[0] && routeData[0].error) {
- const error = routeData[0].error;
+ if (error) {
console.error(error);
if (error === "instance_is_private") {
return res.redirect(`/signup`);
import { WebSocketService } from "../../services";
import {
QueryParams,
+ WithPromiseKeys,
getPageFromString,
getQueryParams,
getQueryString,
const communityLimit = 50;
+interface CommunitiesData {
+ listCommunitiesResponse: ListCommunitiesResponse;
+}
+
interface CommunitiesState {
listCommunitiesResponse?: ListCommunitiesResponse;
loading: boolean;
export class Communities extends Component<any, CommunitiesState> {
private subscription?: Subscription;
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<CommunitiesData>(this.context);
state: CommunitiesState = {
loading: true,
siteRes: this.isoData.site_res,
// Only fetch the data if coming from another route
if (this.isoData.path === this.context.router.route.match.url) {
- const listRes = this.isoData.routeData[0] as ListCommunitiesResponse;
+ const { listCommunitiesResponse } = this.isoData.routeData;
+
this.state = {
...this.state,
- listCommunitiesResponse: listRes,
+ listCommunitiesResponse,
loading: false,
};
} else {
query: { listingType, page },
client,
auth,
- }: InitialFetchRequest<QueryParams<CommunitiesProps>>): Promise<any>[] {
+ }: InitialFetchRequest<
+ QueryParams<CommunitiesProps>
+ >): WithPromiseKeys<CommunitiesData> {
const listCommunitiesForm: ListCommunities = {
type_: getListingTypeFromQuery(listingType),
sort: "TopMonth",
auth: auth,
};
- return [client.listCommunities(listCommunitiesForm)];
+ return {
+ listCommunitiesResponse: client.listCommunities(listCommunitiesForm),
+ };
}
parseMessage(msg: any) {
import { UserService, WebSocketService } from "../../services";
import {
QueryParams,
+ WithPromiseKeys,
commentsToFlatNodes,
communityRSSUrl,
createCommentLikeRes,
import { PostListings } from "../post/post-listings";
import { CommunityLink } from "./community-link";
+interface CommunityData {
+ communityResponse: GetCommunityResponse;
+ postsResponse?: GetPostsResponse;
+ commentsResponse?: GetCommentsResponse;
+}
+
interface State {
communityRes?: GetCommunityResponse;
communityLoading: boolean;
RouteComponentProps<{ name: string }>,
State
> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<CommunityData>(this.context);
private subscription?: Subscription;
state: State = {
communityLoading: true,
// Only fetch the data if coming from another route
if (this.isoData.path == this.context.router.route.match.url) {
+ const { communityResponse, commentsResponse, postsResponse } =
+ this.isoData.routeData;
+
this.state = {
...this.state,
- communityRes: this.isoData.routeData[0] as GetCommunityResponse,
+ communityRes: communityResponse,
};
- const postsRes = this.isoData.routeData[1] as
- | GetPostsResponse
- | undefined;
- const commentsRes = this.isoData.routeData[2] as
- | GetCommentsResponse
- | undefined;
-
- if (postsRes) {
- this.state = { ...this.state, posts: postsRes.posts };
+
+ if (postsResponse) {
+ this.state = { ...this.state, posts: postsResponse.posts };
}
- if (commentsRes) {
- this.state = { ...this.state, comments: commentsRes.comments };
+ if (commentsResponse) {
+ this.state = { ...this.state, comments: commentsResponse.comments };
}
this.state = {
path,
query: { dataType: urlDataType, page: urlPage, sort: urlSort },
auth,
- }: InitialFetchRequest<QueryParams<CommunityProps>>): Promise<any>[] {
+ }: InitialFetchRequest<
+ QueryParams<CommunityProps>
+ >): WithPromiseKeys<CommunityData> {
const pathSplit = path.split("/");
- const promises: Promise<any>[] = [];
const communityName = pathSplit[2];
const communityForm: GetCommunity = {
name: communityName,
auth,
};
- promises.push(client.getCommunity(communityForm));
const dataType = getDataTypeFromQuery(urlDataType);
const page = getPageFromString(urlPage);
+ let postsResponse: Promise<GetPostsResponse> | undefined = undefined;
+ let commentsResponse: Promise<GetCommentsResponse> | undefined = undefined;
+
if (dataType === DataType.Post) {
const getPostsForm: GetPosts = {
community_name: communityName,
saved_only: false,
auth,
};
- promises.push(client.getPosts(getPostsForm));
- promises.push(Promise.resolve());
+
+ postsResponse = client.getPosts(getPostsForm);
} else {
const getCommentsForm: GetComments = {
community_name: communityName,
saved_only: false,
auth,
};
- promises.push(Promise.resolve());
- promises.push(client.getComments(getCommentsForm));
+
+ commentsResponse = client.getComments(getCommentsForm);
}
- return promises;
+ return {
+ communityResponse: client.getCommunity(communityForm),
+ commentsResponse,
+ postsResponse,
+ };
}
get documentTitle(): string {
import { Component, linkEvent } from "inferno";
import {
BannedPersonsResponse,
- GetBannedPersons,
GetFederatedInstancesResponse,
GetSiteResponse,
PersonView,
import { InitialFetchRequest } from "../../interfaces";
import { WebSocketService } from "../../services";
import {
+ WithPromiseKeys,
capitalizeFirstLetter,
isBrowser,
myAuth,
import { SiteForm } from "./site-form";
import { TaglineForm } from "./tagline-form";
+interface AdminSettingsData {
+ bannedPersonsResponse: BannedPersonsResponse;
+ federatedInstancesResponse: GetFederatedInstancesResponse;
+}
+
interface AdminSettingsState {
siteRes: GetSiteResponse;
instancesRes?: GetFederatedInstancesResponse;
export class AdminSettings extends Component<any, AdminSettingsState> {
private siteConfigTextAreaId = `site-config-${randomStr()}`;
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<AdminSettingsData>(this.context);
private subscription?: Subscription;
state: AdminSettingsState = {
siteRes: this.isoData.site_res,
// Only fetch the data if coming from another route
if (this.isoData.path == this.context.router.route.match.url) {
+ const { bannedPersonsResponse, federatedInstancesResponse } =
+ this.isoData.routeData;
+
this.state = {
...this.state,
- banned: (this.isoData.routeData[0] as BannedPersonsResponse).banned,
- instancesRes: this.isoData
- .routeData[1] as GetFederatedInstancesResponse,
+ banned: bannedPersonsResponse.banned,
+ instancesRes: federatedInstancesResponse,
loading: false,
};
} else {
}
}
- static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let promises: Promise<any>[] = [];
-
- let auth = req.auth;
- if (auth) {
- let bannedPersonsForm: GetBannedPersons = { auth };
- promises.push(req.client.getBannedPersons(bannedPersonsForm));
- promises.push(req.client.getFederatedInstances({ auth }));
- }
-
- return promises;
+ static fetchInitialData({
+ auth,
+ client,
+ }: InitialFetchRequest): WithPromiseKeys<AdminSettingsData> {
+ return {
+ bannedPersonsResponse: client.getBannedPersons({ auth: auth as string }),
+ federatedInstancesResponse: client.getFederatedInstances({
+ auth: auth as string,
+ }) as Promise<GetFederatedInstancesResponse>,
+ };
}
componentDidMount() {
toast,
trendingFetchLimit,
updatePersonBlock,
+ WithPromiseKeys,
wsClient,
wsSubscribe,
} from "../../utils";
page: number;
}
+interface HomeData {
+ postsResponse?: GetPostsResponse;
+ commentsResponse?: GetCommentsResponse;
+ trendingResponse: ListCommunitiesResponse;
+}
+
function getDataTypeFromQuery(type?: string): DataType {
return type ? DataType[type] : DataType.Post;
}
}
export class Home extends Component<any, HomeState> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<HomeData>(this.context);
private subscription?: Subscription;
state: HomeState = {
trendingCommunities: [],
// Only fetch the data if coming from another route
if (this.isoData.path === this.context.router.route.match.url) {
- const postsRes = this.isoData.routeData[0] as
- | GetPostsResponse
- | undefined;
- const commentsRes = this.isoData.routeData[1] as
- | GetCommentsResponse
- | undefined;
- const trendingRes = this.isoData.routeData[2] as
- | ListCommunitiesResponse
- | undefined;
-
- if (postsRes) {
- this.state = { ...this.state, posts: postsRes.posts };
+ const { trendingResponse, commentsResponse, postsResponse } =
+ this.isoData.routeData;
+
+ if (postsResponse) {
+ this.state = { ...this.state, posts: postsResponse.posts };
}
- if (commentsRes) {
- this.state = { ...this.state, comments: commentsRes.comments };
+ if (commentsResponse) {
+ this.state = { ...this.state, comments: commentsResponse.comments };
}
if (isBrowser()) {
const taglines = this.state?.siteRes?.taglines ?? [];
this.state = {
...this.state,
- trendingCommunities: trendingRes?.communities ?? [],
+ trendingCommunities: trendingResponse?.communities ?? [],
loading: false,
tagline: getRandomFromList(taglines)?.content,
};
client,
auth,
query: { dataType: urlDataType, listingType, page: urlPage, sort: urlSort },
- }: InitialFetchRequest<QueryParams<HomeProps>>): Promise<any>[] {
+ }: InitialFetchRequest<QueryParams<HomeProps>>): WithPromiseKeys<HomeData> {
const dataType = getDataTypeFromQuery(urlDataType);
// TODO figure out auth default_listingType, default_sort_type
const promises: Promise<any>[] = [];
+ let postsResponse: Promise<GetPostsResponse> | undefined = undefined;
+ let commentsResponse: Promise<GetCommentsResponse> | undefined = undefined;
+
if (dataType === DataType.Post) {
const getPostsForm: GetPosts = {
type_,
auth,
};
- promises.push(client.getPosts(getPostsForm));
- promises.push(Promise.resolve());
+ postsResponse = client.getPosts(getPostsForm);
} else {
const getCommentsForm: GetComments = {
page,
saved_only: false,
auth,
};
- promises.push(Promise.resolve());
- promises.push(client.getComments(getCommentsForm));
+
+ commentsResponse = client.getComments(getCommentsForm);
}
const trendingCommunitiesForm: ListCommunities = {
};
promises.push(client.listCommunities(trendingCommunitiesForm));
- return promises;
+ return {
+ trendingResponse: client.listCommunities(trendingCommunitiesForm),
+ commentsResponse,
+ postsResponse,
+ };
}
get documentTitle(): string {
import { InitialFetchRequest } from "../../interfaces";
import { WebSocketService } from "../../services";
import {
+ WithPromiseKeys,
isBrowser,
relTags,
setIsoData,
} from "../../utils";
import { HtmlTags } from "../common/html-tags";
+interface InstancesData {
+ federatedInstancesResponse: GetFederatedInstancesResponse;
+}
+
interface InstancesState {
siteRes: GetSiteResponse;
instancesRes?: GetFederatedInstancesResponse;
}
export class Instances extends Component<any, InstancesState> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<InstancesData>(this.context);
state: InstancesState = {
siteRes: this.isoData.site_res,
loading: true,
if (this.isoData.path == this.context.router.route.match.url) {
this.state = {
...this.state,
- instancesRes: this.isoData
- .routeData[0] as GetFederatedInstancesResponse,
+ instancesRes: this.isoData.routeData.federatedInstancesResponse,
loading: false,
};
} else {
}
}
- static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let promises: Promise<any>[] = [];
-
- promises.push(req.client.getFederatedInstances({}));
-
- return promises;
+ static fetchInitialData({
+ client,
+ }: InitialFetchRequest): WithPromiseKeys<InstancesData> {
+ return {
+ federatedInstancesResponse: client.getFederatedInstances(
+ {}
+ ) as Promise<GetFederatedInstancesResponse>,
+ };
}
get documentTitle(): string {
import {
Choice,
QueryParams,
+ WithPromiseKeys,
amAdmin,
amMod,
debounce,
| AdminPurgePostView
| AdminPurgeCommentView;
+interface ModlogData {
+ modlogResponse: GetModlogResponse;
+ communityResponse?: GetCommunityResponse;
+ modUserResponse?: GetPersonDetailsResponse;
+ userResponse?: GetPersonDetailsResponse;
+}
+
interface ModlogType {
id: number;
type_: ModlogActionType;
RouteComponentProps<{ communityId?: string }>,
ModlogState
> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<ModlogData>(this.context);
private subscription?: Subscription;
state: ModlogState = {
// Only fetch the data if coming from another route
if (this.isoData.path === this.context.router.route.match.url) {
+ const {
+ modlogResponse,
+ communityResponse,
+ modUserResponse,
+ userResponse,
+ } = this.isoData.routeData;
+
this.state = {
...this.state,
- res: this.isoData.routeData[0] as GetModlogResponse,
+ res: modlogResponse,
};
- const communityRes: GetCommunityResponse | undefined =
- this.isoData.routeData[1];
-
// Getting the moderators
this.state = {
...this.state,
- communityMods: communityRes?.moderators,
+ communityMods: communityResponse?.moderators,
};
- const filteredModRes: GetPersonDetailsResponse | undefined =
- this.isoData.routeData[2];
- if (filteredModRes) {
+ if (modUserResponse) {
this.state = {
...this.state,
- modSearchOptions: [personToChoice(filteredModRes.person_view)],
+ modSearchOptions: [personToChoice(modUserResponse.person_view)],
};
}
- const filteredUserRes: GetPersonDetailsResponse | undefined =
- this.isoData.routeData[3];
- if (filteredUserRes) {
+ if (userResponse) {
this.state = {
...this.state,
- userSearchOptions: [personToChoice(filteredUserRes.person_view)],
+ userSearchOptions: [personToChoice(userResponse.person_view)],
};
}
query: { modId: urlModId, page, userId: urlUserId, actionType },
auth,
site,
- }: InitialFetchRequest<QueryParams<ModlogProps>>): Promise<any>[] {
+ }: InitialFetchRequest<
+ QueryParams<ModlogProps>
+ >): WithPromiseKeys<ModlogData> {
const pathSplit = path.split("/");
- const promises: Promise<any>[] = [];
const communityId = getIdFromString(pathSplit[2]);
const modId = !site.site_view.local_site.hide_modlog_mod_names
? getIdFromString(urlModId)
auth,
};
- promises.push(client.getModlog(modlogForm));
+ let communityResponse: Promise<GetCommunityResponse> | undefined =
+ undefined;
if (communityId) {
const communityForm: GetCommunity = {
id: communityId,
auth,
};
- promises.push(client.getCommunity(communityForm));
- } else {
- promises.push(Promise.resolve());
+
+ communityResponse = client.getCommunity(communityForm);
}
+ let modUserResponse: Promise<GetPersonDetailsResponse> | undefined =
+ undefined;
+
if (modId) {
const getPersonForm: GetPersonDetails = {
person_id: modId,
auth,
};
- promises.push(client.getPersonDetails(getPersonForm));
- } else {
- promises.push(Promise.resolve());
+ modUserResponse = client.getPersonDetails(getPersonForm);
}
+ let userResponse: Promise<GetPersonDetailsResponse> | undefined = undefined;
+
if (userId) {
const getPersonForm: GetPersonDetails = {
person_id: userId,
auth,
};
- promises.push(client.getPersonDetails(getPersonForm));
- } else {
- promises.push(Promise.resolve());
+ userResponse = client.getPersonDetails(getPersonForm);
}
- return promises;
+ return {
+ modlogResponse: client.getModlog(modlogForm),
+ communityResponse,
+ modUserResponse,
+ userResponse,
+ };
}
parseMessage(msg: any) {
import { CommentViewType, InitialFetchRequest } from "../../interfaces";
import { UserService, WebSocketService } from "../../services";
import {
+ WithPromiseKeys,
commentsToFlatNodes,
createCommentLikeRes,
editCommentRes,
Mention,
Message,
}
+
+interface InboxData {
+ repliesResponse: GetRepliesResponse;
+ personMentionsResponse: GetPersonMentionsResponse;
+ privateMessagesResponse: PrivateMessagesResponse;
+}
+
type ReplyType = {
id: number;
type_: ReplyEnum;
}
export class Inbox extends Component<any, InboxState> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<InboxData>(this.context);
private subscription?: Subscription;
state: InboxState = {
unreadOrAll: UnreadOrAll.Unread,
this.subscription = wsSubscribe(this.parseMessage);
// Only fetch the data if coming from another route
- if (this.isoData.path == this.context.router.route.match.url) {
+ if (this.isoData.path === this.context.router.route.match.url) {
+ const {
+ personMentionsResponse,
+ privateMessagesResponse,
+ repliesResponse,
+ } = this.isoData.routeData;
+
this.state = {
...this.state,
- replies:
- (this.isoData.routeData[0] as GetRepliesResponse).replies || [],
- mentions:
- (this.isoData.routeData[1] as GetPersonMentionsResponse).mentions ||
- [],
- messages:
- (this.isoData.routeData[2] as PrivateMessagesResponse)
- .private_messages || [],
+ replies: repliesResponse.replies ?? [],
+ mentions: personMentionsResponse.mentions ?? [],
+ messages: privateMessagesResponse.private_messages ?? [],
loading: false,
};
this.state = { ...this.state, combined: this.buildCombined() };
i.refetch();
}
- static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let promises: Promise<any>[] = [];
-
- let sort: CommentSortType = "New";
- let auth = req.auth;
-
- if (auth) {
- // It can be /u/me, or /username/1
- let repliesForm: GetReplies = {
- sort: "New",
- unread_only: true,
- page: 1,
- limit: fetchLimit,
- auth,
- };
- promises.push(req.client.getReplies(repliesForm));
+ static fetchInitialData({
+ auth,
+ client,
+ }: InitialFetchRequest): WithPromiseKeys<InboxData> {
+ const sort: CommentSortType = "New";
+
+ // It can be /u/me, or /username/1
+ const repliesForm: GetReplies = {
+ sort,
+ unread_only: true,
+ page: 1,
+ limit: fetchLimit,
+ auth: auth as string,
+ };
- let personMentionsForm: GetPersonMentions = {
- sort,
- unread_only: true,
- page: 1,
- limit: fetchLimit,
- auth,
- };
- promises.push(req.client.getPersonMentions(personMentionsForm));
+ const personMentionsForm: GetPersonMentions = {
+ sort,
+ unread_only: true,
+ page: 1,
+ limit: fetchLimit,
+ auth: auth as string,
+ };
- let privateMessagesForm: GetPrivateMessages = {
- unread_only: true,
- page: 1,
- limit: fetchLimit,
- auth,
- };
- promises.push(req.client.getPrivateMessages(privateMessagesForm));
- }
+ const privateMessagesForm: GetPrivateMessages = {
+ unread_only: true,
+ page: 1,
+ limit: fetchLimit,
+ auth: auth as string,
+ };
- return promises;
+ return {
+ privateMessagesResponse: client.getPrivateMessages(privateMessagesForm),
+ personMentionsResponse: client.getPersonMentions(personMentionsForm),
+ repliesResponse: client.getReplies(repliesForm),
+ };
}
refetch() {
- let sort = this.state.sort;
- let unread_only = this.state.unreadOrAll == UnreadOrAll.Unread;
- let page = this.state.page;
- let limit = fetchLimit;
- let auth = myAuth();
+ const { sort, page, unreadOrAll } = this.state;
+ const unread_only = unreadOrAll === UnreadOrAll.Unread;
+ const limit = fetchLimit;
+ const auth = myAuth();
if (auth) {
- let repliesForm: GetReplies = {
+ const repliesForm: GetReplies = {
sort,
unread_only,
page,
};
WebSocketService.Instance.send(wsClient.getReplies(repliesForm));
- let personMentionsForm: GetPersonMentions = {
+ const personMentionsForm: GetPersonMentions = {
sort,
unread_only,
page,
wsClient.getPersonMentions(personMentionsForm)
);
- let privateMessagesForm: GetPrivateMessages = {
+ const privateMessagesForm: GetPrivateMessages = {
unread_only,
page,
limit,
import { UserService, WebSocketService } from "../../services";
import {
QueryParams,
+ WithPromiseKeys,
canMod,
capitalizeFirstLetter,
createCommentLikeRes,
import { PersonDetails } from "./person-details";
import { PersonListing } from "./person-listing";
+interface ProfileData {
+ personResponse: GetPersonDetailsResponse;
+}
+
interface ProfileState {
personRes?: GetPersonDetailsResponse;
loading: boolean;
RouteComponentProps<{ username: string }>,
ProfileState
> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<ProfileData>(this.context);
private subscription?: Subscription;
state: ProfileState = {
loading: true,
if (this.isoData.path === this.context.router.route.match.url) {
this.state = {
...this.state,
- personRes: this.isoData.routeData[0] as GetPersonDetailsResponse,
+ personRes: this.isoData.routeData.personResponse,
loading: false,
};
} else {
path,
query: { page, sort, view: urlView },
auth,
- }: InitialFetchRequest<QueryParams<ProfileProps>>): Promise<any>[] {
+ }: InitialFetchRequest<
+ QueryParams<ProfileProps>
+ >): WithPromiseKeys<ProfileData> {
const pathSplit = path.split("/");
const username = pathSplit[2];
auth,
};
- return [client.getPersonDetails(form)];
+ return {
+ personResponse: client.getPersonDetails(form),
+ };
}
componentDidMount() {
import { InitialFetchRequest } from "../../interfaces";
import { UserService, WebSocketService } from "../../services";
import {
+ WithPromiseKeys,
fetchLimit,
isBrowser,
myAuth,
All,
}
+interface RegistrationApplicationsData {
+ listRegistrationApplicationsResponse: ListRegistrationApplicationsResponse;
+}
+
interface RegistrationApplicationsState {
listRegistrationApplicationsResponse?: ListRegistrationApplicationsResponse;
siteRes: GetSiteResponse;
any,
RegistrationApplicationsState
> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<RegistrationApplicationsData>(this.context);
private subscription?: Subscription;
state: RegistrationApplicationsState = {
siteRes: this.isoData.site_res,
this.subscription = wsSubscribe(this.parseMessage);
// Only fetch the data if coming from another route
- if (this.isoData.path == this.context.router.route.match.url) {
+ if (this.isoData.path === this.context.router.route.match.url) {
this.state = {
...this.state,
- listRegistrationApplicationsResponse: this.isoData
- .routeData[0] as ListRegistrationApplicationsResponse,
+ listRegistrationApplicationsResponse:
+ this.isoData.routeData.listRegistrationApplicationsResponse,
loading: false,
};
} else {
this.refetch();
}
- static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let promises: Promise<any>[] = [];
-
- let auth = req.auth;
- if (auth) {
- let form: ListRegistrationApplications = {
- unread_only: true,
- page: 1,
- limit: fetchLimit,
- auth,
- };
- promises.push(req.client.listRegistrationApplications(form));
- }
+ static fetchInitialData({
+ auth,
+ client,
+ }: InitialFetchRequest): WithPromiseKeys<RegistrationApplicationsData> {
+ const form: ListRegistrationApplications = {
+ unread_only: true,
+ page: 1,
+ limit: fetchLimit,
+ auth: auth as string,
+ };
- return promises;
+ return {
+ listRegistrationApplicationsResponse:
+ client.listRegistrationApplications(form),
+ };
}
refetch() {
import { InitialFetchRequest } from "../../interfaces";
import { UserService, WebSocketService } from "../../services";
import {
+ WithPromiseKeys,
amAdmin,
fetchLimit,
isBrowser,
PrivateMessageReport,
}
+interface ReportsData {
+ commentReportsResponse: ListCommentReportsResponse;
+ postReportsResponse: ListPostReportsResponse;
+ privateMessageReportsResponse?: ListPrivateMessageReportsResponse;
+}
+
type ItemType = {
id: number;
type_: MessageEnum;
}
export class Reports extends Component<any, ReportsState> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<ReportsData>(this.context);
private subscription?: Subscription;
state: ReportsState = {
unreadOrAll: UnreadOrAll.Unread,
this.subscription = wsSubscribe(this.parseMessage);
// Only fetch the data if coming from another route
- if (this.isoData.path == this.context.router.route.match.url) {
+ if (this.isoData.path === this.context.router.route.match.url) {
+ const {
+ commentReportsResponse,
+ postReportsResponse,
+ privateMessageReportsResponse,
+ } = this.isoData.routeData;
+
this.state = {
...this.state,
- listCommentReportsResponse: this.isoData
- .routeData[0] as ListCommentReportsResponse,
- listPostReportsResponse: this.isoData
- .routeData[1] as ListPostReportsResponse,
+ listCommentReportsResponse: commentReportsResponse,
+ listPostReportsResponse: postReportsResponse,
+ listPrivateMessageReportsResponse: privateMessageReportsResponse,
};
- if (amAdmin()) {
- this.state = {
- ...this.state,
- listPrivateMessageReportsResponse: this.isoData
- .routeData[2] as ListPrivateMessageReportsResponse,
- };
- }
+
this.state = {
...this.state,
combined: this.buildCombined(),
i.refetch();
}
- static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let promises: Promise<any>[] = [];
+ static fetchInitialData({
+ auth,
+ client,
+ }: InitialFetchRequest): WithPromiseKeys<ReportsData> {
+ const unresolved_only = true;
+ const page = 1;
+ const limit = fetchLimit;
+
+ const commentReportsForm: ListCommentReports = {
+ unresolved_only,
+ page,
+ limit,
+ auth: auth as string,
+ };
- let unresolved_only = true;
- let page = 1;
- let limit = fetchLimit;
- let auth = req.auth;
+ const postReportsForm: ListPostReports = {
+ unresolved_only,
+ page,
+ limit,
+ auth: auth as string,
+ };
- if (auth) {
- let commentReportsForm: ListCommentReports = {
- unresolved_only,
- page,
- limit,
- auth,
- };
- promises.push(req.client.listCommentReports(commentReportsForm));
+ const data: WithPromiseKeys<ReportsData> = {
+ commentReportsResponse: client.listCommentReports(commentReportsForm),
+ postReportsResponse: client.listPostReports(postReportsForm),
+ };
- let postReportsForm: ListPostReports = {
+ if (amAdmin()) {
+ const privateMessageReportsForm: ListPrivateMessageReports = {
unresolved_only,
page,
limit,
- auth,
+ auth: auth as string,
};
- promises.push(req.client.listPostReports(postReportsForm));
- if (amAdmin()) {
- let privateMessageReportsForm: ListPrivateMessageReports = {
- unresolved_only,
- page,
- limit,
- auth,
- };
- promises.push(
- req.client.listPrivateMessageReports(privateMessageReportsForm)
- );
- }
+ data.privateMessageReportsResponse = client.listPrivateMessageReports(
+ privateMessageReportsForm
+ );
}
- return promises;
+ return data;
}
refetch() {
- let unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
- let page = this.state.page;
- let limit = fetchLimit;
- let auth = myAuth();
+ const unresolved_only = this.state.unreadOrAll === UnreadOrAll.Unread;
+ const page = this.state.page;
+ const limit = fetchLimit;
+ const auth = myAuth();
+
if (auth) {
- let commentReportsForm: ListCommentReports = {
+ const commentReportsForm: ListCommentReports = {
unresolved_only,
page,
limit,
auth,
};
+
WebSocketService.Instance.send(
wsClient.listCommentReports(commentReportsForm)
);
- let postReportsForm: ListPostReports = {
+ const postReportsForm: ListPostReports = {
unresolved_only,
page,
limit,
auth,
};
+
WebSocketService.Instance.send(wsClient.listPostReports(postReportsForm));
if (amAdmin()) {
- let privateMessageReportsForm: ListPrivateMessageReports = {
+ const privateMessageReportsForm: ListPrivateMessageReports = {
unresolved_only,
page,
limit,
import {
Choice,
QueryParams,
+ WithPromiseKeys,
enableDownvotes,
enableNsfw,
getIdFromString,
communityId?: number;
}
+interface CreatePostData {
+ communityResponse?: GetCommunityResponse;
+}
+
function getCreatePostQueryParams() {
return getQueryParams<CreatePostProps>({
communityId: getIdFromString,
RouteComponentProps<Record<string, never>>,
CreatePostState
> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<CreatePostData>(this.context);
private subscription?: Subscription;
state: CreatePostState = {
siteRes: this.isoData.site_res,
// Only fetch the data if coming from another route
if (this.isoData.path === this.context.router.route.match.url) {
- const communityRes = this.isoData.routeData[0] as
- | GetCommunityResponse
- | undefined;
+ const { communityResponse } = this.isoData.routeData;
- if (communityRes) {
+ if (communityResponse) {
const communityChoice: Choice = {
- label: communityRes.community_view.community.name,
- value: communityRes.community_view.community.id.toString(),
+ label: communityResponse.community_view.community.name,
+ value: communityResponse.community_view.community.id.toString(),
};
this.state = {
client,
query: { communityId },
auth,
- }: InitialFetchRequest<QueryParams<CreatePostProps>>): Promise<any>[] {
- const promises: Promise<any>[] = [];
+ }: InitialFetchRequest<
+ QueryParams<CreatePostProps>
+ >): WithPromiseKeys<CreatePostData> {
+ const data: WithPromiseKeys<CreatePostData> = {};
if (communityId) {
const form: GetCommunity = {
id: getIdFromString(communityId),
};
- promises.push(client.getCommunity(form));
- } else {
- promises.push(Promise.resolve());
+ data.communityResponse = client.getCommunity(form);
}
- return promises;
+ return data;
}
parseMessage(msg: any) {
toast,
trendingFetchLimit,
updatePersonBlock,
+ WithPromiseKeys,
wsClient,
wsSubscribe,
} from "../../utils";
const commentsShownInterval = 15;
+interface PostData {
+ postResponse: GetPostResponse;
+ commentsResponse: GetCommentsResponse;
+}
+
interface PostState {
postId?: number;
commentId?: number;
export class Post extends Component<any, PostState> {
private subscription?: Subscription;
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<PostData>(this.context);
private commentScrollDebounced: () => void;
state: PostState = {
postId: getIdFromProps(this.props),
this.state = { ...this.state, commentSectionRef: createRef() };
// Only fetch the data if coming from another route
- if (this.isoData.path == this.context.router.route.match.url) {
+ if (this.isoData.path === this.context.router.route.match.url) {
+ const { commentsResponse, postResponse } = this.isoData.routeData;
+
this.state = {
...this.state,
- postRes: this.isoData.routeData[0] as GetPostResponse,
- commentsRes: this.isoData.routeData[1] as GetCommentsResponse,
+ postRes: postResponse,
+ commentsRes: commentsResponse,
};
if (this.state.commentsRes) {
}
}
- static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split("/");
- let promises: Promise<any>[] = [];
+ static fetchInitialData(req: InitialFetchRequest): WithPromiseKeys<PostData> {
+ const pathSplit = req.path.split("/");
- let pathType = pathSplit.at(1);
- let id = pathSplit.at(2) ? Number(pathSplit.at(2)) : undefined;
- let auth = req.auth;
+ const pathType = pathSplit.at(1);
+ const id = pathSplit.at(2) ? Number(pathSplit.at(2)) : undefined;
+ const auth = req.auth;
- let postForm: GetPost = {
+ const postForm: GetPost = {
auth,
};
- let commentsForm: GetComments = {
+ const commentsForm: GetComments = {
max_depth: commentTreeMaxDepth,
sort: "Hot",
type_: "All",
};
// Set the correct id based on the path type
- if (pathType == "post") {
+ if (pathType === "post") {
postForm.id = id;
commentsForm.post_id = id;
} else {
commentsForm.parent_id = id;
}
- promises.push(req.client.getPost(postForm));
- promises.push(req.client.getComments(commentsForm));
-
- return promises;
+ return {
+ postResponse: req.client.getPost(postForm),
+ commentsResponse: req.client.getComments(commentsForm),
+ };
}
componentWillUnmount() {
import { InitialFetchRequest } from "../../interfaces";
import { WebSocketService } from "../../services";
import {
+ WithPromiseKeys,
getRecipientIdFromProps,
isBrowser,
myAuth,
import { Spinner } from "../common/icon";
import { PrivateMessageForm } from "./private-message-form";
+interface CreatePrivateMessageData {
+ recipientDetailsResponse: GetPersonDetailsResponse;
+}
+
interface CreatePrivateMessageState {
siteRes: GetSiteResponse;
recipientDetailsRes?: GetPersonDetailsResponse;
any,
CreatePrivateMessageState
> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<CreatePrivateMessageData>(this.context);
private subscription?: Subscription;
state: CreatePrivateMessageState = {
siteRes: this.isoData.site_res,
this.subscription = wsSubscribe(this.parseMessage);
// Only fetch the data if coming from another route
- if (this.isoData.path == this.context.router.route.match.url) {
+ if (this.isoData.path === this.context.router.route.match.url) {
this.state = {
...this.state,
- recipientDetailsRes: this.isoData
- .routeData[0] as GetPersonDetailsResponse,
+ recipientDetailsRes: this.isoData.routeData.recipientDetailsResponse,
loading: false,
};
} else {
WebSocketService.Instance.send(wsClient.getPersonDetails(form));
}
- static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let person_id = Number(req.path.split("/").pop());
- let form: GetPersonDetails = {
+ static fetchInitialData(
+ req: InitialFetchRequest
+ ): WithPromiseKeys<CreatePrivateMessageData> {
+ const person_id = Number(req.path.split("/").pop());
+
+ const form: GetPersonDetails = {
person_id,
sort: "New",
saved_only: false,
auth: req.auth,
};
- return [req.client.getPersonDetails(form)];
+
+ return {
+ recipientDetailsResponse: req.client.getPersonDetails(form),
+ };
}
get documentTitle(): string {
import {
Choice,
QueryParams,
+ WithPromiseKeys,
capitalizeFirstLetter,
commentsToFlatNodes,
communityToChoice,
page: number;
}
+interface SearchData {
+ communityResponse?: GetCommunityResponse;
+ listCommunitiesResponse?: ListCommunitiesResponse;
+ creatorDetailsResponse?: GetPersonDetailsResponse;
+ searchResponse?: SearchResponse;
+ resolveObjectResponse?: ResolveObjectResponse;
+}
+
type FilterType = "creator" | "community";
interface SearchState {
}
export class Search extends Component<any, SearchState> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<SearchData>(this.context);
private subscription?: Subscription;
state: SearchState = {
searchLoading: false,
// Only fetch the data if coming from another route
if (this.isoData.path === this.context.router.route.match.url) {
- const communityRes = this.isoData.routeData[0] as
- | GetCommunityResponse
- | undefined;
- const communitiesRes = this.isoData.routeData[1] as
- | ListCommunitiesResponse
- | undefined;
+ const {
+ communityResponse,
+ creatorDetailsResponse,
+ listCommunitiesResponse,
+ resolveObjectResponse,
+ searchResponse,
+ } = this.isoData.routeData;
+
// This can be single or multiple communities given
- if (communitiesRes) {
+ if (listCommunitiesResponse) {
this.state = {
...this.state,
- communities: communitiesRes.communities,
+ communities: listCommunitiesResponse.communities,
};
}
- if (communityRes) {
+ if (communityResponse) {
this.state = {
...this.state,
- communities: [communityRes.community_view],
+ communities: [communityResponse.community_view],
communitySearchOptions: [
- communityToChoice(communityRes.community_view),
+ communityToChoice(communityResponse.community_view),
],
};
}
- const creatorRes = this.isoData.routeData[2] as GetPersonDetailsResponse;
-
this.state = {
...this.state,
- creatorDetails: creatorRes,
- creatorSearchOptions: creatorRes
- ? [personToChoice(creatorRes.person_view)]
+ creatorDetails: creatorDetailsResponse,
+ creatorSearchOptions: creatorDetailsResponse
+ ? [personToChoice(creatorDetailsResponse.person_view)]
: [],
};
if (q !== "") {
this.state = {
...this.state,
- searchResponse: this.isoData.routeData[3] as SearchResponse,
- resolveObjectResponse: this.isoData
- .routeData[4] as ResolveObjectResponse,
+ searchResponse,
+ resolveObjectResponse,
searchLoading: false,
};
} else {
client,
auth,
query: { communityId, creatorId, q, type, sort, listingType, page },
- }: InitialFetchRequest<QueryParams<SearchProps>>): Promise<any>[] {
- const promises: Promise<any>[] = [];
-
+ }: InitialFetchRequest<
+ QueryParams<SearchProps>
+ >): WithPromiseKeys<SearchData> {
const community_id = getIdFromString(communityId);
+ let communityResponse: Promise<GetCommunityResponse> | undefined =
+ undefined;
+ let listCommunitiesResponse: Promise<ListCommunitiesResponse> | undefined =
+ undefined;
if (community_id) {
const getCommunityForm: GetCommunity = {
id: community_id,
auth,
};
- promises.push(client.getCommunity(getCommunityForm));
- promises.push(Promise.resolve());
+
+ communityResponse = client.getCommunity(getCommunityForm);
} else {
const listCommunitiesForm: ListCommunities = {
type_: defaultListingType,
limit: fetchLimit,
auth,
};
- promises.push(Promise.resolve());
- promises.push(client.listCommunities(listCommunitiesForm));
+
+ listCommunitiesResponse = client.listCommunities(listCommunitiesForm);
}
const creator_id = getIdFromString(creatorId);
+ let creatorDetailsResponse: Promise<GetPersonDetailsResponse> | undefined =
+ undefined;
if (creator_id) {
const getCreatorForm: GetPersonDetails = {
person_id: creator_id,
auth,
};
- promises.push(client.getPersonDetails(getCreatorForm));
- } else {
- promises.push(Promise.resolve());
+
+ creatorDetailsResponse = client.getPersonDetails(getCreatorForm);
}
const query = getSearchQueryFromQuery(q);
+ let searchResponse: Promise<SearchResponse> | undefined = undefined;
+ let resolveObjectResponse:
+ | Promise<ResolveObjectResponse | undefined>
+ | undefined = undefined;
+
if (query) {
const form: SearchForm = {
q: query,
};
if (query !== "") {
- promises.push(client.search(form));
+ searchResponse = client.search(form);
if (auth) {
const resolveObjectForm: ResolveObject = {
q: query,
auth,
};
- promises.push(client.resolveObject(resolveObjectForm));
+ resolveObjectResponse = client
+ .resolveObject(resolveObjectForm)
+ .catch(() => undefined);
}
- } else {
- promises.push(Promise.resolve());
- promises.push(Promise.resolve());
}
}
- return promises;
+ return {
+ communityResponse,
+ creatorDetailsResponse,
+ listCommunitiesResponse,
+ resolveObjectResponse,
+ searchResponse,
+ };
}
get documentTitle(): string {
/**
* This contains serialized data, it needs to be deserialized before use.
*/
-export interface IsoData {
+export interface IsoData<T extends object = any> {
path: string;
- routeData: any[];
+ routeData: T;
site_res: GetSiteResponse;
errorPageData?: ErrorPageData;
}
-export type IsoDataOptionalSite = Partial<IsoData> &
- Pick<IsoData, Exclude<keyof IsoData, "site_res">>;
+export type IsoDataOptionalSite<T extends object = any> = Partial<IsoData<T>> &
+ Pick<IsoData<T>, Exclude<keyof IsoData<T>, "site_res">>;
export interface ILemmyConfig {
wsHost?: string;
import { CreatePrivateMessage } from "./components/private_message/create-private-message";
import { Search } from "./components/search";
import { InitialFetchRequest } from "./interfaces";
+import { WithPromiseKeys } from "./utils";
-interface IRoutePropsWithFetch extends IRouteProps {
+interface IRoutePropsWithFetch<T extends object> extends IRouteProps {
// TODO Make sure this one is good.
- fetchInitialData?(req: InitialFetchRequest): Promise<any>[];
+ fetchInitialData?(req: InitialFetchRequest): WithPromiseKeys<T>;
}
-export const routes: IRoutePropsWithFetch[] = [
+export const routes: IRoutePropsWithFetch<Record<string, any>>[] = [
{
path: `/`,
component: Home,
return typeof window !== "undefined";
}
-export function setIsoData(context: any): IsoData {
+export function setIsoData<T extends object>(context: any): IsoData<T> {
// If its the browser, you need to deserialize the data from the window
if (isBrowser()) {
return window.isoData;
[key in keyof T]?: string;
};
+export type WithPromiseKeys<T extends object> = {
+ [K in keyof T]: Promise<T[K]>;
+};
+
export function getQueryParams<T extends Record<string, any>>(processors: {
[K in keyof T]: (param: string) => T[K];
}): T {