import { Component, linkEvent } from "inferno"; import { CommunityResponse, GetSiteResponse, ListCommunities, ListCommunitiesResponse, ListingType, } from "lemmy-js-client"; import { i18n } from "../../i18next"; import { InitialFetchRequest } from "../../interfaces"; import { FirstLoadService } from "../../services/FirstLoadService"; import { HttpService, RequestState } from "../../services/HttpService"; import { QueryParams, editCommunity, getPageFromString, getQueryParams, getQueryString, myAuth, myAuthRequired, numToSI, setIsoData, showLocal, } from "../../utils"; import { HtmlTags } from "../common/html-tags"; import { Spinner } from "../common/icon"; import { ListingTypeSelect } from "../common/listing-type-select"; import { Paginator } from "../common/paginator"; import { CommunityLink } from "./community-link"; const communityLimit = 50; interface CommunitiesState { listCommunitiesResponse: RequestState; siteRes: GetSiteResponse; searchText: string; isIsomorphic: boolean; } interface CommunitiesProps { listingType: ListingType; page: number; } function getListingTypeFromQuery(listingType?: string): ListingType { return listingType ? (listingType as ListingType) : "Local"; } export class Communities extends Component { private isoData = setIsoData(this.context); state: CommunitiesState = { listCommunitiesResponse: { state: "empty" }, siteRes: this.isoData.site_res, searchText: "", isIsomorphic: false, }; constructor(props: any, context: any) { super(props, context); this.handlePageChange = this.handlePageChange.bind(this); this.handleListingTypeChange = this.handleListingTypeChange.bind(this); // Only fetch the data if coming from another route if (FirstLoadService.isFirstLoad) { this.state = { ...this.state, listCommunitiesResponse: this.isoData.routeData[0], isIsomorphic: true, }; } } async componentDidMount() { if (!this.state.isIsomorphic) { await this.refetch(); } } get documentTitle(): string { return `${i18n.t("communities")} - ${ this.state.siteRes.site_view.site.name }`; } renderListings() { switch (this.state.listCommunitiesResponse.state) { case "loading": return (
); case "success": { const { listingType, page } = this.getCommunitiesQueryParams(); return (

{i18n.t("list_of_communities")}

{this.searchForm()}
{this.state.listCommunitiesResponse.data.communities.map( cv => ( ) )}
{i18n.t("name")} {i18n.t("subscribers")} {i18n.t("users")} / {i18n.t("month")} {i18n.t("posts")} {i18n.t("comments")}
{numToSI(cv.counts.subscribers)} {numToSI(cv.counts.users_active_month)} {numToSI(cv.counts.posts)} {numToSI(cv.counts.comments)} {cv.subscribed == "Subscribed" && ( )} {cv.subscribed === "NotSubscribed" && ( )} {cv.subscribed === "Pending" && (
{i18n.t("subscribe_pending")}
)}
); } } } render() { return (
{this.renderListings()}
); } searchForm() { return (
); } async updateUrl({ listingType, page }: Partial) { const { listingType: urlListingType, page: urlPage } = this.getCommunitiesQueryParams(); const queryParams: QueryParams = { listingType: listingType ?? urlListingType, page: (page ?? urlPage)?.toString(), }; this.props.history.push(`/communities${getQueryString(queryParams)}`); await this.refetch(); } handlePageChange(page: number) { this.updateUrl({ page }); } handleListingTypeChange(val: ListingType) { this.updateUrl({ listingType: val, page: 1, }); } handleSearchChange(i: Communities, event: any) { i.setState({ searchText: event.target.value }); } handleSearchSubmit(i: Communities, event: any) { event.preventDefault(); const searchParamEncoded = encodeURIComponent(i.state.searchText); i.context.router.history.push(`/search?q=${searchParamEncoded}`); } static fetchInitialData({ query: { listingType, page }, client, auth, }: InitialFetchRequest>): Promise< RequestState >[] { const listCommunitiesForm: ListCommunities = { type_: getListingTypeFromQuery(listingType), sort: "TopMonth", limit: communityLimit, page: getPageFromString(page), auth: auth, }; return [client.listCommunities(listCommunitiesForm)]; } getCommunitiesQueryParams() { return getQueryParams({ listingType: getListingTypeFromQuery, page: getPageFromString, }); } async handleFollow(data: { i: Communities; communityId: number; follow: boolean; }) { const res = await HttpService.client.followCommunity({ community_id: data.communityId, follow: data.follow, auth: myAuthRequired(), }); data.i.findAndUpdateCommunity(res); } async refetch() { this.setState({ listCommunitiesResponse: { state: "loading" } }); const { listingType, page } = this.getCommunitiesQueryParams(); this.setState({ listCommunitiesResponse: await HttpService.client.listCommunities({ type_: listingType, sort: "TopMonth", limit: communityLimit, page, auth: myAuth(), }), }); window.scrollTo(0, 0); } findAndUpdateCommunity(res: RequestState) { this.setState(s => { if ( s.listCommunitiesResponse.state == "success" && res.state == "success" ) { s.listCommunitiesResponse.data.communities = editCommunity( res.data.community_view, s.listCommunitiesResponse.data.communities ); } return s; }); } }