import { Component, linkEvent } from 'inferno'; import { Link } from 'inferno-router'; import { Subscription } from "rxjs"; import { retryWhen, delay, take } from 'rxjs/operators'; import { WebSocketService, UserService } from '../services'; import { UserOperation, GetRepliesForm, GetRepliesResponse, SortType, GetSiteResponse } from '../interfaces'; import { msgOp } from '../utils'; import { version } from '../version'; interface NavbarState { isLoggedIn: boolean; expanded: boolean; expandUserDropdown: boolean; unreadCount: number; siteName: string; } export class Navbar extends Component { private wsSub: Subscription; private userSub: Subscription; emptyState: NavbarState = { isLoggedIn: (UserService.Instance.user !== undefined), unreadCount: 0, expanded: false, expandUserDropdown: false, siteName: undefined } constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; this.handleOverviewClick = this.handleOverviewClick.bind(this); this.keepFetchingReplies(); // Subscribe to user changes this.userSub = UserService.Instance.sub.subscribe(user => { this.state.isLoggedIn = user.user !== undefined; this.state.unreadCount = user.unreadCount; this.setState(this.state); }); this.wsSub = WebSocketService.Instance.subject .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10)))) .subscribe( (msg) => this.parseMessage(msg), (err) => console.error(err), () => console.log('complete') ); WebSocketService.Instance.getSite(); } render() { return (
{this.navbar()}
) } componentWillUnmount() { this.wsSub.unsubscribe(); this.userSub.unsubscribe(); } // TODO class active corresponding to current page navbar() { return ( ); } expandUserDropdown(i: Navbar) { i.state.expandUserDropdown = !i.state.expandUserDropdown; i.setState(i.state); } handleLogoutClick(i: Navbar) { i.state.expandUserDropdown = false; UserService.Instance.logout(); i.context.router.history.push('/'); } handleOverviewClick(i: Navbar) { i.state.expandUserDropdown = false; i.setState(i.state); let userPage = `/u/${UserService.Instance.user.username}`; i.context.router.history.push(userPage); } expandNavbar(i: Navbar) { i.state.expanded = !i.state.expanded; i.setState(i.state); } parseMessage(msg: any) { let op: UserOperation = msgOp(msg); if (msg.error) { return; } else if (op == UserOperation.GetReplies) { let res: GetRepliesResponse = msg; this.sendRepliesCount(res); } else if (op == UserOperation.GetSite) { let res: GetSiteResponse = msg; if (res.site) { this.state.siteName = res.site.name; WebSocketService.Instance.site = res.site; this.setState(this.state); } } } keepFetchingReplies() { this.fetchReplies(); setInterval(() => this.fetchReplies(), 30000); } fetchReplies() { if (this.state.isLoggedIn) { let repliesForm: GetRepliesForm = { sort: SortType[SortType.New], unread_only: true, page: 1, limit: 9999, }; WebSocketService.Instance.getReplies(repliesForm); } } get currentLocation() { return this.context.router.history.location.pathname; } sendRepliesCount(res: GetRepliesResponse) { UserService.Instance.sub.next({user: UserService.Instance.user, unreadCount: res.replies.filter(r => !r.read).length}); } }