import { i18n } from "../../i18next";
import { WebSocketService } from "../../services";
import {
- getListingTypeFromPropsNoDefault,
- getPageFromProps,
+ getPageFromString,
+ getQueryParams,
+ getQueryString,
isBrowser,
myAuth,
numToSI,
+ QueryParams,
+ routeListingTypeToEnum,
setIsoData,
showLocal,
toast,
interface CommunitiesState {
listCommunitiesResponse?: ListCommunitiesResponse;
- page: number;
loading: boolean;
siteRes: GetSiteResponse;
searchText: string;
- listingType: ListingType;
}
interface CommunitiesProps {
- listingType?: ListingType;
- page?: number;
+ listingType: ListingType;
+ page: number;
+}
+
+function getCommunitiesQueryParams() {
+ return getQueryParams<CommunitiesProps>({
+ listingType: getListingTypeFromQuery,
+ page: getPageFromString,
+ });
+}
+
+function getListingTypeFromQuery(listingType?: string): ListingType {
+ return routeListingTypeToEnum(listingType ?? "", ListingType.Local);
+}
+
+function toggleSubscribe(community_id: number, follow: boolean) {
+ const auth = myAuth();
+ if (auth) {
+ const form: FollowCommunity = {
+ community_id,
+ follow,
+ auth,
+ };
+
+ WebSocketService.Instance.send(wsClient.followCommunity(form));
+ }
+}
+
+function refetch() {
+ const { listingType, page } = getCommunitiesQueryParams();
+
+ const listCommunitiesForm: ListCommunities = {
+ type_: listingType,
+ sort: SortType.TopMonth,
+ limit: communityLimit,
+ page,
+ auth: myAuth(false),
+ };
+
+ WebSocketService.Instance.send(wsClient.listCommunities(listCommunitiesForm));
}
export class Communities extends Component<any, CommunitiesState> {
private isoData = setIsoData(this.context);
state: CommunitiesState = {
loading: true,
- page: getPageFromProps(this.props),
- listingType: getListingTypeFromPropsNoDefault(this.props),
siteRes: this.isoData.site_res,
searchText: "",
};
this.subscription = wsSubscribe(this.parseMessage);
// Only fetch the data if coming from another route
- if (this.isoData.path == this.context.router.route.match.url) {
- let listRes = this.isoData.routeData[0] as ListCommunitiesResponse;
+ if (this.isoData.path === this.context.router.route.match.url) {
+ const listRes = this.isoData.routeData[0] as ListCommunitiesResponse;
this.state = {
...this.state,
listCommunitiesResponse: listRes,
loading: false,
};
} else {
- this.refetch();
+ refetch();
}
}
}
}
- static getDerivedStateFromProps(props: any): CommunitiesProps {
- return {
- listingType: getListingTypeFromPropsNoDefault(props),
- page: getPageFromProps(props),
- };
- }
-
- componentDidUpdate(_: any, lastState: CommunitiesState) {
- if (
- lastState.page !== this.state.page ||
- lastState.listingType !== this.state.listingType
- ) {
- this.setState({ loading: true });
- this.refetch();
- }
- }
-
get documentTitle(): string {
return `${i18n.t("communities")} - ${
this.state.siteRes.site_view.site.name
}
render() {
+ const { listingType, page } = getCommunitiesQueryParams();
+
return (
<div className="container-lg">
<HtmlTags
<h4>{i18n.t("list_of_communities")}</h4>
<span className="mb-2">
<ListingTypeSelect
- type_={this.state.listingType}
+ type_={listingType}
showLocal={showLocal(this.isoData)}
showSubscribed
onChange={this.handleListingTypeChange}
{i18n.t("unsubscribe")}
</button>
)}
- {cv.subscribed == SubscribedType.NotSubscribed && (
+ {cv.subscribed === SubscribedType.NotSubscribed && (
<button
className="btn btn-link d-inline-block"
onClick={linkEvent(
{i18n.t("subscribe")}
</button>
)}
- {cv.subscribed == SubscribedType.Pending && (
+ {cv.subscribed === SubscribedType.Pending && (
<div className="text-warning d-inline-block">
{i18n.t("subscribe_pending")}
</div>
</tbody>
</table>
</div>
- <Paginator
- page={this.state.page}
- onChange={this.handlePageChange}
- />
+ <Paginator page={page} onChange={this.handlePageChange} />
</div>
)}
</div>
);
}
- updateUrl(paramUpdates: CommunitiesProps) {
- const page = paramUpdates.page || this.state.page;
- const listingTypeStr = paramUpdates.listingType || this.state.listingType;
- this.props.history.push(
- `/communities/listing_type/${listingTypeStr}/page/${page}`
- );
+ updateUrl({ listingType, page }: Partial<CommunitiesProps>) {
+ const { listingType: urlListingType, page: urlPage } =
+ getCommunitiesQueryParams();
+
+ const queryParams: QueryParams<CommunitiesProps> = {
+ listingType: listingType ?? urlListingType,
+ page: (page ?? urlPage)?.toString(),
+ };
+
+ this.props.history.push(`/communities${getQueryString(queryParams)}`);
+
+ refetch();
}
handlePageChange(page: number) {
}
handleUnsubscribe(communityId: number) {
- let auth = myAuth();
- if (auth) {
- let form: FollowCommunity = {
- community_id: communityId,
- follow: false,
- auth,
- };
- WebSocketService.Instance.send(wsClient.followCommunity(form));
- }
+ toggleSubscribe(communityId, false);
}
handleSubscribe(communityId: number) {
- let auth = myAuth();
- if (auth) {
- let form: FollowCommunity = {
- community_id: communityId,
- follow: true,
- auth,
- };
- WebSocketService.Instance.send(wsClient.followCommunity(form));
- }
+ toggleSubscribe(communityId, true);
}
handleSearchChange(i: Communities, event: any) {
handleSearchSubmit(i: Communities) {
const searchParamEncoded = encodeURIComponent(i.state.searchText);
- i.context.router.history.push(
- `/search/q/${searchParamEncoded}/type/Communities/sort/TopAll/listing_type/All/community_id/0/creator_id/0/page/1`
- );
- }
-
- refetch() {
- let listCommunitiesForm: ListCommunities = {
- type_: this.state.listingType,
- sort: SortType.TopMonth,
- limit: communityLimit,
- page: this.state.page,
- auth: myAuth(false),
- };
-
- WebSocketService.Instance.send(
- wsClient.listCommunities(listCommunitiesForm)
- );
+ i.context.router.history.push(`/search?q=${searchParamEncoded}`);
}
- static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split("/");
- let type_: ListingType = pathSplit[3]
- ? ListingType[pathSplit[3]]
- : ListingType.Local;
- let page = pathSplit[5] ? Number(pathSplit[5]) : 1;
- let listCommunitiesForm: ListCommunities = {
- type_,
+ static fetchInitialData({
+ query: { listingType, page },
+ client,
+ auth,
+ }: InitialFetchRequest<QueryParams<CommunitiesProps>>): Promise<any>[] {
+ const listCommunitiesForm: ListCommunities = {
+ type_: getListingTypeFromQuery(listingType),
sort: SortType.TopMonth,
limit: communityLimit,
- page,
- auth: req.auth,
+ page: getPageFromString(page),
+ auth: auth,
};
- return [req.client.listCommunities(listCommunitiesForm)];
+ return [client.listCommunities(listCommunitiesForm)];
}
parseMessage(msg: any) {
- let op = wsUserOp(msg);
+ const op = wsUserOp(msg);
console.log(msg);
if (msg.error) {
toast(i18n.t(msg.error), "danger");
- return;
- } else if (op == UserOperation.ListCommunities) {
- let data = wsJsonToRes<ListCommunitiesResponse>(msg);
+ } else if (op === UserOperation.ListCommunities) {
+ const data = wsJsonToRes<ListCommunitiesResponse>(msg);
this.setState({ listCommunitiesResponse: data, loading: false });
window.scrollTo(0, 0);
- } else if (op == UserOperation.FollowCommunity) {
- let data = wsJsonToRes<CommunityResponse>(msg);
- let res = this.state.listCommunitiesResponse;
- let found = res?.communities.find(
- c => c.community.id == data.community_view.community.id
+ } else if (op === UserOperation.FollowCommunity) {
+ const {
+ community_view: {
+ community,
+ subscribed,
+ counts: { subscribers },
+ },
+ } = wsJsonToRes<CommunityResponse>(msg);
+ const res = this.state.listCommunitiesResponse;
+ const found = res?.communities.find(
+ ({ community: { id } }) => id == community.id
);
+
if (found) {
- found.subscribed = data.community_view.subscribed;
- found.counts.subscribers = data.community_view.counts.subscribers;
+ found.subscribed = subscribed;
+ found.counts.subscribers = subscribers;
this.setState(this.state);
}
}