use new modal controller

This commit is contained in:
SrGooglo 2023-07-12 17:13:20 +00:00
parent effdd5cb6e
commit 4b13c84bc1
13 changed files with 206 additions and 137 deletions

View File

@ -76,13 +76,12 @@ import {
NotFound,
RenderError,
Crash,
Navigation,
Login,
UserRegister,
Searcher,
NotificationsCenter,
PostViewer,
PostCreatorModal,
PostCreator,
} from "components"
import { DOMWindow } from "components/RenderWindow"
@ -222,7 +221,7 @@ class ComtyApp extends React.Component {
})
}
return window.app.ModalController.open((props) => <Searcher renderResults {...props} />)
return app.layout.modal.open("searcher", () => <Searcher renderResults />)
},
openFullImageViewer: (src) => {
const win = new DOMWindow({
@ -239,22 +238,10 @@ class ComtyApp extends React.Component {
/>)
},
openPostViewer: (post) => {
const win = new DOMWindow({
id: "postViewer",
className: "postViewer",
})
win.render(<PostViewer post={post} />)
app.layout.modal.open("post_viewer", () => <PostViewer post={post} />)
},
openPostCreator: () => {
const win = new DOMWindow({
id: "postCreator",
className: "postCreator",
})
win.render(<PostCreatorModal
onClose={() => win.destroy()}
/>)
app.layout.modal.open("post_creator", () => <PostCreator />)
}
},
navigation: {

View File

@ -1,67 +0,0 @@
import React from "react"
import classnames from "classnames"
import PostCreator from "components/PostCreator"
import "./index.less"
export default (props) => {
const [visible, setVisible] = React.useState(false)
let escTimeout = null
const close = () => {
setVisible(false)
setTimeout(() => {
if (typeof props.onClose === "function") {
props.onClose()
}
}, 150)
}
const handleEsc = (e) => {
if (e.key === "Escape") {
if (escTimeout !== null) {
clearTimeout(escTimeout)
return close()
}
escTimeout = setTimeout(() => {
escTimeout = null
}, 250)
}
}
const handleClickOutside = (e) => {
if (e.target === e.currentTarget) {
close()
}
}
React.useEffect(() => {
setTimeout(() => {
setVisible(true)
}, 10)
document.addEventListener("keydown", handleEsc, false)
return () => {
document.removeEventListener("keydown", handleEsc, false)
}
}, [])
return <div
className={classnames(
"post_creator_modal",
{
["active"]: visible
}
)}
onClick={handleClickOutside}
>
<PostCreator
onPost={close}
/>
</div>
}

View File

@ -1,45 +0,0 @@
@import "theme/vars.less";
@modal_background_blur: 10px;
.post_creator_modal {
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
transition: all 150ms ease-in-out;
&.active {
background-color: rgba(var(--bg_color_6), 0.5);
backdrop-filter: blur(@modal_background_blur);
-webkit-backdrop-filter: blur(@modal_background_blur);
.postCreator {
opacity: 1;
transform: translateY(0);
}
}
.postCreator {
transition: all 150ms ease-in-out;
opacity: 0;
transform: translateY(100px);
}
.postCreator {
box-shadow: @card-shadow;
-webkit-box-shadow: @card-shadow;
-moz-box-shadow: @card-shadow;
}
}

View File

@ -227,5 +227,5 @@ const UserSelector = (props) => {
}
export const openModal = (props) => {
return app.ModalController.open(() => <UserSelector {...props} />)
return app.layout.modal.open("user_selector", () => <UserSelector {...props} />)
}

View File

@ -4,6 +4,12 @@
gap: 20px;
padding: 20px;
background-color: var(--background-color-accent);
border-radius: 12px;
.user-selector_actions {
display: flex;
flex-direction: row;

View File

@ -96,5 +96,5 @@ export const WidgetBrowser = (props) => {
}
export const openModal = () => {
app.ModalController.open(() => <WidgetBrowser />)
app.layout.modal.open("widgets_browser", () => <WidgetBrowser />)
}

View File

@ -1,5 +1,12 @@
.widgets_browser {
display: flex;
flex-direction: column;
gap: 20px;
padding: 30px;
background-color: var(--background-color-accent);
border-radius: 12px;
}

View File

@ -40,7 +40,6 @@ export { default as PostsList } from "./PostsList"
export { default as PostCard } from "./PostCard"
export { default as PostViewer } from "./PostViewer"
export { default as PostCreator } from "./PostCreator"
export { default as PostCreatorModal } from "./PostCreatorModal"
// COMMENTS
export { default as CommentsCard } from "./CommentsCard"

View File

@ -0,0 +1,123 @@
import React from "react"
import classnames from "classnames"
import useLayoutInterface from "hooks/useLayoutInterface"
import { DOMWindow } from "components/RenderWindow"
import "./index.less"
class Modal extends React.Component {
state = {
visible: false,
}
escTimeout = null
componentDidMount() {
setTimeout(() => {
this.setState({
visible: true,
})
}, 10)
document.addEventListener("keydown", this.handleEsc, false)
}
componentWillUnmount() {
document.removeEventListener("keydown", this.handleEsc, false)
}
close = () => {
this.setState({
visible: false,
})
setTimeout(() => {
if (typeof this.props.onClose === "function") {
this.props.onClose()
}
}, 250)
}
handleEsc = (e) => {
if (e.key === "Escape") {
if (this.escTimeout !== null) {
clearTimeout(this.escTimeout)
return this.close()
}
this.escTimeout = setTimeout(() => {
this.escTimeout = null
}, 250)
}
}
handleClickOutside = (e) => {
if (e.target === e.currentTarget) {
this.close()
}
}
render() {
return <div
className={classnames(
"app_modal_wrapper",
{
["active"]: this.state.visible
}
)}
onClick={this.handleClickOutside}
>
<div
className="app_modal_content"
onClick={this.handleClickOutside}
>
{
React.cloneElement(this.props.children, {
close: this.close
})
}
</div>
</div>
}
}
export default () => {
const modalRef = React.useRef()
function openModal(
id,
render,
{
className,
props,
} = {}
) {
const win = new DOMWindow({
id: id,
className: className,
})
win.render(<Modal
ref={modalRef}
win={win}
onClose={() => {
win.destroy()
}}
>
{
React.createElement(render, props)
}
</Modal>)
}
function closeModal() {
modalRef.current.close()
}
useLayoutInterface("modal", {
open: openModal,
close: closeModal,
})
return null
}

View File

@ -2,13 +2,16 @@ import React from "react"
import classnames from "classnames"
import { Layout } from "antd"
import { Sidebar, Drawer, Sidedrawer, Modal, BottomBar, TopBar, ToolsBar } from "components/Layout"
import { Sidebar, Drawer, Sidedrawer, BottomBar, TopBar, ToolsBar } from "components/Layout"
import BackgroundDecorator from "components/BackgroundDecorator"
import { createWithDom as FloatingStack } from "../components/floatingStack"
import InitializeModalsController from "../components/modals"
const DesktopLayout = (props) => {
InitializeModalsController()
React.useEffect(() => {
const floatingStack = FloatingStack()
@ -21,7 +24,6 @@ const DesktopLayout = (props) => {
<BackgroundDecorator />
<Layout id="app_layout" className="app_layout">
<Modal />
<Drawer />
<Sidebar />
<Sidedrawer />
@ -47,8 +49,6 @@ const DesktopLayout = (props) => {
const MobileLayout = (props) => {
return <Layout id="app_layout" className="app_layout">
<Modal />
<TopBar />
<Layout.Content

View File

@ -404,4 +404,61 @@ html {
.__react_modal_image__header {
background-color: transparent !important;
}
}
.app_modal_wrapper {
position: absolute;
top: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
transition: all 150ms ease-in-out;
&.active {
background-color: rgba(var(--bg_color_6), 0.5);
backdrop-filter: blur(@modal_background_blur);
-webkit-backdrop-filter: blur(@modal_background_blur);
.app_modal_content {
opacity: 1;
transform: translateY(0);
}
}
.app_modal_content {
transition: all 150ms ease-in-out;
opacity: 0;
transform: translateY(100px);
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
// fixments
.postCreator {
box-shadow: @card-shadow;
-webkit-box-shadow: @card-shadow;
-moz-box-shadow: @card-shadow;
}
.searcher {
width: 50vw;
height: 80vh;
}
}
}

View File

@ -15,4 +15,6 @@
@top_bar_padding: 10px;
@bottomBar_iconSize: 45px;
@topBar_height: 52px;
@topBar_height: 52px;
@modal_background_blur: 10px;