From aca2c1abecc4be7e60a190f931aab8c9be40f369 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 5 Sep 2019 18:34:10 -0700 Subject: [PATCH] Adding usable search urls - Fixes #242 --- ui/src/components/main.tsx | 3 +- ui/src/components/search.tsx | 62 ++++++++++++++++++++++++++++++++---- ui/src/index.tsx | 1 + ui/src/utils.ts | 6 +++- 4 files changed, 64 insertions(+), 8 deletions(-) diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index 48df1edd0..cce31fced 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -106,11 +106,12 @@ export class Main extends Component { // Necessary for back button for some reason componentWillReceiveProps(nextProps: any) { - if (nextProps.history.action == 'POP') { + if (nextProps.history.action == 'POP' || nextProps.history.action == 'PUSH') { this.state = this.emptyState; this.state.type_ = this.getListingTypeFromProps(nextProps); this.state.sort = this.getSortTypeFromProps(nextProps); this.state.page = this.getPageFromProps(nextProps); + this.setState(this.state); this.fetchPosts(); } } diff --git a/ui/src/components/search.tsx b/ui/src/components/search.tsx index 34a4a3d31..42e1f3173 100644 --- a/ui/src/components/search.tsx +++ b/ui/src/components/search.tsx @@ -4,7 +4,7 @@ import { Subscription } from "rxjs"; import { retryWhen, delay, take } from 'rxjs/operators'; import { UserOperation, Post, Comment, Community, UserView, SortType, SearchForm, SearchResponse, SearchType } from '../interfaces'; import { WebSocketService } from '../services'; -import { msgOp, fetchLimit } from '../utils'; +import { msgOp, fetchLimit, routeSearchTypeToEnum, routeSortTypeToEnum } from '../utils'; import { PostListing } from './post-listing'; import { CommentNodes } from './comment-nodes'; import { i18n } from '../i18next'; @@ -23,10 +23,10 @@ export class Search extends Component { private subscription: Subscription; private emptyState: SearchState = { - q: undefined, - type_: SearchType.All, - sort: SortType.TopAll, - page: 1, + q: this.getSearchQueryFromProps(this.props), + type_: this.getSearchTypeFromProps(this.props), + sort: this.getSortTypeFromProps(this.props), + page: this.getPageFromProps(this.props), searchResponse: { op: null, type_: null, @@ -38,6 +38,26 @@ export class Search extends Component { loading: false, } + getSearchQueryFromProps(props: any): string { + return (props.match.params.q) ? props.match.params.q : ''; + } + + getSearchTypeFromProps(props: any): SearchType { + return (props.match.params.type) ? + routeSearchTypeToEnum(props.match.params.type) : + SearchType.All; + } + + getSortTypeFromProps(props: any): SortType { + return (props.match.params.sort) ? + routeSortTypeToEnum(props.match.params.sort) : + SortType.TopAll; + } + + getPageFromProps(props: any): number { + return (props.match.params.page) ? Number(props.match.params.page) : 1; + } + constructor(props: any, context: any) { super(props, context); @@ -50,6 +70,10 @@ export class Search extends Component { (err) => console.error(err), () => console.log('complete') ); + + if (this.state.q) { + this.search(); + } } @@ -57,6 +81,19 @@ export class Search extends Component { this.subscription.unsubscribe(); } + // Necessary for back button for some reason + componentWillReceiveProps(nextProps: any) { + if (nextProps.history.action == 'POP' || nextProps.history.action == 'PUSH') { + this.state = this.emptyState; + this.state.q = this.getSearchQueryFromProps(nextProps); + this.state.type_ = this.getSearchTypeFromProps(nextProps); + this.state.sort = this.getSortTypeFromProps(nextProps); + this.state.page = this.getPageFromProps(nextProps); + this.setState(this.state); + this.search(); + } + } + componentDidMount() { document.title = `${i18n.t('search')} - ${WebSocketService.Instance.site.name}`; } @@ -256,12 +293,14 @@ export class Search extends Component { nextPage(i: Search) { i.state.page++; i.setState(i.state); + i.updateUrl(); i.search(); } prevPage(i: Search) { i.state.page--; i.setState(i.state); + i.updateUrl(); i.search(); } @@ -275,19 +314,23 @@ export class Search extends Component { limit: fetchLimit, }; - WebSocketService.Instance.search(form); + if (this.state.q != '') { + WebSocketService.Instance.search(form); + } } handleSortChange(i: Search, event: any) { i.state.sort = Number(event.target.value); i.state.page = 1; i.setState(i.state); + i.updateUrl(); } handleTypeChange(i: Search, event: any) { i.state.type_ = Number(event.target.value); i.state.page = 1; i.setState(i.state); + i.updateUrl(); } handleSearchSubmit(i: Search, event: any) { @@ -295,6 +338,7 @@ export class Search extends Component { i.state.loading = true; i.search(); i.setState(i.state); + i.updateUrl(); } handleQChange(i: Search, event: any) { @@ -302,6 +346,12 @@ export class Search extends Component { i.setState(i.state); } + updateUrl() { + let typeStr = SearchType[this.state.type_].toLowerCase(); + let sortStr = SortType[this.state.sort].toLowerCase(); + this.props.history.push(`/search/q/${this.state.q}/type/${typeStr}/sort/${sortStr}/page/${this.state.page}`); + } + parseMessage(msg: any) { console.log(msg); let op: UserOperation = msgOp(msg); diff --git a/ui/src/index.tsx b/ui/src/index.tsx index 63ecd53f2..7a252be21 100644 --- a/ui/src/index.tsx +++ b/ui/src/index.tsx @@ -61,6 +61,7 @@ class Index extends Component { + diff --git a/ui/src/utils.ts b/ui/src/utils.ts index fb326deb2..2d5076a52 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -7,7 +7,7 @@ import 'moment/locale/sv'; import 'moment/locale/ru'; import 'moment/locale/nl'; -import { UserOperation, Comment, User, SortType, ListingType } from './interfaces'; +import { UserOperation, Comment, User, SortType, ListingType, SearchType } from './interfaces'; import * as markdown_it from 'markdown-it'; import * as markdownitEmoji from 'markdown-it-emoji/light'; import * as markdown_it_container from 'markdown-it-container'; @@ -144,6 +144,10 @@ export function routeListingTypeToEnum(type: string): ListingType { return ListingType[capitalizeFirstLetter(type)]; } +export function routeSearchTypeToEnum(type: string): SearchType { + return SearchType[capitalizeFirstLetter(type)]; +} + export async function getPageTitle(url: string) { let res = await fetch(`https://textance.herokuapp.com/title/${url}`); let data = await res.text();