comty/packages/app/src/layout.jsx
2023-02-24 14:38:48 +00:00

160 lines
3.9 KiB
JavaScript
Executable File

import React from "react"
import progressBar from "nprogress"
import Layouts from "layouts"
export default class Layout extends React.PureComponent {
progressBar = progressBar.configure({ parent: "html", showSpinner: false })
state = {
layoutType: "default",
renderError: null,
}
events = {
"layout.forceUpdate": () => {
this.forceUpdate()
},
"layout.animations.fadeOut": () => {
if (app.cores.settings.get("reduceAnimations")) {
console.warn("Skipping fadeIn animation due to `reduceAnimations` setting")
return false
}
const transitionLayer = document.getElementById("transitionLayer")
if (!transitionLayer) {
console.warn("transitionLayer not found, no animation will be played")
return false
}
transitionLayer.classList.add("fade-opacity-leave")
},
"layout.animations.fadeIn": () => {
if (app.cores.settings.get("reduceAnimations")) {
console.warn("Skipping fadeOut animation due to `reduceAnimations` setting")
return false
}
const transitionLayer = document.getElementById("transitionLayer")
if (!transitionLayer) {
console.warn("transitionLayer not found, no animation will be played")
return false
}
transitionLayer.classList.remove("fade-opacity-leave")
},
"router.navigate": (path, options) => {
this.makePageTransition(path, options)
},
}
componentDidMount() {
if (window.app.cores.settings.get("forceMobileMode") || window.app.capacitor.isAppCapacitor() || Math.min(window.screen.width, window.screen.height) < 768 || navigator.userAgent.indexOf("Mobi") > -1) {
window.isMobile = true
app.layout.set("mobile")
} else {
window.isMobile = false
}
// register events
Object.keys(this.events).forEach((event) => {
window.app.eventBus.on(event, this.events[event])
})
}
componentWillUnmount() {
// unregister events
Object.keys(this.events).forEach((event) => {
window.app.eventBus.off(event, this.events[event])
})
}
componentDidCatch(info, stack) {
this.setState({ renderError: { info, stack } })
}
makePageTransition(path, options = {}) {
this.progressBar.start()
if (app.cores.settings.get("reduceAnimations") || options.state?.noTransition) {
this.progressBar.done()
return false
}
const transitionLayer = document.getElementById("transitionLayer")
if (!transitionLayer) {
console.warn("transitionLayer not found, no animation will be played")
return false
}
transitionLayer.classList.add("fade-transverse-leave")
setTimeout(() => {
this.progressBar.done()
transitionLayer.classList.remove("fade-transverse-leave")
}, options.state?.transitionDelay ?? 250)
}
layoutInterface = window.app.layout = {
set: (layout) => {
if (typeof Layouts[layout] !== "function") {
return console.error("Layout not found")
}
console.log(`Setting layout to [${layout}]`)
return this.setState({
layoutType: layout,
})
},
toogleCenteredContent: (to) => {
const root = document.getElementById("root")
if (!root) {
console.error("root not found")
return false
}
to = typeof to === "boolean" ? to : !root.classList.contains("centered-content")
if (to === true) {
root.classList.add("centered_content")
} else {
root.classList.remove("centered_content")
}
}
}
render() {
let layoutType = this.state.layoutType
const layoutComponentProps = {
...this.props.bindProps,
...this.state,
}
if (this.state.renderError) {
if (this.props.staticRenders?.RenderError) {
return React.createElement(this.props.staticRenders?.RenderError, { error: this.state.renderError })
}
return JSON.stringify(this.state.renderError)
}
const Layout = Layouts[layoutType]
if (!Layout) {
return app.eventBus.emit("runtime.crash", new Error(`Layout type [${layoutType}] not found`))
}
return <Layout {...layoutComponentProps}>
{this.props.children}
</Layout>
}
}