import React from "react" import { Switch, Route, BrowserRouter, withRouter } from "react-router-dom" const NotFoundRender = () => { return
Not found
} const paths = { ...import.meta.glob("/src/debug/components/**/[a-z[]*.jsx"), ...import.meta.glob("/src/pages/**/[a-z[]*.jsx"), ...import.meta.glob("/src/pages/**/[a-z[]*.tsx"), } const pathsMobile = { ...import.meta.glob("/src/pages/**/[a-z[]*.mobile.jsx"), ...import.meta.glob("/src/pages/**/[a-z[]*.mobile.tsx"), } const routes = Object.keys(paths).map((route) => { const path = route .replace(/\/src\/pages|index|\.jsx$/g, "") .replace(/\/src\/pages|index|\.tsx$/g, "") .replace(/\/src\/debug\/components/g, "/debug") .replace(/\[\.{3}.+\]/, "*") .replace(/\[(.+)\]/, ":$1") return { path, component: React.lazy(paths[route]) } }) const mobileComponents = Object.fromEntries(Object.keys(pathsMobile).map((route) => { const path = route .replace(/\/src\/pages|index|\.mobile|\.jsx$/g, "") .replace(/\/src\/pages|index|\.mobile|\.tsx$/g, "") .replace(/\/src\/debug\/components/g, "/debug") .replace(/\[\.{3}.+\]/, "*") .replace(/\[(.+)\]/, ":$1") return [path, React.lazy(pathsMobile[route])] })) export function BindContexts(component) { let contexts = { main: {}, app: {}, } if (typeof component.bindApp === "string") { if (component.bindApp === "all") { Object.keys(app).forEach((key) => { contexts.app[key] = app[key] }) } } else { if (Array.isArray(component.bindApp)) { component.bindApp.forEach((key) => { contexts.app[key] = app[key] }) } } if (typeof component.bindMain === "string") { if (component.bindMain === "all") { Object.keys(main).forEach((key) => { contexts.main[key] = main[key] }) } } else { if (Array.isArray(component.bindMain)) { component.bindMain.forEach((key) => { contexts.main[key] = main[key] }) } } return (props) => React.createElement(component, { ...props, contexts }) } export const Router = withRouter((props) => { const defaultTransitionDelay = 150 const forceUpdate = React.useReducer(() => ({}))[1] React.useEffect(() => { props.history.listen((event) => { if (typeof props.onTransitionFinish === "function") { props.onTransitionFinish(event) } window.app.eventBus.emit("router.transitionFinish", event) }) props.history.setLocation = (to, state = {}, delay = 150) => { // clean double slashes to = to.replace(/\/{2,}/g, "/") // if state is a number, it's a delay if (typeof state !== "object") { delay = state state = {} } const lastLocation = props.history.lastLocation if (typeof lastLocation !== "undefined" && lastLocation?.pathname === to && lastLocation?.state === state) { return false } if (typeof props.onTransitionStart === "function") { props.onTransitionStart(delay) } window.app.eventBus.emit("router.transitionStart", delay) setTimeout(() => { props.history.push({ pathname: to, }, state) props.history.lastLocation = window.location }, delay ?? defaultTransitionDelay) } window.app.eventBus.on(`router.forceUpdate`, forceUpdate) props.history.lastLocation = window.location window.app.setLocation = props.history.setLocation }, []) const router = { history: props.history, lastLocation: props.history.lastLocation, forceUpdate, } // return children with router in props return React.cloneElement(props.children, { router }) }) export const InternalRouter = (props) => { return } export const PageRender = (props) => { return {routes.map(({ path, component: Component = React.Fragment }) => { if (window.isMobile) { if (mobileComponents[path]) { Component = mobileComponents[path] } else { console.warn(`No mobile component for ${path}, using default`) } } const generateRenderComponent = (props) => { return React.createElement(BindContexts(Component), { ...props, history: props.history, }) } return })} } export default { routes, BindContexts, InternalRouter, PageRender, }