X-Git-Url: http://these/git/?a=blobdiff_plain;f=src%2Fshared%2Fcomponents%2Fsearch.tsx;fp=src%2Fshared%2Fcomponents%2Fsearch.tsx;h=9f466730a8c952cd5cf03fcefb3efe44a1f3e1d1;hb=9265fc58948341856513c06ba44e1a0c0d5a4241;hp=c62c7a98413542d7220ee7c875579927bb5ad332;hpb=72b4d14b47dd8501597b15cc0cf5713ff86aaca9;p=lemmy-ui.git diff --git a/src/shared/components/search.tsx b/src/shared/components/search.tsx index c62c7a9..9f46673 100644 --- a/src/shared/components/search.tsx +++ b/src/shared/components/search.tsx @@ -1,7 +1,6 @@ import type { NoOptionI18nKeys } from "i18next"; import { Component, linkEvent } from "inferno"; import { - CommentResponse, CommentView, CommunityView, GetCommunity, @@ -13,7 +12,6 @@ import { ListCommunitiesResponse, ListingType, PersonView, - PostResponse, PostView, ResolveObject, ResolveObjectResponse, @@ -21,23 +19,18 @@ import { SearchResponse, SearchType, SortType, - UserOperation, - wsJsonToRes, - wsUserOp, } from "lemmy-js-client"; -import { Subscription } from "rxjs"; import { i18n } from "../i18next"; import { CommentViewType, InitialFetchRequest } from "../interfaces"; -import { WebSocketService } from "../services"; +import { FirstLoadService } from "../services/FirstLoadService"; +import { HttpService, RequestState } from "../services/HttpService"; import { Choice, QueryParams, - WithPromiseKeys, + RouteDataResponse, capitalizeFirstLetter, commentsToFlatNodes, communityToChoice, - createCommentLikeRes, - createPostLikeFindRes, debounce, enableDownvotes, enableNsfw, @@ -56,9 +49,6 @@ import { saveScrollPosition, setIsoData, showLocal, - toast, - wsClient, - wsSubscribe, } from "../utils"; import { CommentNodes } from "./comment/comment-nodes"; import { HtmlTags } from "./common/html-tags"; @@ -81,28 +71,29 @@ interface SearchProps { page: number; } -interface SearchData { +type SearchData = RouteDataResponse<{ communityResponse?: GetCommunityResponse; listCommunitiesResponse?: ListCommunitiesResponse; creatorDetailsResponse?: GetPersonDetailsResponse; searchResponse?: SearchResponse; resolveObjectResponse?: ResolveObjectResponse; -} +}>; type FilterType = "creator" | "community"; interface SearchState { - searchResponse?: SearchResponse; - communities: CommunityView[]; - creatorDetails?: GetPersonDetailsResponse; - searchLoading: boolean; - searchCommunitiesLoading: boolean; - searchCreatorLoading: boolean; + searchRes: RequestState; + resolveObjectRes: RequestState; + creatorDetailsRes: RequestState; + communitiesRes: RequestState; + communityRes: RequestState; siteRes: GetSiteResponse; searchText?: string; - resolveObjectResponse?: ResolveObjectResponse; communitySearchOptions: Choice[]; creatorSearchOptions: Choice[]; + searchCreatorLoading: boolean; + searchCommunitiesLoading: boolean; + isIsomorphic: boolean; } interface Combined { @@ -247,15 +238,19 @@ function getListing( export class Search extends Component { private isoData = setIsoData(this.context); - private subscription?: Subscription; + state: SearchState = { - searchLoading: false, + resolveObjectRes: { state: "empty" }, + creatorDetailsRes: { state: "empty" }, + communitiesRes: { state: "empty" }, + communityRes: { state: "empty" }, siteRes: this.isoData.site_res, - communities: [], - searchCommunitiesLoading: false, - searchCreatorLoading: false, creatorSearchOptions: [], communitySearchOptions: [], + searchRes: { state: "empty" }, + searchCreatorLoading: false, + searchCommunitiesLoading: false, + isIsomorphic: false, }; constructor(props: any, context: any) { @@ -268,9 +263,6 @@ export class Search extends Component { this.handleCommunityFilterChange.bind(this); this.handleCreatorFilterChange = this.handleCreatorFilterChange.bind(this); - this.parseMessage = this.parseMessage.bind(this); - this.subscription = wsSubscribe(this.parseMessage); - const { q } = getSearchQueryParams(); this.state = { @@ -279,92 +271,112 @@ export class Search extends Component { }; // Only fetch the data if coming from another route - if (this.isoData.path === this.context.router.route.match.url) { + if (FirstLoadService.isFirstLoad) { const { - communityResponse, - creatorDetailsResponse, - listCommunitiesResponse, - resolveObjectResponse, - searchResponse, + communityResponse: communityRes, + creatorDetailsResponse: creatorDetailsRes, + listCommunitiesResponse: communitiesRes, + resolveObjectResponse: resolveObjectRes, + searchResponse: searchRes, } = this.isoData.routeData; - // This can be single or multiple communities given - if (listCommunitiesResponse) { + this.state = { + ...this.state, + isIsomorphic: true, + }; + + if (creatorDetailsRes?.state === "success") { this.state = { ...this.state, - communities: listCommunitiesResponse.communities, + creatorSearchOptions: + creatorDetailsRes?.state === "success" + ? [personToChoice(creatorDetailsRes.data.person_view)] + : [], + creatorDetailsRes, }; } - if (communityResponse) { + + if (communitiesRes?.state === "success") { this.state = { ...this.state, - communities: [communityResponse.community_view], - communitySearchOptions: [ - communityToChoice(communityResponse.community_view), - ], + communitiesRes, }; } - this.state = { - ...this.state, - creatorDetails: creatorDetailsResponse, - creatorSearchOptions: creatorDetailsResponse - ? [personToChoice(creatorDetailsResponse.person_view)] - : [], - }; + if (communityRes?.state === "success") { + this.state = { + ...this.state, + communityRes, + }; + } if (q !== "") { this.state = { ...this.state, - searchResponse, - resolveObjectResponse, - searchLoading: false, }; - } else { - this.search(); - } - } else { - const listCommunitiesForm: ListCommunities = { - type_: defaultListingType, - sort: defaultSortType, - limit: fetchLimit, - auth: myAuth(false), - }; - WebSocketService.Instance.send( - wsClient.listCommunities(listCommunitiesForm) - ); + if (searchRes?.state === "success") { + this.state = { + ...this.state, + searchRes, + }; + } - if (q) { - this.search(); + if (resolveObjectRes?.state === "success") { + this.state = { + ...this.state, + resolveObjectRes, + }; + } } } } + async componentDidMount() { + if (!this.state.isIsomorphic) { + const promises = [this.fetchCommunities()]; + if (this.state.searchText) { + promises.push(this.search()); + } + + await Promise.all(promises); + } + } + + async fetchCommunities() { + this.setState({ communitiesRes: { state: "loading" } }); + this.setState({ + communitiesRes: await HttpService.client.listCommunities({ + type_: defaultListingType, + sort: defaultSortType, + limit: fetchLimit, + auth: myAuth(), + }), + }); + } + componentWillUnmount() { - this.subscription?.unsubscribe(); saveScrollPosition(this.context); } - static fetchInitialData({ + static async fetchInitialData({ client, auth, query: { communityId, creatorId, q, type, sort, listingType, page }, - }: InitialFetchRequest< - QueryParams - >): WithPromiseKeys { + }: InitialFetchRequest>): Promise { const community_id = getIdFromString(communityId); - let communityResponse: Promise | undefined = - undefined; - let listCommunitiesResponse: Promise | undefined = + let communityResponse: RequestState | undefined = undefined; + let listCommunitiesResponse: + | RequestState + | undefined = undefined; if (community_id) { const getCommunityForm: GetCommunity = { id: community_id, auth, }; - communityResponse = client.getCommunity(getCommunityForm); + communityResponse = await client.getCommunity(getCommunityForm); } else { const listCommunitiesForm: ListCommunities = { type_: defaultListingType, @@ -373,27 +385,29 @@ export class Search extends Component { auth, }; - listCommunitiesResponse = client.listCommunities(listCommunitiesForm); + listCommunitiesResponse = await client.listCommunities( + listCommunitiesForm + ); } const creator_id = getIdFromString(creatorId); - let creatorDetailsResponse: Promise | undefined = - undefined; + let creatorDetailsResponse: + | RequestState + | undefined = undefined; if (creator_id) { const getCreatorForm: GetPersonDetails = { person_id: creator_id, auth, }; - creatorDetailsResponse = client.getPersonDetails(getCreatorForm); + creatorDetailsResponse = await client.getPersonDetails(getCreatorForm); } const query = getSearchQueryFromQuery(q); - let searchResponse: Promise | undefined = undefined; - let resolveObjectResponse: - | Promise - | undefined = undefined; + let searchResponse: RequestState | undefined = undefined; + let resolveObjectResponse: RequestState | undefined = + undefined; if (query) { const form: SearchForm = { @@ -409,13 +423,13 @@ export class Search extends Component { }; if (query !== "") { - searchResponse = client.search(form); + searchResponse = await client.search(form); if (auth) { const resolveObjectForm: ResolveObject = { q: query, auth, }; - resolveObjectResponse = client + resolveObjectResponse = await client .resolveObject(resolveObjectForm) .catch(() => undefined); } @@ -450,9 +464,10 @@ export class Search extends Component { {this.selects} {this.searchForm} {this.displayResults(type)} - {this.resultsCount === 0 && !this.state.searchLoading && ( - {i18n.t("no_results")} - )} + {this.resultsCount === 0 && + this.state.searchRes.state === "success" && ( + {i18n.t("no_results")} + )} ); @@ -493,7 +508,7 @@ export class Search extends Component { minLength={1} />