Use custom stack
This commit is contained in:
parent
b5ad46a63f
commit
88d9687575
|
@ -1,6 +1,6 @@
|
|||
import {Config} from "data";
|
||||
import Logger from "common/logger";
|
||||
import {WebpackModules, React, ReactDOM, Settings, Strings, DOMManager} from "modules";
|
||||
import {WebpackModules, React, ReactDOM, Settings, Strings, DOMManager, Events} from "modules";
|
||||
import FormattableString from "../structs/string";
|
||||
import AddonErrorModal from "./modals/addonerrormodal";
|
||||
import ErrorBoundary from "./errorboundary";
|
||||
|
@ -14,6 +14,7 @@ import ConfirmationModal from "./modals/confirmation";
|
|||
import Button from "./base/button";
|
||||
import CustomMarkdown from "./base/markdown";
|
||||
import ChangelogModal from "./modals/changelog";
|
||||
import ModalStack, {generateKey} from "./modals/stack";
|
||||
|
||||
|
||||
export default class Modals {
|
||||
|
@ -172,7 +173,7 @@ export default class Modals {
|
|||
if (!Array.isArray(content)) content = [content];
|
||||
content = content.map(c => typeof(c) === "string" ? React.createElement(CustomMarkdown, null, c) : c);
|
||||
|
||||
const modalKey = ModalActions.openModal(props => {
|
||||
const modalKey = this.openModal(props => {
|
||||
return React.createElement(ErrorBoundary, {
|
||||
onError: () => {
|
||||
setTimeout(() => {
|
||||
|
@ -204,7 +205,7 @@ export default class Modals {
|
|||
pluginErrors: Array.isArray(pluginErrors) ? pluginErrors : [],
|
||||
themeErrors: Array.isArray(themeErrors) ? themeErrors : []
|
||||
};
|
||||
this.ModalActions.openModal(props => {
|
||||
this.openModal(props => {
|
||||
return React.createElement(ErrorBoundary, null, React.createElement(AddonErrorModal, Object.assign(options, props)));
|
||||
});
|
||||
}
|
||||
|
@ -212,7 +213,7 @@ export default class Modals {
|
|||
static showChangelogModal(options = {}) {
|
||||
options = Object.assign({image: "https://i.imgur.com/wuh5yMK.png", description: "", changes: [], title: "BetterDiscord", subtitle: `v${Config.version}`}, options);
|
||||
|
||||
const key = this.ModalActions.openModal(props => {
|
||||
const key = this.openModal(props => {
|
||||
return React.createElement(ErrorBoundary, null, React.createElement(ChangelogModal, Object.assign(options, props)));
|
||||
});
|
||||
return key;
|
||||
|
@ -263,4 +264,23 @@ export default class Modals {
|
|||
return React.createElement(ErrorBoundary, null, React.createElement(ConfirmationModal, Object.assign(options, props), child));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
static makeStack() {
|
||||
const div = DOMManager.parseHTML(`<div id="bd-modal-container">`);
|
||||
DOMManager.bdBody.append(div);
|
||||
ReactDOM.render(<ModalStack />, div);
|
||||
this.hasInitialized = true;
|
||||
}
|
||||
|
||||
static openModal(render, options = {}) {
|
||||
if (!this.hasInitialized) this.makeStack();
|
||||
options.modalKey = generateKey(options.modalKey);
|
||||
Events.emit("open-modal", render, options);
|
||||
return options.modalKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Modals.makeStack();
|
|
@ -0,0 +1,33 @@
|
|||
import {React, Utilities, WebpackModules} from "modules";
|
||||
|
||||
const Spring = WebpackModules.getByProps("useSpring", "animated");
|
||||
|
||||
|
||||
export default function Backdrop({isVisible, className, onClick}) {
|
||||
const transition = Spring.useTransition(isVisible, {
|
||||
keys: e => e ? "backdrop" : "empty",
|
||||
config: {duration: 300},
|
||||
from: {
|
||||
opacity: 0,
|
||||
background: "var(--black-500)"
|
||||
},
|
||||
enter: {
|
||||
opacity: 0.85,
|
||||
background: "var(--black-500)"
|
||||
},
|
||||
leave: {
|
||||
opacity: 0,
|
||||
background: "var(--black-500)"
|
||||
}
|
||||
});
|
||||
|
||||
return transition((styles, visible) => {
|
||||
if (!visible) return null;
|
||||
|
||||
return <Spring.animated.div
|
||||
className={Utilities.className("bd-modal-backdrop", className)}
|
||||
style={styles}
|
||||
onClick={onClick}
|
||||
/>;
|
||||
});
|
||||
}
|
|
@ -18,7 +18,8 @@ export const Styles = Object.freeze({
|
|||
|
||||
|
||||
export default function ModalRoot({className, transitionState, children, size = Sizes.DYNAMIC, style = Styles.CUSTOM}) {
|
||||
const visible = transitionState == 0 || transitionState == 1;
|
||||
const visible = transitionState == 0 || transitionState == 1; // 300 ms
|
||||
// const visible = transitionState;
|
||||
const springStyles = Spring.useSpring({
|
||||
opacity: visible ? 1 : 0,
|
||||
transform: visible ? "scale(1)" : "scale(0.7)",
|
||||
|
@ -28,12 +29,57 @@ export default function ModalRoot({className, transitionState, children, size =
|
|||
clamp: true
|
||||
}
|
||||
});
|
||||
|
||||
return <Spring.animated.div
|
||||
className={Utilities.className("bd-modal-root", size, className, style)}
|
||||
style={springStyles}
|
||||
>
|
||||
{children}
|
||||
</Spring.animated.div>;
|
||||
// const [visible, setVisible] = React.useState(true);
|
||||
|
||||
// const visible = transitionState < 2;
|
||||
// const springTransition = Spring.useTransition(transitionState, {
|
||||
// keys: e => e ? "backdrop" : "empty",
|
||||
// from: {
|
||||
// opacity: 0,
|
||||
// transform: "scale(0.7)"
|
||||
// },
|
||||
// enter: {
|
||||
// opacity: 1,
|
||||
// transform: "scale(1)"
|
||||
// },
|
||||
// leave: {
|
||||
// opacity: 0,
|
||||
// transform: "scale(0.7)"
|
||||
// },
|
||||
// // config: (a, b, c, d) => {
|
||||
// // console.log({a, b, c, d});
|
||||
// // return {
|
||||
// // duration: a ? 300 : 100,
|
||||
// // easing: a ? Anims.Easing.inOut(Anims.Easing.back()) : Anims.Easing.quad,
|
||||
// // clamp: true
|
||||
// // };
|
||||
// // }
|
||||
// config: (a, b, c) => {
|
||||
// console.log({a, b, c});
|
||||
// return {
|
||||
// duration: true ? 300 : 100,
|
||||
// easing: true ? Anims.Easing.inOut(Anims.Easing.back()) : Anims.Easing.quad,
|
||||
// clamp: true
|
||||
// };
|
||||
// }
|
||||
// });
|
||||
|
||||
// return springTransition((styles, isVisible) => {
|
||||
// if (!isVisible) console.log("not visible");
|
||||
// return <Spring.animated.div
|
||||
// className={Utilities.className("bd-modal-root", size, className, style)}
|
||||
// style={styles}
|
||||
// >
|
||||
// {children}
|
||||
// </Spring.animated.div>;
|
||||
// });
|
||||
}
|
||||
|
||||
ModalRoot.Sizes = Sizes;
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
import {React, Events, WebpackModules} from "modules";
|
||||
import Backdrop from "./backdrop";
|
||||
|
||||
const {Fragment, useState, useCallback, useEffect} = React;
|
||||
|
||||
|
||||
const Transitions = WebpackModules.getModule(m => m?.defaultProps?.transitionAppear);
|
||||
// const Transitions = WebpackModules.getByProps("TransitionGroup").TransitionGroup;
|
||||
|
||||
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 <Transitions 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)} />}
|
||||
</Transitions>;
|
||||
}
|
Loading…
Reference in New Issue