BetterDiscordApp-rauenzi/renderer/src/ui/modals/stack.jsx

76 lines
2.3 KiB
JavaScript

import React from "@modules/react";
import Events from "@modules/emitter";
import WebpackModules from "@modules/webpackmodules";
import Backdrop from "./backdrop";
const {Fragment, useState, useCallback, useEffect} = React;
const Transitions = WebpackModules.getModule(m => m?.defaultProps?.transitionAppear || m?.TransitionGroup?.defaultProps);
const TransitionGroup = Transitions.TransitionGroup ?? Transitions;
class ModalLayer extends React.Component {
constructor(props) {
super(props);
this.state = {transitionState: null};
}
componentWillEnter(finish) {
this.setState({transitionState: 0});
setTimeout(() => {
this.setState({transitionState: 1});
finish();
}, 300);
}
componentWillLeave(finish) {
this.setState({transitionState: 2});
setTimeout(() => {
this.setState({transitionState: 3});
finish();
}, 300);
}
render() {
return React.createElement("div", {className: "bd-modal-layer"}, this.props.render({
transitionState: this.state.transitionState,
onClose: this.props.onClose
}));
}
}
// ENTERING 0
// ENTERED 1
// EXITING 2
// EXITED 3
// HIDDEN 4
let modalKey = 0;
export const generateKey = key => key ? `${key}-${modalKey++}` : modalKey++;
export default function ModalStack() {
const [modals, setModals] = useState([]);
const addModal = useCallback((render, props = {}) => {
setModals(m => [...m, {...props, render}]);
}, []);
const removeModal = useCallback((key) => {
setModals(mods => mods.filter(m => {
if (m.modalKey === key && m.onClose) m.onClose();
return m.modalKey !== key;
}));
}, []);
useEffect(() => {
Events.on("open-modal", addModal);
return () => {
Events.off("open-modal", addModal);
};
}, [addModal]);
return <TransitionGroup component={Fragment}>
<Backdrop isVisible={!!modals.length} onClick={() => removeModal(modals[modals.length - 1].modalKey)} />
{modals.length && <ModalLayer key={modals[modals.length - 1].modalKey} {...modals[modals.length - 1]} onClose={() => removeModal(modals[modals.length - 1].modalKey)} />}
</TransitionGroup>;
}