import React from "react"; require("sanitize.css"); import "./app.pcss"; import "./app.scss"; import svg from "../../assets/svgs.svg.txt"; import { createRouter } from "../../router"; import { Router, Subscription } from "router5"; import { Unsubscribe } from "router5/types/types/base"; import { appendSvg, getAppendSvgString } from "./svg"; import { SsrData } from "common/types"; import { createUpdate as createPageMetaUpdate } from "../../util/pageMeta"; import { PageNotFound } from "../../screens/pageNotFound"; import { Home } from "../../screens/home"; import { Profile } from "../../screens/profile"; export type GlobalContext = { router: Router; routerState?: ReturnType; pageMeta: SsrData["result"]["pageMeta"]; updatePageMeta: Function; }; type AppState = { count: boolean; data: any }; type AppSubscriptions = { router?: Subscription | Unsubscribe; count?; reload?; }; export const RouterContext = React.createContext<{ router: Router | null }>({ router: null, }); export class App extends React.Component { state: AppState = { count: false, data: {}, }; ctx: GlobalContext; subscriptions: AppSubscriptions = {}; webSocketClient: null | { subscribe } = null; constructor(props: { ssr?: SsrData }) { super(props); let updatePageMeta = createPageMetaUpdate(); this.ctx = { router: createRouter(), pageMeta: props.ssr ? props.ssr.result.pageMeta : { title: "", description: "", keywords: "" }, updatePageMeta: () => { updatePageMeta(this.ctx.pageMeta); }, }; if (!props.ssr) { this.webSocketClient = new Faye.Client("/faye"); } this.bootstrapRouteData(props.ssr); this.bootstrapSvg(props.ssr); this.bootstrapRouter(props.ssr); } bootstrapRouteData(ssr?: SsrData) { if (ssr) { if (ssr.routeData) { this.state.data = ssr.routeData; } } else if (window["data"]) { this.state.data = window["data"]; } } bootstrapSvg(ssr?: SsrData) { if (ssr) { ssr.result.appendToBody.push(getAppendSvgString(svg)); } else { appendSvg(svg); } } bootstrapRouter(ssr?: SsrData) { if (ssr) { this.ctx.router.start(ssr.url, ssr.routerCallBack); } else { this.ctx.router.start(); } const routerState = this.ctx.router.getState(); if (routerState) this.ctx.routerState = routerState; if (ssr && !routerState) { ssr.result.pageFound = false; } } componentDidMount() { this.subscriptions.router = this.ctx.router.subscribe((state) => { this.ctx.routerState = state.route; this.setState(Object.assign({}, this.state)); }); if (this.webSocketClient) { this.subscriptions.count = this.webSocketClient.subscribe( "/count", (count) => { this.setState(Object.assign({}, this.state, { count })); } ); this.subscriptions.reload = this.webSocketClient.subscribe( "/reload", () => { location.href = location.href; } ); } } componentWillUnmount() { if (this.subscriptions.router) { (this.subscriptions.router as Unsubscribe)(); } if (this.subscriptions.count) { this.subscriptions.count.cancel(); } if (this.subscriptions.reload) { this.subscriptions.reload.cancel(); } } render() { return ( <> {this.ctx.routerState && this.ctx.routerState.name === "home" ? ( ) : null} {this.ctx.routerState && this.ctx.routerState.name === "profile" ? ( ) : null} {!this.ctx.routerState ? : null} ); } }