summaryrefslogtreecommitdiffstats
path: root/ui/src/components/navbar.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/components/navbar.tsx')
-rw-r--r--ui/src/components/navbar.tsx130
1 files changed, 104 insertions, 26 deletions
diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx
index 4cb74391..a332f0e5 100644
--- a/ui/src/components/navbar.tsx
+++ b/ui/src/components/navbar.tsx
@@ -1,4 +1,4 @@
-import { Component, linkEvent } from 'inferno';
+import { Component, linkEvent, createRef, RefObject } from 'inferno';
import { Link } from 'inferno-router';
import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
@@ -42,11 +42,14 @@ interface NavbarState {
unreadCount: number;
siteName: string;
admins: Array<UserView>;
+ searchParam: string;
+ toggleSearch: boolean;
}
export class Navbar extends Component<any, NavbarState> {
private wsSub: Subscription;
private userSub: Subscription;
+ private searchTextField: RefObject<HTMLInputElement>;
emptyState: NavbarState = {
isLoggedIn: UserService.Instance.user !== undefined,
unreadCount: 0,
@@ -56,6 +59,8 @@ export class Navbar extends Component<any, NavbarState> {
expanded: false,
siteName: undefined,
admins: [],
+ searchParam: '',
+ toggleSearch: false,
};
constructor(props: any, context: any) {
@@ -87,6 +92,49 @@ export class Navbar extends Component<any, NavbarState> {
}
WebSocketService.Instance.getSite();
+
+ this.searchTextField = createRef();
+ }
+
+ handleSearchParam(i: Navbar, event: any) {
+ i.state.searchParam = event.target.value;
+ i.setState(i.state);
+ }
+
+ updateUrl() {
+ const searchParam = this.state.searchParam;
+ this.setState({ searchParam: '' });
+ this.setState({ toggleSearch: false });
+ if (searchParam === '') {
+ this.context.router.history.push(`/search/`);
+ } else {
+ this.context.router.history.push(
+ `/search/q/${searchParam}/type/all/sort/topall/page/1`
+ );
+ }
+ }
+
+ handleSearchSubmit(i: Navbar, event: any) {
+ event.preventDefault();
+ i.updateUrl();
+ }
+
+ handleSearchBtn(i: Navbar, event: any) {
+ event.preventDefault();
+ i.setState({ toggleSearch: true });
+
+ i.searchTextField.current.focus();
+ const offsetWidth = i.searchTextField.current.offsetWidth;
+ if (i.state.searchParam && offsetWidth > 100) {
+ i.updateUrl();
+ }
+ }
+
+ handleSearchBlur(i: Navbar, event: any) {
+ if (!(event.relatedTarget && event.relatedTarget.name !== 'search-btn')) {
+ i.state.toggleSearch = false;
+ i.setState(i.state);
+ }
}
render() {
@@ -133,7 +181,7 @@ export class Navbar extends Component<any, NavbarState> {
<div
className={`${!this.state.expanded && 'collapse'} navbar-collapse`}
>
- <ul class="navbar-nav mr-auto">
+ <ul class="navbar-nav my-2 mr-auto">
<li class="nav-item">
<Link
class="nav-link"
@@ -144,11 +192,6 @@ export class Navbar extends Component<any, NavbarState> {
</Link>
</li>
<li class="nav-item">
- <Link class="nav-link" to="/search" title={i18n.t('search')}>
- {i18n.t('search')}
- </Link>
- </li>
- <li class="nav-item">
<Link
class="nav-link"
to={{
@@ -181,9 +224,39 @@ export class Navbar extends Component<any, NavbarState> {
</Link>
</li>
</ul>
- <ul class="navbar-nav ml-auto">
+ {!this.context.router.history.location.pathname.match(
+ /^\/search/
+ ) && (
+ <form
+ class="form-inline"
+ onSubmit={linkEvent(this, this.handleSearchSubmit)}
+ >
+ <input
+ class={`form-control mr-0 search-input ${
+ this.state.toggleSearch ? 'show-input' : 'hide-input'
+ }`}
+ onInput={linkEvent(this, this.handleSearchParam)}
+ value={this.state.searchParam}
+ ref={this.searchTextField}
+ type="text"
+ placeholder={i18n.t('search')}
+ onBlur={linkEvent(this, this.handleSearchBlur)}
+ ></input>
+ <button
+ name="search-btn"
+ onClick={linkEvent(this, this.handleSearchBtn)}
+ class="btn btn-link"
+ style="color: var(--gray)"
+ >
+ <svg class="icon">
+ <use xlinkHref="#icon-search"></use>
+ </svg>
+ </button>
+ </form>
+ )}
+ <ul class="navbar-nav my-2">
{this.canAdmin && (
- <li className="nav-item mt-1">
+ <li className="nav-item">
<Link
class="nav-link"
to={`/admin`}
@@ -195,9 +268,11 @@ export class Navbar extends Component<any, NavbarState> {
</Link>
</li>
)}
- {this.state.isLoggedIn ? (
- <>
- <li className="nav-item mt-1">
+ </ul>
+ {this.state.isLoggedIn ? (
+ <>
+ <ul class="navbar-nav my-2">
+ <li className="nav-item">
<Link class="nav-link" to="/inbox" title={i18n.t('inbox')}>
<svg class="icon">
<use xlinkHref="#icon-bell"></use>
@@ -209,6 +284,8 @@ export class Navbar extends Component<any, NavbarState> {
)}
</Link>
</li>
+ </ul>
+ <ul class="navbar-nav">
<li className="nav-item">
<Link
class="nav-link"
@@ -230,17 +307,21 @@ export class Navbar extends Component<any, NavbarState> {
</span>
</Link>
</li>
- </>
- ) : (
- <Link
- class="nav-link"
- to="/login"
- title={i18n.t('login_sign_up')}
- >
- {i18n.t('login_sign_up')}
- </Link>
- )}
- </ul>
+ </ul>
+ </>
+ ) : (
+ <ul class="navbar-nav my-2">
+ <li className="nav-item">
+ <Link
+ class="nav-link"
+ to="/login"
+ title={i18n.t('login_sign_up')}
+ >
+ {i18n.t('login_sign_up')}
+ </Link>
+ </li>
+ </ul>
+ )}
</div>
</nav>
);
@@ -315,9 +396,6 @@ export class Navbar extends Component<any, NavbarState> {
if (data.site && !this.state.siteName) {
this.state.siteName = data.site.name;
this.state.admins = data.admins;
- WebSocketService.Instance.site = data.site;
- WebSocketService.Instance.admins = data.admins;
-
this.setState(this.state);
}
}