X-Git-Url: http://these/git/?a=blobdiff_plain;f=src%2Fshared%2Fcomponents%2Fsearch.tsx;h=99b180356b87c5ab89f789a795c49c81f9ef8645;hb=53c3cfeade90150b07431386745a24aa699a25ec;hp=c1f9ff4572ebc35b496f145276097e743a2a3fb0;hpb=f7ace27477fccdaf57b4ed546f484c24a5390e76;p=lemmy-ui.git diff --git a/src/shared/components/search.tsx b/src/shared/components/search.tsx index c1f9ff4..99b1803 100644 --- a/src/shared/components/search.tsx +++ b/src/shared/components/search.tsx @@ -1,7 +1,31 @@ +import { + commentsToFlatNodes, + communityToChoice, + enableDownvotes, + enableNsfw, + fetchCommunities, + fetchUsers, + getUpdatedSearchId, + myAuth, + personToChoice, + setIsoData, + showLocal, +} from "@utils/app"; +import { restoreScrollPosition, saveScrollPosition } from "@utils/browser"; +import { + capitalizeFirstLetter, + debounce, + getIdFromString, + getPageFromString, + getQueryParams, + getQueryString, + numToSI, +} from "@utils/helpers"; +import type { QueryParams } from "@utils/types"; +import { Choice, RouteDataResponse } from "@utils/types"; import type { NoOptionI18nKeys } from "i18next"; import { Component, linkEvent } from "inferno"; import { - CommentResponse, CommentView, CommunityView, GetCommunity, @@ -12,8 +36,7 @@ import { ListCommunities, ListCommunitiesResponse, ListingType, - PersonViewSafe, - PostResponse, + PersonView, PostView, ResolveObject, ResolveObjectResponse, @@ -21,47 +44,11 @@ import { SearchResponse, SearchType, SortType, - UserOperation, - wsJsonToRes, - wsUserOp, } from "lemmy-js-client"; -import { Subscription } from "rxjs"; -import { i18n } from "../i18next"; +import { fetchLimit } from "../config"; import { CommentViewType, InitialFetchRequest } from "../interfaces"; -import { WebSocketService } from "../services"; -import { - Choice, - QueryParams, - capitalizeFirstLetter, - commentsToFlatNodes, - communityToChoice, - createCommentLikeRes, - createPostLikeFindRes, - debounce, - enableDownvotes, - enableNsfw, - fetchCommunities, - fetchLimit, - fetchUsers, - getIdFromString, - getPageFromString, - getQueryParams, - getQueryString, - getUpdatedSearchId, - myAuth, - numToSI, - personToChoice, - restoreScrollPosition, - routeListingTypeToEnum, - routeSearchTypeToEnum, - routeSortTypeToEnum, - saveScrollPosition, - setIsoData, - showLocal, - toast, - wsClient, - wsSubscribe, -} from "../utils"; +import { FirstLoadService, I18NextService } from "../services"; +import { HttpService, RequestState } from "../services/HttpService"; import { CommentNodes } from "./comment/comment-nodes"; import { HtmlTags } from "./common/html-tags"; import { Spinner } from "./common/icon"; @@ -83,40 +70,42 @@ interface SearchProps { page: number; } +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 { type_: string; - data: CommentView | PostView | CommunityView | PersonViewSafe; + data: CommentView | PostView | CommunityView | PersonView; published: string; } -const defaultSearchType = SearchType.All; -const defaultSortType = SortType.TopAll; -const defaultListingType = ListingType.All; +const defaultSearchType = "All"; +const defaultSortType = "TopAll"; +const defaultListingType = "All"; -const searchTypes = [ - SearchType.All, - SearchType.Comments, - SearchType.Posts, - SearchType.Communities, - SearchType.Users, - SearchType.Url, -]; +const searchTypes = ["All", "Comments", "Posts", "Communities", "Users", "Url"]; const getSearchQueryParams = () => getQueryParams({ @@ -132,38 +121,49 @@ const getSearchQueryParams = () => const getSearchQueryFromQuery = (q?: string): string | undefined => q ? decodeURIComponent(q) : undefined; -const getSearchTypeFromQuery = (type_?: string): SearchType => - routeSearchTypeToEnum(type_ ?? "", defaultSearchType); +function getSearchTypeFromQuery(type_?: string): SearchType { + return type_ ? (type_ as SearchType) : defaultSearchType; +} -const getSortTypeFromQuery = (sort?: string): SortType => - routeSortTypeToEnum(sort ?? "", defaultSortType); +function getSortTypeFromQuery(sort?: string): SortType { + return sort ? (sort as SortType) : defaultSortType; +} -const getListingTypeFromQuery = (listingType?: string): ListingType => - routeListingTypeToEnum(listingType ?? "", defaultListingType); +function getListingTypeFromQuery(listingType?: string): ListingType { + return listingType ? (listingType as ListingType) : defaultListingType; +} -const postViewToCombined = (data: PostView): Combined => ({ - type_: "posts", - data, - published: data.post.published, -}); +function postViewToCombined(data: PostView): Combined { + return { + type_: "posts", + data, + published: data.post.published, + }; +} -const commentViewToCombined = (data: CommentView): Combined => ({ - type_: "comments", - data, - published: data.comment.published, -}); +function commentViewToCombined(data: CommentView): Combined { + return { + type_: "comments", + data, + published: data.comment.published, + }; +} -const communityViewToCombined = (data: CommunityView): Combined => ({ - type_: "communities", - data, - published: data.community.published, -}); +function communityViewToCombined(data: CommunityView): Combined { + return { + type_: "communities", + data, + published: data.community.published, + }; +} -const personViewSafeToCombined = (data: PersonViewSafe): Combined => ({ - type_: "users", - data, - published: data.person.published, -}); +function personViewSafeToCombined(data: PersonView): Combined { + return { + type_: "users", + data, + published: data.person.published, + }; +} const Filter = ({ filterType, @@ -181,15 +181,15 @@ const Filter = ({ loading: boolean; }) => { return ( -
-
@@ -703,11 +865,18 @@ export class Search extends Component { } get communities() { - const { searchResponse, resolveObjectResponse } = this.state; - const communities = searchResponse?.communities ?? []; - - if (resolveObjectResponse?.community) { - communities.unshift(resolveObjectResponse.community); + const { + searchRes: searchResponse, + resolveObjectRes: resolveObjectResponse, + } = this.state; + const communities = + searchResponse.state === "success" ? searchResponse.data.communities : []; + + if ( + resolveObjectResponse.state === "success" && + resolveObjectResponse.data.community + ) { + communities.unshift(resolveObjectResponse.data.community); } return ( @@ -722,11 +891,18 @@ export class Search extends Component { } get users() { - const { searchResponse, resolveObjectResponse } = this.state; - const users = searchResponse?.users ?? []; - - if (resolveObjectResponse?.person) { - users.unshift(resolveObjectResponse.person); + const { + searchRes: searchResponse, + resolveObjectRes: resolveObjectResponse, + } = this.state; + const users = + searchResponse.state === "success" ? searchResponse.data.users : []; + + if ( + resolveObjectResponse.state === "success" && + resolveObjectResponse.data.person + ) { + users.unshift(resolveObjectResponse.data.person); } return ( @@ -741,71 +917,72 @@ export class Search extends Component { } get resultsCount(): number { - const { searchResponse: r, resolveObjectResponse: resolveRes } = this.state; - - const searchCount = r - ? r.posts.length + - r.comments.length + - r.communities.length + - r.users.length - : 0; - - const resObjCount = resolveRes - ? resolveRes.post || - resolveRes.person || - resolveRes.community || - resolveRes.comment - ? 1 - : 0 - : 0; + const { searchRes: r, resolveObjectRes: resolveRes } = this.state; + + const searchCount = + r.state === "success" + ? r.data.posts.length + + r.data.comments.length + + r.data.communities.length + + r.data.users.length + : 0; + + const resObjCount = + resolveRes.state === "success" + ? resolveRes.data.post || + resolveRes.data.person || + resolveRes.data.community || + resolveRes.data.comment + ? 1 + : 0 + : 0; return resObjCount + searchCount; } - search() { - const auth = myAuth(false); + async search() { + const auth = myAuth(); const { searchText: q } = this.state; const { communityId, creatorId, type, sort, listingType, page } = getSearchQueryParams(); - if (q && q !== "") { - const form: SearchForm = { - q, - community_id: communityId ?? undefined, - creator_id: creatorId ?? undefined, - type_: type, - sort, - listing_type: listingType, - page, - limit: fetchLimit, - auth, - }; - - const resolveObjectForm: ResolveObject = { - q, - auth, - }; - + if (q) { + this.setState({ searchRes: { state: "loading" } }); this.setState({ - searchResponse: undefined, - resolveObjectResponse: undefined, - searchLoading: true, + searchRes: await HttpService.client.search({ + q, + community_id: communityId ?? undefined, + creator_id: creatorId ?? undefined, + type_: type, + sort, + listing_type: listingType, + page, + limit: fetchLimit, + auth, + }), }); + window.scrollTo(0, 0); + restoreScrollPosition(this.context); - WebSocketService.Instance.send(wsClient.search(form)); - WebSocketService.Instance.send(wsClient.resolveObject(resolveObjectForm)); + if (auth) { + this.setState({ resolveObjectRes: { state: "loading" } }); + this.setState({ + resolveObjectRes: await HttpService.silent_client.resolveObject({ + q, + auth, + }), + }); + } } } handleCreatorSearch = debounce(async (text: string) => { const { creatorId } = getSearchQueryParams(); const { creatorSearchOptions } = this.state; - this.setState({ - searchCreatorLoading: true, - }); - const newOptions: Choice[] = []; + this.setState({ searchCreatorLoading: true }); + const selectedChoice = creatorSearchOptions.find( choice => getIdFromString(choice.value) === creatorId ); @@ -815,7 +992,7 @@ export class Search extends Component { } if (text.length > 0) { - newOptions.push(...(await fetchUsers(text)).users.map(personToChoice)); + newOptions.push(...(await fetchUsers(text)).map(personToChoice)); } this.setState({ @@ -842,9 +1019,7 @@ export class Search extends Component { } if (text.length > 0) { - newOptions.push( - ...(await fetchCommunities(text)).communities.map(communityToChoice) - ); + newOptions.push(...(await fetchCommunities(text)).map(communityToChoice)); } this.setState({ @@ -858,7 +1033,7 @@ export class Search extends Component { } handleTypeChange(i: Search, event: any) { - const type = SearchType[event.target.value]; + const type = event.target.value as SearchType; i.updateUrl({ type, @@ -904,7 +1079,7 @@ export class Search extends Component { i.setState({ searchText: event.target.value }); } - updateUrl({ + async updateUrl({ q, type, listingType, @@ -940,72 +1115,5 @@ export class Search extends Component { }; this.props.history.push(`/search${getQueryString(queryParams)}`); - - this.search(); - } - - parseMessage(msg: any) { - console.log(msg); - const op = wsUserOp(msg); - if (msg.error) { - if (msg.error === "couldnt_find_object") { - this.setState({ - resolveObjectResponse: {}, - }); - this.checkFinishedLoading(); - } else { - toast(i18n.t(msg.error), "danger"); - } - } else { - switch (op) { - case UserOperation.Search: { - const searchResponse = wsJsonToRes(msg); - this.setState({ searchResponse }); - window.scrollTo(0, 0); - this.checkFinishedLoading(); - restoreScrollPosition(this.context); - - break; - } - - case UserOperation.CreateCommentLike: { - const { comment_view } = wsJsonToRes(msg); - createCommentLikeRes( - comment_view, - this.state.searchResponse?.comments - ); - - break; - } - - case UserOperation.CreatePostLike: { - const { post_view } = wsJsonToRes(msg); - createPostLikeFindRes(post_view, this.state.searchResponse?.posts); - - break; - } - - case UserOperation.ListCommunities: { - const { communities } = wsJsonToRes(msg); - this.setState({ communities }); - - break; - } - - case UserOperation.ResolveObject: { - const resolveObjectResponse = wsJsonToRes(msg); - this.setState({ resolveObjectResponse }); - this.checkFinishedLoading(); - - break; - } - } - } - } - - checkFinishedLoading() { - if (this.state.searchResponse || this.state.resolveObjectResponse) { - this.setState({ searchLoading: false }); - } } }