Allow sorting on /communities (#1934)

* Allow sorting on communities page

Just a few minor changes to communities.tsx that add a sort dropdown - same element as the sort dropdown in home.tsx

* Fix alignment of communities.tsx selector row

Simple CSS fix for correct alignment of a few elements

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
Ben Wyatt 2023-07-17 10:22:01 -05:00 committed by GitHub
parent 9c489680de
commit 6331323554
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -20,6 +20,7 @@ import {
ListCommunities, ListCommunities,
ListCommunitiesResponse, ListCommunitiesResponse,
ListingType, ListingType,
SortType,
} from "lemmy-js-client"; } from "lemmy-js-client";
import { InitialFetchRequest } from "../../interfaces"; import { InitialFetchRequest } from "../../interfaces";
import { FirstLoadService, I18NextService } from "../../services"; import { FirstLoadService, I18NextService } from "../../services";
@ -28,6 +29,7 @@ import { HtmlTags } from "../common/html-tags";
import { Spinner } from "../common/icon"; import { Spinner } from "../common/icon";
import { ListingTypeSelect } from "../common/listing-type-select"; import { ListingTypeSelect } from "../common/listing-type-select";
import { Paginator } from "../common/paginator"; import { Paginator } from "../common/paginator";
import { SortSelect } from "../common/sort-select";
import { CommunityLink } from "./community-link"; import { CommunityLink } from "./community-link";
const communityLimit = 50; const communityLimit = 50;
@ -45,6 +47,7 @@ interface CommunitiesState {
interface CommunitiesProps { interface CommunitiesProps {
listingType: ListingType; listingType: ListingType;
sort: SortType;
page: number; page: number;
} }
@ -52,6 +55,10 @@ function getListingTypeFromQuery(listingType?: string): ListingType {
return listingType ? (listingType as ListingType) : "Local"; return listingType ? (listingType as ListingType) : "Local";
} }
function getSortTypeFromQuery(type?: string): SortType {
return type ? (type as SortType) : "TopMonth";
}
export class Communities extends Component<any, CommunitiesState> { export class Communities extends Component<any, CommunitiesState> {
private isoData = setIsoData<CommunitiesData>(this.context); private isoData = setIsoData<CommunitiesData>(this.context);
state: CommunitiesState = { state: CommunitiesState = {
@ -64,6 +71,7 @@ export class Communities extends Component<any, CommunitiesState> {
constructor(props: any, context: any) { constructor(props: any, context: any) {
super(props, context); super(props, context);
this.handlePageChange = this.handlePageChange.bind(this); this.handlePageChange = this.handlePageChange.bind(this);
this.handleSortChange = this.handleSortChange.bind(this);
this.handleListingTypeChange = this.handleListingTypeChange.bind(this); this.handleListingTypeChange = this.handleListingTypeChange.bind(this);
// Only fetch the data if coming from another route // Only fetch the data if coming from another route
@ -99,13 +107,13 @@ export class Communities extends Component<any, CommunitiesState> {
</h5> </h5>
); );
case "success": { case "success": {
const { listingType, page } = this.getCommunitiesQueryParams(); const { listingType, sort, page } = this.getCommunitiesQueryParams();
return ( return (
<div> <div>
<h1 className="h4 mb-4"> <h1 className="h4 mb-4">
{I18NextService.i18n.t("list_of_communities")} {I18NextService.i18n.t("list_of_communities")}
</h1> </h1>
<div className="row g-2 justify-content-between"> <div className="row g-3 align-items-center mb-2">
<div className="col-auto"> <div className="col-auto">
<ListingTypeSelect <ListingTypeSelect
type_={listingType} type_={listingType}
@ -114,6 +122,9 @@ export class Communities extends Component<any, CommunitiesState> {
onChange={this.handleListingTypeChange} onChange={this.handleListingTypeChange}
/> />
</div> </div>
<div className="col-auto me-auto">
<SortSelect sort={sort} onChange={this.handleSortChange} />
</div>
<div className="col-auto">{this.searchForm()}</div> <div className="col-auto">{this.searchForm()}</div>
</div> </div>
@ -224,10 +235,7 @@ export class Communities extends Component<any, CommunitiesState> {
searchForm() { searchForm() {
return ( return (
<form <form className="row" onSubmit={linkEvent(this, this.handleSearchSubmit)}>
className="row mb-2"
onSubmit={linkEvent(this, this.handleSearchSubmit)}
>
<div className="col-auto"> <div className="col-auto">
<input <input
type="text" type="text"
@ -252,12 +260,16 @@ export class Communities extends Component<any, CommunitiesState> {
); );
} }
async updateUrl({ listingType, page }: Partial<CommunitiesProps>) { async updateUrl({ listingType, sort, page }: Partial<CommunitiesProps>) {
const { listingType: urlListingType, page: urlPage } = const {
this.getCommunitiesQueryParams(); listingType: urlListingType,
sort: urlSort,
page: urlPage,
} = this.getCommunitiesQueryParams();
const queryParams: QueryParams<CommunitiesProps> = { const queryParams: QueryParams<CommunitiesProps> = {
listingType: listingType ?? urlListingType, listingType: listingType ?? urlListingType,
sort: sort ?? urlSort,
page: (page ?? urlPage)?.toString(), page: (page ?? urlPage)?.toString(),
}; };
@ -270,6 +282,10 @@ export class Communities extends Component<any, CommunitiesState> {
this.updateUrl({ page }); this.updateUrl({ page });
} }
handleSortChange(val: SortType) {
this.updateUrl({ sort: val, page: 1 });
}
handleListingTypeChange(val: ListingType) { handleListingTypeChange(val: ListingType) {
this.updateUrl({ this.updateUrl({
listingType: val, listingType: val,
@ -290,7 +306,7 @@ export class Communities extends Component<any, CommunitiesState> {
} }
static async fetchInitialData({ static async fetchInitialData({
query: { listingType, page }, query: { listingType, sort, page },
client, client,
auth, auth,
}: InitialFetchRequest< }: InitialFetchRequest<
@ -298,7 +314,7 @@ export class Communities extends Component<any, CommunitiesState> {
>): Promise<CommunitiesData> { >): Promise<CommunitiesData> {
const listCommunitiesForm: ListCommunities = { const listCommunitiesForm: ListCommunities = {
type_: getListingTypeFromQuery(listingType), type_: getListingTypeFromQuery(listingType),
sort: "TopMonth", sort: getSortTypeFromQuery(sort),
limit: communityLimit, limit: communityLimit,
page: getPageFromString(page), page: getPageFromString(page),
auth: auth, auth: auth,
@ -314,6 +330,7 @@ export class Communities extends Component<any, CommunitiesState> {
getCommunitiesQueryParams() { getCommunitiesQueryParams() {
return getQueryParams<CommunitiesProps>({ return getQueryParams<CommunitiesProps>({
listingType: getListingTypeFromQuery, listingType: getListingTypeFromQuery,
sort: getSortTypeFromQuery,
page: getPageFromString, page: getPageFromString,
}); });
} }
@ -334,12 +351,12 @@ export class Communities extends Component<any, CommunitiesState> {
async refetch() { async refetch() {
this.setState({ listCommunitiesResponse: { state: "loading" } }); this.setState({ listCommunitiesResponse: { state: "loading" } });
const { listingType, page } = this.getCommunitiesQueryParams(); const { listingType, sort, page } = this.getCommunitiesQueryParams();
this.setState({ this.setState({
listCommunitiesResponse: await HttpService.client.listCommunities({ listCommunitiesResponse: await HttpService.client.listCommunities({
type_: listingType, type_: listingType,
sort: "TopMonth", sort: sort,
limit: communityLimit, limit: communityLimit,
page, page,
auth: myAuth(), auth: myAuth(),