import { Component, linkEvent } from "inferno"; import { HtmlTags } from "./html-tags"; import { Subscription } from "rxjs"; import { UserOperation, CommunityView, ListCommunitiesResponse, CommunityResponse, FollowCommunity, ListCommunities, SortType, ListingType, SiteView, } from "lemmy-js-client"; import { WebSocketService } from "../services"; import { wsJsonToRes, toast, getPageFromProps, isBrowser, setIsoData, wsSubscribe, wsUserOp, wsClient, authField, setOptionalAuth, } from "../utils"; import { CommunityLink } from "./community-link"; import { Spinner } from "./icon"; import { i18n } from "../i18next"; import { InitialFetchRequest } from "shared/interfaces"; const communityLimit = 100; interface CommunitiesState { communities: CommunityView[]; page: number; loading: boolean; site_view: SiteView; searchText: string; } interface CommunitiesProps { page: number; } export class Communities extends Component { private subscription: Subscription; private isoData = setIsoData(this.context); private emptyState: CommunitiesState = { communities: [], loading: true, page: getPageFromProps(this.props), site_view: this.isoData.site_res.site_view, searchText: "", }; constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { this.state.communities = this.isoData.routeData[0].communities; this.state.communities.sort( (a, b) => b.counts.subscribers - a.counts.subscribers ); this.state.loading = false; } else { this.refetch(); } } componentWillUnmount() { if (isBrowser()) { this.subscription.unsubscribe(); } } static getDerivedStateFromProps(props: any): CommunitiesProps { return { page: getPageFromProps(props), }; } componentDidUpdate(_: any, lastState: CommunitiesState) { if (lastState.page !== this.state.page) { this.setState({ loading: true }); this.refetch(); } } get documentTitle(): string { return `${i18n.t("communities")} - ${this.state.site_view.site.name}`; } render() { return (
{this.state.loading ? (
) : (

{i18n.t("list_of_communities")}

{this.searchForm()}
{this.state.communities.map(cv => ( ))}
{i18n.t("name")} {i18n.t("category")} {i18n.t("subscribers")} {i18n.t("users")} / {i18n.t("month")} {i18n.t("posts")} {i18n.t("comments")}
{cv.category.name} {cv.counts.subscribers} {cv.counts.users_active_month} {cv.counts.posts} {cv.counts.comments} {cv.subscribed ? ( {i18n.t("unsubscribe")} ) : ( {i18n.t("subscribe")} )}
{this.paginator()}
)}
); } searchForm() { return (
); } paginator() { return (
{this.state.page > 1 && ( )} {this.state.communities.length > 0 && ( )}
); } updateUrl(paramUpdates: CommunitiesProps) { const page = paramUpdates.page || this.state.page; this.props.history.push(`/communities/page/${page}`); } nextPage(i: Communities) { i.updateUrl({ page: i.state.page + 1 }); } prevPage(i: Communities) { i.updateUrl({ page: i.state.page - 1 }); } handleUnsubscribe(communityId: number) { let form: FollowCommunity = { community_id: communityId, follow: false, auth: authField(), }; WebSocketService.Instance.send(wsClient.followCommunity(form)); } handleSubscribe(communityId: number) { let form: FollowCommunity = { community_id: communityId, follow: true, auth: authField(), }; WebSocketService.Instance.send(wsClient.followCommunity(form)); } handleSearchChange(i: Communities, event: any) { i.setState({ searchText: event.target.value }); } handleSearchSubmit(i: Communities) { const searchParamEncoded = encodeURIComponent(i.state.searchText); i.context.router.history.push( `/search/q/${searchParamEncoded}/type/Communities/sort/TopAll/page/1` ); } refetch() { let listCommunitiesForm: ListCommunities = { type_: ListingType.All, sort: SortType.TopAll, limit: communityLimit, page: this.state.page, auth: authField(false), }; WebSocketService.Instance.send( wsClient.listCommunities(listCommunitiesForm) ); } static fetchInitialData(req: InitialFetchRequest): Promise[] { let pathSplit = req.path.split("/"); let page = pathSplit[3] ? Number(pathSplit[3]) : 1; let listCommunitiesForm: ListCommunities = { type_: ListingType.All, sort: SortType.TopAll, limit: communityLimit, page, }; setOptionalAuth(listCommunitiesForm, req.auth); return [req.client.listCommunities(listCommunitiesForm)]; } parseMessage(msg: any) { let op = wsUserOp(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); return; } else if (op == UserOperation.ListCommunities) { let data = wsJsonToRes(msg).data; this.state.communities = data.communities; this.state.communities.sort( (a, b) => b.counts.subscribers - a.counts.subscribers ); this.state.loading = false; window.scrollTo(0, 0); this.setState(this.state); } else if (op == UserOperation.FollowCommunity) { let data = wsJsonToRes(msg).data; let found = this.state.communities.find( c => c.community.id == data.community_view.community.id ); found.subscribed = data.community_view.subscribed; found.counts.subscribers = data.community_view.counts.subscribers; this.setState(this.state); } } }