treat Modal equal to Window, move them to WindowManager
This commit is contained in:
parent
43c2f1d012
commit
196e701150
|
@ -7,6 +7,7 @@ import { useSelector, useDispatch } from 'react-redux';
|
|||
|
||||
import GlobalCaptcha from './GlobalCaptcha';
|
||||
import BanInfo from './BanInfo';
|
||||
import Overlay from './Overlay';
|
||||
import { closeAlert } from '../store/actions';
|
||||
|
||||
const Alert = () => {
|
||||
|
@ -25,14 +26,12 @@ const Alert = () => {
|
|||
dispatch(closeAlert());
|
||||
}, [dispatch]);
|
||||
|
||||
const onTransitionEnd = () => {
|
||||
if (!open) setRender(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
if (open) setRender(true);
|
||||
}, 10);
|
||||
if (open) {
|
||||
window.setTimeout(() => {
|
||||
setRender(true);
|
||||
}, 10);
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
let Content = null;
|
||||
|
@ -47,37 +46,43 @@ const Alert = () => {
|
|||
// nothing
|
||||
}
|
||||
|
||||
if (!render && !open) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const show = open && render;
|
||||
|
||||
return (
|
||||
(render || open) && (
|
||||
<div>
|
||||
<div
|
||||
className={(open && render)
|
||||
? 'OverlayAlert show'
|
||||
: 'OverlayAlert'}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
tabIndex={-1}
|
||||
onClick={close}
|
||||
/>
|
||||
<div
|
||||
className={(open && render) ? 'Alert show' : 'Alert'}
|
||||
>
|
||||
<h2>{title}</h2>
|
||||
{(message) && (
|
||||
<p className="modaltext">
|
||||
{message}
|
||||
</p>
|
||||
)}
|
||||
{(Content) ? (
|
||||
<Content close={close} />
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={close}
|
||||
>{btn}</button>
|
||||
)}
|
||||
</div>
|
||||
<>
|
||||
<Overlay
|
||||
z={6}
|
||||
show={show}
|
||||
onClick={close}
|
||||
/>
|
||||
(render || open) && (
|
||||
<div
|
||||
className={(show) ? 'Alert show' : 'Alert'}
|
||||
onTransitionEnd={() => {
|
||||
if (!open) setRender(false);
|
||||
}}
|
||||
>
|
||||
<h2>{title}</h2>
|
||||
{(message) && (
|
||||
<p className="modaltext">
|
||||
{message}
|
||||
</p>
|
||||
)}
|
||||
{(Content) ? (
|
||||
<Content close={close} />
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={close}
|
||||
>{btn}</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
)
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ import ChatButton from './buttons/ChatButton';
|
|||
import Menu from './Menu';
|
||||
import UI from './UI';
|
||||
import ExpandMenuButton from './buttons/ExpandMenuButton';
|
||||
import ModalRoot from './ModalRoot';
|
||||
import WindowManager from './WindowManager';
|
||||
|
||||
const iconContextValue = { style: { verticalAlign: 'middle' } };
|
||||
|
@ -32,7 +31,6 @@ const App = () => (
|
|||
<CoordinatesBox />
|
||||
<ExpandMenuButton />
|
||||
<UI />
|
||||
<ModalRoot />
|
||||
<WindowManager />
|
||||
</IconContext.Provider>
|
||||
</div>
|
||||
|
|
|
@ -41,7 +41,7 @@ function ChatMessage({
|
|||
const pArray = parseParagraph(msg);
|
||||
|
||||
return (
|
||||
<li className="chatmsg">
|
||||
<li className="chatmsg" ref={refEmbed}>
|
||||
{(!isInfo && !isEvent)
|
||||
&& (
|
||||
<div className="chathead" key="ch">
|
||||
|
@ -86,7 +86,6 @@ function ChatMessage({
|
|||
<div className={className} key="cm">
|
||||
<MarkdownParagraph refEmbed={refEmbed} pArray={pArray} />
|
||||
</div>
|
||||
<div className="chatembed" ref={refEmbed} key="ce" />
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -20,14 +20,14 @@ const keepState = {
|
|||
/*
|
||||
* sorting function for array sort
|
||||
*/
|
||||
function compare(a, b) {
|
||||
function compare(a, b, asc) {
|
||||
if (typeof a === 'string' && typeof b === 'string') {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
if (a === 'N/A') a = 0;
|
||||
if (b === 'N/A') b = 0;
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
if (a < b) return (asc) ? -1 : 1;
|
||||
if (a > b) return (asc) ? 1 : -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ function ModWatchtools() {
|
|||
const [tlcoords, selectTLCoords] = useState(keepState.tlcoords);
|
||||
const [brcoords, selectBRCoords] = useState(keepState.brcoords);
|
||||
const [interval, selectInterval] = useState(keepState.interval);
|
||||
const [sortAsc, setSortAsc] = useState(true);
|
||||
const [sortBy, setSortBy] = useState(0);
|
||||
const [table, setTable] = useState({});
|
||||
const [iid, selectIid] = useState(keepState.iid);
|
||||
|
@ -266,116 +267,121 @@ function ModWatchtools() {
|
|||
{(rows && columns && types) && (
|
||||
<React.Fragment key="pxltable">
|
||||
<div className="modaldivider" />
|
||||
<table
|
||||
style={{
|
||||
userSelect: 'text',
|
||||
fontSize: 11,
|
||||
}}
|
||||
>
|
||||
<table style={{ fontSize: 11 }} >
|
||||
<thead>
|
||||
<tr>
|
||||
{columns.slice(1).map((col, ind) => (
|
||||
<th
|
||||
key={col}
|
||||
style={
|
||||
(sortBy - 1 === ind)
|
||||
? { fontWeight: 'normal' }
|
||||
: { cursor: 'pointer' }
|
||||
(sortBy - 1 === ind) ? {
|
||||
cursor: 'pointer',
|
||||
fontWeight: 'normal',
|
||||
} : {
|
||||
cursor: 'pointer',
|
||||
}
|
||||
}
|
||||
onClick={() => setSortBy(ind + 1)}
|
||||
onClick={() => {
|
||||
if (sortBy - 1 === ind) {
|
||||
setSortAsc(!sortAsc);
|
||||
} else {
|
||||
setSortBy(ind + 1);
|
||||
}
|
||||
}}
|
||||
>{col}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.sort((a, b) => compare(a[sortBy], b[sortBy])).map((row) => (
|
||||
<tr key={row[0]}>
|
||||
{row.slice(1).map((val, ind) => {
|
||||
const type = types[ind + 1];
|
||||
switch (type) {
|
||||
case 'ts': {
|
||||
const date = new Date(val);
|
||||
let minutes = date.getMinutes();
|
||||
if (minutes < 10) minutes = `0${minutes}`;
|
||||
return (
|
||||
<td title={date.toLocaleDateString()}>
|
||||
{`${date.getHours()}:${minutes}`}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
case 'clr': {
|
||||
const cid = (cidColumn > 0)
|
||||
? row[cidColumn] : selectedCanvas;
|
||||
const rgb = canvases[cid]
|
||||
<tbody style={{ userSelect: 'text' }}>
|
||||
{rows.sort((a, b) => compare(a[sortBy], b[sortBy], sortAsc))
|
||||
.map((row) => (
|
||||
<tr key={row[0]}>
|
||||
{row.slice(1).map((val, ind) => {
|
||||
const type = types[ind + 1];
|
||||
switch (type) {
|
||||
case 'ts': {
|
||||
const date = new Date(val);
|
||||
let minutes = date.getMinutes();
|
||||
if (minutes < 10) minutes = `0${minutes}`;
|
||||
return (
|
||||
<td title={date.toLocaleDateString()}>
|
||||
{`${date.getHours()}:${minutes}`}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
case 'clr': {
|
||||
const cid = (cidColumn > 0)
|
||||
? row[cidColumn] : selectedCanvas;
|
||||
const rgb = canvases[cid]
|
||||
&& canvases[cid].colors
|
||||
&& canvases[cid].colors[val];
|
||||
if (!rgb) {
|
||||
if (!rgb) {
|
||||
return (<td>{val}</td>);
|
||||
}
|
||||
const color = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`;
|
||||
return (
|
||||
<td style={{ backgroundColor: color }}>{val}</td>
|
||||
);
|
||||
}
|
||||
case 'coord': {
|
||||
const cid = (cidColumn > 0)
|
||||
? row[cidColumn] : selectedCanvas;
|
||||
const ident = canvases[cid] && canvases[cid].ident;
|
||||
const coords = `./#${ident},${val},47`;
|
||||
return (
|
||||
<td>
|
||||
<a href={coords}>{val}</a>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
case 'flag': {
|
||||
const flag = val.toLowerCase();
|
||||
return (
|
||||
<td title={val}><img
|
||||
style={{
|
||||
height: '1em',
|
||||
imageRendering: 'crisp-edges',
|
||||
}}
|
||||
alt={val}
|
||||
src={`${window.ssv.assetserver}/cf/${flag}.gif`}
|
||||
/></td>
|
||||
);
|
||||
}
|
||||
case 'cid': {
|
||||
const ident = canvases[val] && canvases[val].ident;
|
||||
return (<td>{ident}</td>);
|
||||
}
|
||||
case 'uuid': {
|
||||
return (
|
||||
<td>
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={-1}
|
||||
style={{ cursor: 'pointer' }}
|
||||
title={t`Copy to Clipboard`}
|
||||
onClick={() => copyTextToClipboard(val)}
|
||||
>{val}</span>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
case 'user': {
|
||||
const seperator = val.lastIndexOf(',');
|
||||
if (seperator === -1) {
|
||||
return (<td>{val}</td>);
|
||||
}
|
||||
return (
|
||||
<td title={val.slice(seperator + 1)}>
|
||||
{val.slice(0, seperator)}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
default: {
|
||||
return (<td>{val}</td>);
|
||||
}
|
||||
const color = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`;
|
||||
return (
|
||||
<td style={{ backgroundColor: color }}>{val}</td>
|
||||
);
|
||||
}
|
||||
case 'coord': {
|
||||
const cid = (cidColumn > 0)
|
||||
? row[cidColumn] : selectedCanvas;
|
||||
const ident = canvases[cid] && canvases[cid].ident;
|
||||
const coords = `./#${ident},${val},47`;
|
||||
return (
|
||||
<td>
|
||||
<a href={coords}>{val}</a>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
case 'flag': {
|
||||
const flag = val.toLowerCase();
|
||||
return (
|
||||
<td title={val}><img
|
||||
style={{
|
||||
height: '1em',
|
||||
imageRendering: 'crisp-edges',
|
||||
}}
|
||||
alt={val}
|
||||
src={`${window.ssv.assetserver}/cf/${flag}.gif`}
|
||||
/></td>
|
||||
);
|
||||
}
|
||||
case 'cid': {
|
||||
const ident = canvases[val] && canvases[val].ident;
|
||||
return (<td>{ident}</td>);
|
||||
}
|
||||
case 'uuid': {
|
||||
return (
|
||||
<td>
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={-1}
|
||||
style={{ cursor: 'pointer' }}
|
||||
title={t`Copy to Clipboard`}
|
||||
onClick={() => copyTextToClipboard(val)}
|
||||
>{val}</span>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
case 'user': {
|
||||
const seperator = val.lastIndexOf(',');
|
||||
if (seperator === -1) {
|
||||
return (<td>{val}</td>);
|
||||
}
|
||||
return (
|
||||
<td title={val.slice(seperator + 1)}>
|
||||
{val.slice(0, seperator)}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
default: {
|
||||
return (<td>{val}</td>);
|
||||
}
|
||||
}
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* https://stackoverflow.com/questions/35623656/how-can-i-display-a-modal-dialog-in-redux-that-performs-asynchronous-actions/35641680#35641680
|
||||
*
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { MdClose } from 'react-icons/md';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import {
|
||||
closeWindow,
|
||||
restoreWindow,
|
||||
removeWindow,
|
||||
} from '../store/actions';
|
||||
import COMPONENTS from './windows';
|
||||
|
||||
const ModalRoot = () => {
|
||||
const [render, setRender] = useState(false);
|
||||
|
||||
const { windowType, open, title } = useSelector(
|
||||
(state) => state.windows.modal,
|
||||
);
|
||||
const showWindows = useSelector((state) => state.windows.showWindows);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const onTransitionEnd = () => {
|
||||
if (!open) {
|
||||
setRender(false);
|
||||
dispatch(removeWindow(0));
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
if (open) setRender(true);
|
||||
}, 10);
|
||||
}, [open]);
|
||||
|
||||
if (!windowType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [Content, name] = COMPONENTS[windowType];
|
||||
|
||||
return (
|
||||
(render || open) && (
|
||||
<>
|
||||
<div
|
||||
className={(open && render)
|
||||
? 'OverlayModal show'
|
||||
: 'OverlayModal'}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
tabIndex={-1}
|
||||
onClick={() => dispatch(closeWindow(0))}
|
||||
/>
|
||||
<div
|
||||
className={(open && render) ? 'Modal show' : 'Modal'}
|
||||
>
|
||||
<h2>{(title) ? `${name} - ${title}` : name}</h2>
|
||||
<div
|
||||
onClick={() => dispatch(closeWindow(0))}
|
||||
className="ModalClose"
|
||||
role="button"
|
||||
label="close"
|
||||
title={t`Close`}
|
||||
tabIndex={-1}
|
||||
><MdClose /></div>
|
||||
{(showWindows) && (
|
||||
<div
|
||||
onClick={() => dispatch(restoreWindow())}
|
||||
className="ModalRestore"
|
||||
role="button"
|
||||
label="restore"
|
||||
title={t`Restore`}
|
||||
tabIndex={-1}
|
||||
>↓</div>
|
||||
)}
|
||||
<div className="Modal-content">
|
||||
<Content windowId={0} />
|
||||
</div>
|
||||
</div>,
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ModalRoot);
|
37
src/components/Overlay.jsx
Normal file
37
src/components/Overlay.jsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Overlay to fade out background
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
const Overlay = ({ show, onClick, z }) => {
|
||||
const [render, setRender] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (show) {
|
||||
window.setTimeout(() => {
|
||||
setRender(true);
|
||||
}, 10);
|
||||
}
|
||||
}, [show]);
|
||||
|
||||
if (!render && !show) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={(show && render)
|
||||
? 'overlay show'
|
||||
: 'overlay'}
|
||||
style={(z) ? { zIndex: z } : {}}
|
||||
onTransitionEnd={() => {
|
||||
if (!show) setRender(false);
|
||||
}}
|
||||
tabIndex={-1}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(Overlay);
|
|
@ -13,7 +13,7 @@ import {
|
|||
removeWindow,
|
||||
resizeWindow,
|
||||
closeWindow,
|
||||
maximizeWindow,
|
||||
toggleMaximizeWindow,
|
||||
cloneWindow,
|
||||
focusWindow,
|
||||
} from '../store/actions';
|
||||
|
@ -30,22 +30,76 @@ const Window = ({ id }) => {
|
|||
const resizeRef = useRef(null);
|
||||
|
||||
const win = useSelector((state) => selectWindowById(state, id));
|
||||
const showWindows = useSelector((state) => state.windows.showWindows);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const focus = useCallback(() => dispatch(focusWindow(id)), []);
|
||||
const clone = (evt) => {
|
||||
const {
|
||||
open,
|
||||
hidden,
|
||||
fullscreen,
|
||||
} = win;
|
||||
|
||||
const focus = useCallback(() => {
|
||||
dispatch(focusWindow(id));
|
||||
}, [dispatch]);
|
||||
|
||||
const clone = useCallback((evt) => {
|
||||
evt.stopPropagation();
|
||||
dispatch(cloneWindow(id));
|
||||
};
|
||||
const maximize = (evt) => {
|
||||
evt.stopPropagation();
|
||||
dispatch(maximizeWindow(id));
|
||||
};
|
||||
const close = (evt) => {
|
||||
}, [dispatch]);
|
||||
|
||||
const toggleMaximize = useCallback((evt) => {
|
||||
setRender(false);
|
||||
}, [dispatch]);
|
||||
|
||||
const close = useCallback((evt) => {
|
||||
evt.stopPropagation();
|
||||
dispatch(closeWindow(id));
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
useDrag(
|
||||
titleBarRef,
|
||||
focus,
|
||||
useCallback((xDiff, yDiff) => dispatch(
|
||||
moveWindow(id, xDiff, yDiff),
|
||||
), [fullscreen, !render && hidden]),
|
||||
);
|
||||
|
||||
useDrag(
|
||||
resizeRef,
|
||||
focus,
|
||||
useCallback((xDiff, yDiff) => dispatch(
|
||||
resizeWindow(id, xDiff, yDiff),
|
||||
), [fullscreen, !render && hidden]),
|
||||
);
|
||||
|
||||
const onTransitionEnd = useCallback(() => {
|
||||
if (hidden) {
|
||||
setRender(false);
|
||||
return;
|
||||
}
|
||||
if (!open) {
|
||||
dispatch(removeWindow(id));
|
||||
return;
|
||||
}
|
||||
if (!render) {
|
||||
dispatch(toggleMaximizeWindow(id));
|
||||
setTimeout(() => setRender(true), 10);
|
||||
}
|
||||
}, [dispatch, hidden, open, render]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open && !hidden) {
|
||||
window.setTimeout(() => {
|
||||
setRender(true);
|
||||
}, 10);
|
||||
}
|
||||
}, [open, hidden]);
|
||||
|
||||
if (!render && (hidden || !open)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
width, height,
|
||||
|
@ -53,50 +107,62 @@ const Window = ({ id }) => {
|
|||
windowType,
|
||||
z,
|
||||
title,
|
||||
open,
|
||||
hidden,
|
||||
} = win;
|
||||
|
||||
useDrag(
|
||||
titleBarRef,
|
||||
focus,
|
||||
useCallback((xDiff, yDiff) => dispatch(moveWindow(id, xDiff, yDiff)),
|
||||
[hidden]),
|
||||
);
|
||||
|
||||
useDrag(
|
||||
resizeRef,
|
||||
focus,
|
||||
useCallback((xDiff, yDiff) => dispatch(resizeWindow(id, xDiff, yDiff)),
|
||||
[hidden]),
|
||||
);
|
||||
|
||||
const onTransitionEnd = () => {
|
||||
if (hidden) {
|
||||
setRender(false);
|
||||
}
|
||||
if (!open) {
|
||||
dispatch(removeWindow(id));
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.setTimeout(() => {
|
||||
if (open && !hidden) setRender(true);
|
||||
}, 10);
|
||||
}, [open, hidden]);
|
||||
|
||||
const [Content, name] = COMPONENTS[windowType];
|
||||
|
||||
if (!render && hidden) {
|
||||
const windowTitle = (title) ? `${name} - ${title}` : name;
|
||||
const extraClasses = `${windowType}${
|
||||
(open && !hidden && render) ? ' show' : ''}`;
|
||||
|
||||
if (fullscreen) {
|
||||
return (
|
||||
<div
|
||||
className={`modal ${extraClasses}`}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
onClick={focus}
|
||||
style={{
|
||||
zIndex: z,
|
||||
}}
|
||||
>
|
||||
<h2>{windowTitle}</h2>
|
||||
<div
|
||||
onClick={close}
|
||||
className="ModalClose"
|
||||
role="button"
|
||||
label="close"
|
||||
key="closebtn"
|
||||
title={t`Close`}
|
||||
tabIndex={-1}
|
||||
>✕</div>
|
||||
{(showWindows) && (
|
||||
<div
|
||||
onClick={toggleMaximize}
|
||||
className="ModalRestore"
|
||||
key="resbtn"
|
||||
role="button"
|
||||
label="restore"
|
||||
title={t`Restore`}
|
||||
tabIndex={-1}
|
||||
>↓</div>
|
||||
)}
|
||||
<div
|
||||
className="modal-content"
|
||||
key="content"
|
||||
>
|
||||
<Content windowId={id} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!showWindows) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`window ${windowType}${
|
||||
(open && !hidden && render) ? ' show' : ''
|
||||
}`}
|
||||
className={`window ${extraClasses}`}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
onClick={focus}
|
||||
style={{
|
||||
|
@ -125,12 +191,12 @@ const Window = ({ id }) => {
|
|||
ref={titleBarRef}
|
||||
title={t`Move`}
|
||||
>
|
||||
{(title) ? `${name} - ${title}` : name}
|
||||
{windowTitle}
|
||||
</span>
|
||||
<span
|
||||
className="win-topbtn"
|
||||
key="maxbtn"
|
||||
onClick={maximize}
|
||||
onClick={toggleMaximize}
|
||||
title={t`Maximize`}
|
||||
>
|
||||
↑
|
||||
|
@ -146,9 +212,9 @@ const Window = ({ id }) => {
|
|||
</div>
|
||||
<div
|
||||
className="win-resize"
|
||||
key="winres"
|
||||
title={t`Resize`}
|
||||
ref={resizeRef}
|
||||
key="winres"
|
||||
>
|
||||
▨
|
||||
</div>
|
||||
|
|
|
@ -3,24 +3,35 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useSelector, shallowEqual } from 'react-redux';
|
||||
import { useSelector, shallowEqual, useDispatch } from 'react-redux';
|
||||
|
||||
import Window from './Window';
|
||||
import Overlay from './Overlay';
|
||||
import {
|
||||
closeFullscreenWindows,
|
||||
} from '../store/actions';
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
const selectWindowIds = (state) => state.windows.windows.map((win) => win.windowId);
|
||||
// eslint-disable-next-line max-len
|
||||
const selectMeta = (state) => [state.windows.showWindows, state.windows.someFullscreen];
|
||||
|
||||
const WindowManager = () => {
|
||||
const windowIds = useSelector(selectWindowIds, shallowEqual);
|
||||
const showWindows = useSelector((state) => state.windows.showWindows);
|
||||
const [showWindows, someFullscreen] = useSelector(selectMeta, shallowEqual);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
if (!showWindows) return null;
|
||||
if ((!showWindows && !someFullscreen) || !windowIds.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="wm">
|
||||
{
|
||||
windowIds.map((id) => (<Window key={id} id={id} />))
|
||||
}
|
||||
<Overlay
|
||||
show={someFullscreen}
|
||||
onClick={() => dispatch(closeFullscreenWindows())}
|
||||
/>
|
||||
{windowIds.map((id) => <Window key={id} id={id} />)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -23,8 +23,7 @@ import {
|
|||
const selectChatWindowStatus = (state) => [
|
||||
state.windows.showWindows,
|
||||
state.windows.windows.find((win) => win.windowType === 'CHAT'
|
||||
&& win.hidden === false)
|
||||
|| (state.windows.modal.open && state.windows.modal.windowType === 'CHAT'),
|
||||
&& win.hidden === false),
|
||||
state.windows.windows.find((win) => win.windowType === 'CHAT'
|
||||
&& win.hidden === true),
|
||||
];
|
||||
|
|
|
@ -46,9 +46,11 @@ function useDrag(elRef, startHandler, diffHandler) {
|
|||
document.addEventListener('mouseup', stopDrag);
|
||||
document.addEventListener('touchcancel', stopDrag);
|
||||
document.addEventListener('touchend', stopDrag);
|
||||
}, [startHandler]);
|
||||
}, [startHandler, diffHandler]);
|
||||
|
||||
useEffect(() => {
|
||||
let prevCurrent = null;
|
||||
|
||||
if (elRef.current) {
|
||||
elRef.current.addEventListener('mousedown', startDrag, {
|
||||
passive: false,
|
||||
|
@ -56,14 +58,16 @@ function useDrag(elRef, startHandler, diffHandler) {
|
|||
elRef.current.addEventListener('touchstart', startDrag, {
|
||||
passive: false,
|
||||
});
|
||||
prevCurrent = elRef.current;
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (elRef.current) {
|
||||
elRef.current.removeEventListener('mousedown', startDrag);
|
||||
elRef.current.removeEventListener('touchstart', startDrag);
|
||||
if (prevCurrent) {
|
||||
prevCurrent.removeEventListener('mousedown', startDrag);
|
||||
prevCurrent.removeEventListener('touchstart', startDrag);
|
||||
}
|
||||
};
|
||||
}, [elRef, diffHandler]);
|
||||
}, [elRef, startDrag]);
|
||||
}
|
||||
|
||||
export default useDrag;
|
||||
|
|
|
@ -86,8 +86,8 @@ export type Action =
|
|||
| { type: 'CLOSE_ALL_WINDOW_TYPE', windowType: string}
|
||||
| { type: 'FOCUS_WINDOW', windowId: number }
|
||||
| { type: 'CLONE_WINDOW', windowId: number }
|
||||
| { type: 'MAXIMIZE_WINDOW', windowId: number }
|
||||
| { type: 'RESTORE_WINDOW' }
|
||||
| { type: 'TOGGLE_MAXIMIZE_WINDOW', windowId: number }
|
||||
| { type: 'CLOSE_FULLSCREEN_WINDOWS' }
|
||||
| { type: 'MOVE_WINDOW', windowId: number, xDiff: number, yDiff: number }
|
||||
| { type: 'RESIZE_WINDOW', windowId: number, xDiff: number, yDiff: number }
|
||||
| { type: 'CHANGE_WINDOW_TYPE',
|
||||
|
|
|
@ -611,7 +611,7 @@ export function setWindowArgs(
|
|||
};
|
||||
}
|
||||
|
||||
export function showModal(modalType, title) {
|
||||
function showFullscreenWindow(modalType, title) {
|
||||
return openWindow(
|
||||
modalType,
|
||||
title,
|
||||
|
@ -620,15 +620,21 @@ export function showModal(modalType, title) {
|
|||
);
|
||||
}
|
||||
|
||||
export function closeFullscreenWindows() {
|
||||
return {
|
||||
type: 'CLOSE_FULLSCREEN_WINDOWS',
|
||||
};
|
||||
}
|
||||
|
||||
export function showSettingsModal() {
|
||||
return showModal(
|
||||
return showFullscreenWindow(
|
||||
'SETTINGS',
|
||||
'',
|
||||
);
|
||||
}
|
||||
|
||||
export function showUserAreaModal() {
|
||||
return showModal(
|
||||
return showFullscreenWindow(
|
||||
'USERAREA',
|
||||
'',
|
||||
);
|
||||
|
@ -658,34 +664,34 @@ export function setWindowTitle(windowId, title) {
|
|||
}
|
||||
|
||||
export function showRegisterModal() {
|
||||
return showModal(
|
||||
return showFullscreenWindow(
|
||||
'REGISTER',
|
||||
t`Register New Account`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showForgotPasswordModal() {
|
||||
return showModal(
|
||||
return showFullscreenWindow(
|
||||
'FORGOT_PASSWORD',
|
||||
t`Restore my Password`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showHelpModal() {
|
||||
return showModal(
|
||||
return showFullscreenWindow(
|
||||
'HELP',
|
||||
t`Welcome to PixelPlanet.fun`,
|
||||
);
|
||||
}
|
||||
export function showArchiveModal() {
|
||||
return showModal(
|
||||
return showFullscreenWindow(
|
||||
'ARCHIVE',
|
||||
t`Look at past Canvases`,
|
||||
);
|
||||
}
|
||||
|
||||
export function showCanvasSelectionModal() {
|
||||
return showModal(
|
||||
return showFullscreenWindow(
|
||||
'CANVAS_SELECTION',
|
||||
'',
|
||||
);
|
||||
|
@ -823,19 +829,13 @@ export function cloneWindow(windowId) {
|
|||
};
|
||||
}
|
||||
|
||||
export function maximizeWindow(windowId) {
|
||||
export function toggleMaximizeWindow(windowId) {
|
||||
return {
|
||||
type: 'MAXIMIZE_WINDOW',
|
||||
type: 'TOGGLE_MAXIMIZE_WINDOW',
|
||||
windowId,
|
||||
};
|
||||
}
|
||||
|
||||
export function restoreWindow() {
|
||||
return {
|
||||
type: 'RESTORE_WINDOW',
|
||||
};
|
||||
}
|
||||
|
||||
export function moveWindow(windowId, xDiff, yDiff) {
|
||||
return {
|
||||
type: 'MOVE_WINDOW',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* state for open windows and modal and its content
|
||||
* state for open windows and its content
|
||||
*/
|
||||
|
||||
import { clamp } from '../../core/utils';
|
||||
|
@ -70,8 +70,8 @@ function clampPos(prefXPos, prefYPos, width, height) {
|
|||
/*
|
||||
* resort the zIndex, remove gaps
|
||||
*/
|
||||
function sortWindows(newState) {
|
||||
if (newState.zMax >= MAX_AMOUNT_WINDOWS * 0.5) {
|
||||
function sortWindows(newState, force = false) {
|
||||
if (newState.zMax >= MAX_AMOUNT_WINDOWS * 0.5 || force) {
|
||||
const orderedZ = newState.windows.map((win) => win.z)
|
||||
.sort((a, b) => !b || (a && a >= b));
|
||||
newState.windows = newState.windows.map((win) => ({
|
||||
|
@ -86,30 +86,16 @@ function sortWindows(newState) {
|
|||
const initialState = {
|
||||
// if windows get shown, false on small screens
|
||||
showWindows: true,
|
||||
// if at least one window is in fullscreen
|
||||
someFullscreen: false,
|
||||
// highest zIndex of window
|
||||
zMax: 0,
|
||||
// modal is considerd as "fullscreen window"
|
||||
// its windowId is considered 0 and args are under args[0]
|
||||
modal: {
|
||||
windowType: null,
|
||||
title: null,
|
||||
open: false,
|
||||
// used to remember and restore the size
|
||||
// of a maximized window when restoring
|
||||
// {
|
||||
// xPos: number,
|
||||
// yPos: number,
|
||||
// width: number,
|
||||
// height: number,
|
||||
// cloneable: boolean,
|
||||
// }
|
||||
prevWinSize: {},
|
||||
},
|
||||
// [
|
||||
// {
|
||||
// windowId: number,
|
||||
// open: boolean,
|
||||
// hidden: boolean,
|
||||
// fullscreen: boolean,
|
||||
// z: number,
|
||||
// windowType: string,
|
||||
// title: string,
|
||||
|
@ -158,31 +144,8 @@ export default function windows(
|
|||
const [width, height] = clampSize(prefWidth, prefHeight, true);
|
||||
const [xPos, yPos] = clampPos(prefXPos, prefYPos, width, height);
|
||||
|
||||
// fullscreen means to open as Modal
|
||||
const fullscreen = !state.showWindows || action.fullscreen;
|
||||
if (fullscreen) {
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
windowType,
|
||||
title,
|
||||
open: true,
|
||||
prevWinSize: {
|
||||
width,
|
||||
height,
|
||||
xPos,
|
||||
yPos,
|
||||
cloneable,
|
||||
},
|
||||
},
|
||||
args: {
|
||||
...state.args,
|
||||
0: {
|
||||
...args,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (state.windows.length >= MAX_AMOUNT_WINDOWS) {
|
||||
return state;
|
||||
}
|
||||
|
@ -195,6 +158,7 @@ export default function windows(
|
|||
windowType,
|
||||
open: true,
|
||||
hidden: false,
|
||||
fullscreen,
|
||||
z: newZMax,
|
||||
title,
|
||||
width,
|
||||
|
@ -204,8 +168,14 @@ export default function windows(
|
|||
cloneable,
|
||||
},
|
||||
];
|
||||
|
||||
const someFullscreen = newWindows.some(
|
||||
(win) => win.fullscreen && win.open,
|
||||
);
|
||||
|
||||
return sortWindows({
|
||||
...state,
|
||||
someFullscreen,
|
||||
zMax: newZMax,
|
||||
windows: newWindows,
|
||||
args: {
|
||||
|
@ -224,18 +194,6 @@ export default function windows(
|
|||
const args = { ...state.args };
|
||||
delete args[windowId];
|
||||
|
||||
if (windowId === 0) {
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
windowType: null,
|
||||
title: null,
|
||||
open: false,
|
||||
prevWinSize: {},
|
||||
},
|
||||
args,
|
||||
};
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
windows: state.windows.filter((win) => win.windowId !== windowId),
|
||||
|
@ -247,15 +205,6 @@ export default function windows(
|
|||
const {
|
||||
windowId,
|
||||
} = action;
|
||||
if (windowId === 0) {
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
...state.modal,
|
||||
open: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const newWindows = state.windows.map((win) => {
|
||||
if (win.windowId !== windowId) return win;
|
||||
|
@ -264,8 +213,14 @@ export default function windows(
|
|||
open: false,
|
||||
};
|
||||
});
|
||||
|
||||
const someFullscreen = newWindows.some(
|
||||
(win) => win.fullscreen && win.open,
|
||||
);
|
||||
|
||||
return {
|
||||
...state,
|
||||
someFullscreen,
|
||||
windows: newWindows,
|
||||
};
|
||||
}
|
||||
|
@ -281,16 +236,14 @@ export default function windows(
|
|||
open: false,
|
||||
};
|
||||
});
|
||||
let { modal } = state;
|
||||
if (modal.open && modal.windowType === windowType) {
|
||||
modal = {
|
||||
...modal,
|
||||
open: false,
|
||||
};
|
||||
}
|
||||
|
||||
const someFullscreen = newWindows.some(
|
||||
(win) => win.fullscreen && win.open,
|
||||
);
|
||||
|
||||
return {
|
||||
...state,
|
||||
modal,
|
||||
someFullscreen,
|
||||
windows: newWindows,
|
||||
};
|
||||
}
|
||||
|
@ -307,16 +260,8 @@ export default function windows(
|
|||
hidden: hide,
|
||||
};
|
||||
});
|
||||
let { modal } = state;
|
||||
if (hide && modal.open && modal.windowType === windowType) {
|
||||
modal = {
|
||||
...modal,
|
||||
open: false,
|
||||
};
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
modal,
|
||||
windows: newWindows,
|
||||
};
|
||||
}
|
||||
|
@ -366,17 +311,6 @@ export default function windows(
|
|||
...action.args,
|
||||
},
|
||||
};
|
||||
if (windowId === 0) {
|
||||
return {
|
||||
...state,
|
||||
args,
|
||||
modal: {
|
||||
...state.modal,
|
||||
windowType,
|
||||
title,
|
||||
},
|
||||
};
|
||||
}
|
||||
const newWindows = state.windows.map((win) => {
|
||||
if (win.windowId !== windowId) return win;
|
||||
return {
|
||||
|
@ -385,8 +319,14 @@ export default function windows(
|
|||
title,
|
||||
};
|
||||
});
|
||||
|
||||
const someFullscreen = newWindows.some(
|
||||
(win) => win.fullscreen && win.open,
|
||||
);
|
||||
|
||||
return {
|
||||
...state,
|
||||
someFullscreen,
|
||||
args,
|
||||
windows: newWindows,
|
||||
};
|
||||
|
@ -423,89 +363,48 @@ export default function windows(
|
|||
});
|
||||
}
|
||||
|
||||
case 'MAXIMIZE_WINDOW': {
|
||||
case 'TOGGLE_MAXIMIZE_WINDOW': {
|
||||
const {
|
||||
windowId,
|
||||
} = action;
|
||||
const args = {
|
||||
...state.args,
|
||||
0: state.args[windowId],
|
||||
};
|
||||
const {
|
||||
windowType,
|
||||
title,
|
||||
xPos,
|
||||
yPos,
|
||||
width,
|
||||
height,
|
||||
cloneable,
|
||||
} = state.windows
|
||||
.find((w) => w.windowId === windowId);
|
||||
delete args[windowId];
|
||||
|
||||
const newWindows = state.windows.map((win) => {
|
||||
if (win.windowId !== windowId) return win;
|
||||
return {
|
||||
...win,
|
||||
fullscreen: !win.fullscreen,
|
||||
open: true,
|
||||
hidden: false,
|
||||
};
|
||||
});
|
||||
|
||||
const someFullscreen = newWindows.some(
|
||||
(win) => win.fullscreen && win.open,
|
||||
);
|
||||
|
||||
return {
|
||||
...state,
|
||||
modal: {
|
||||
windowType,
|
||||
title,
|
||||
open: true,
|
||||
prevWinSize: {
|
||||
xPos,
|
||||
yPos,
|
||||
width,
|
||||
height,
|
||||
cloneable,
|
||||
},
|
||||
},
|
||||
windows: state.windows.filter((w) => w.windowId !== windowId),
|
||||
args,
|
||||
someFullscreen,
|
||||
windows: newWindows,
|
||||
};
|
||||
}
|
||||
|
||||
case 'RESTORE_WINDOW': {
|
||||
const windowId = generateWindowId(state);
|
||||
const { windowType, title, prevWinSize } = state.modal;
|
||||
const [width, height] = clampSize(
|
||||
prevWinSize.width,
|
||||
prevWinSize.height,
|
||||
);
|
||||
const [xPos, yPos] = clampPos(
|
||||
prevWinSize.xPos,
|
||||
prevWinSize.yPos,
|
||||
width,
|
||||
height,
|
||||
);
|
||||
const cloneable = prevWinSize.cloneable || true;
|
||||
const newZMax = state.zMax + 1;
|
||||
return sortWindows({
|
||||
...state,
|
||||
zMax: newZMax,
|
||||
modal: {
|
||||
...state.modal,
|
||||
open: false,
|
||||
},
|
||||
windows: [
|
||||
...state.windows,
|
||||
{
|
||||
windowType,
|
||||
windowId,
|
||||
open: true,
|
||||
hidden: false,
|
||||
title,
|
||||
width,
|
||||
height,
|
||||
xPos,
|
||||
yPos,
|
||||
z: newZMax,
|
||||
cloneable,
|
||||
},
|
||||
],
|
||||
args: {
|
||||
...state.args,
|
||||
[windowId]: {
|
||||
...state.args[0],
|
||||
},
|
||||
},
|
||||
case 'CLOSE_FULLSCREEN_WINDOWS': {
|
||||
const newWindows = state.windows.map((win) => {
|
||||
if (win.fullscreen) {
|
||||
return {
|
||||
...win,
|
||||
open: false,
|
||||
};
|
||||
}
|
||||
return win;
|
||||
});
|
||||
|
||||
return {
|
||||
...state,
|
||||
someFullscreen: false,
|
||||
windows: newWindows,
|
||||
};
|
||||
}
|
||||
|
||||
case 'MOVE_WINDOW': {
|
||||
|
@ -576,8 +475,8 @@ export default function windows(
|
|||
const xMax = width - SCREEN_MARGIN_EW;
|
||||
const yMax = height - SCREEN_MARGIN_S;
|
||||
let modified = false;
|
||||
|
||||
let newWindows = [];
|
||||
|
||||
for (let i = 0; i < state.windows.length; i += 1) {
|
||||
const win = state.windows[i];
|
||||
const {
|
||||
|
@ -613,12 +512,17 @@ export default function windows(
|
|||
return false;
|
||||
});
|
||||
|
||||
return {
|
||||
const someFullscreen = state.windows.some(
|
||||
(win) => win.fullscreen && win.open,
|
||||
);
|
||||
|
||||
return sortWindows({
|
||||
...state,
|
||||
someFullscreen,
|
||||
showWindows: true,
|
||||
windows: newWindows,
|
||||
args,
|
||||
};
|
||||
}, true);
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -185,17 +185,6 @@ tr:nth-child(even) {
|
|||
z-index: 3;
|
||||
}
|
||||
|
||||
.window {
|
||||
position: fixed;
|
||||
background-color: rgba(252, 252, 252, 0.95);
|
||||
border: solid black;
|
||||
border-width: thin;
|
||||
overflow: hidden;
|
||||
padding: 3px;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.win-topbar {
|
||||
display: flex;
|
||||
height: 24px;
|
||||
|
@ -485,7 +474,7 @@ tr:nth-child(even) {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.Modal, .Alert {
|
||||
.modal, .Alert {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
|
@ -501,14 +490,25 @@ tr:nth-child(even) {
|
|||
opacity: 0;
|
||||
}
|
||||
|
||||
.Modal {
|
||||
.modal {
|
||||
height: 80%;
|
||||
width: 70%;
|
||||
max-height: 900px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.Modal-content {
|
||||
.window {
|
||||
position: fixed;
|
||||
background-color: rgba(252, 252, 252, 0.95);
|
||||
border: solid black;
|
||||
border-width: thin;
|
||||
overflow: hidden;
|
||||
padding: 3px;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
position: relative;
|
||||
width: calc(100% - 3px);
|
||||
height: calc(100% - 50px);
|
||||
|
@ -632,7 +632,7 @@ tr:nth-child(even) {
|
|||
}
|
||||
|
||||
@media (max-width: 604px) {
|
||||
.Modal, .Alert {
|
||||
.modal, .Alert {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
|
@ -647,7 +647,7 @@ tr:nth-child(even) {
|
|||
}
|
||||
}
|
||||
|
||||
.OverlayModal, .OverlayAlert {
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
|
@ -658,14 +658,6 @@ tr:nth-child(even) {
|
|||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.OverlayModal {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.OverlayAlert {
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.chatbox div .chatarea {
|
||||
height: 174px;
|
||||
}
|
||||
|
@ -948,7 +940,7 @@ tr:nth-child(even) {
|
|||
visibility: hidden;
|
||||
}
|
||||
|
||||
.Modal.show, .Alert.show, .OverlayAlert.show, .OverlayModal.show, .window.show {
|
||||
.modal.show, .Alert.show, .overlay.show, .window.show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ tr:nth-child(odd) {
|
|||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.OverlayModal, .OverlayAlert {
|
||||
.overlay {
|
||||
background: linear-gradient(175deg, #61dceaab , #ffb1e1, #ecffec, #ffb1e1, #61dceaab);
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ tr:nth-child(odd) {
|
|||
background: linear-gradient(135deg, orange , yellow, green, aqua, blue, violet);
|
||||
}
|
||||
|
||||
.Modal {
|
||||
.modal {
|
||||
background: #f4edf0 none repeat scroll 0 0;
|
||||
background-image: url("../jew.png");
|
||||
background-repeat: no-repeat;
|
||||
|
|
|
@ -86,12 +86,12 @@ tr:nth-child(even) {
|
|||
background-color: #15374fd1;
|
||||
}
|
||||
|
||||
.Modal, .Alert {
|
||||
.modal, .Alert {
|
||||
background: #444242 none repeat scroll 0 0;;
|
||||
color: #f4f4f4;
|
||||
}
|
||||
|
||||
.Modal {
|
||||
.modal {
|
||||
border-radius: 21px;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ tr:nth-child(even) {
|
|||
background-color: #6f6f75;
|
||||
}
|
||||
|
||||
.OverlayModal, .OverlayAlert {
|
||||
.overlay {
|
||||
background-color: rgba(187, 187, 187, 0.75);
|
||||
}
|
||||
|
||||
|
|
|
@ -91,12 +91,12 @@ tr:nth-child(even) {
|
|||
border-top: thin solid #ffa14c;
|
||||
}
|
||||
|
||||
.Modal, .Alert {
|
||||
.modal, .Alert {
|
||||
background: #262626 none repeat scroll 0 0;;
|
||||
color: #ff8c22;
|
||||
}
|
||||
|
||||
.Modal {
|
||||
.modal {
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ tr:nth-child(even) {
|
|||
background-color: #6f6f75;
|
||||
}
|
||||
|
||||
.OverlayModal, .OverlayAlert {
|
||||
.overlay {
|
||||
background-color: rgba(187, 187, 187, 0.75);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ tr:nth-child(even) {
|
|||
background-color: #15374fd1;
|
||||
}
|
||||
|
||||
.Modal, .Alert {
|
||||
.modal, .Alert {
|
||||
background: #444242 none repeat scroll 0 0;;
|
||||
color: #f4f4f4;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ tr:nth-child(even) {
|
|||
background-color: #6f6f75;
|
||||
}
|
||||
|
||||
.OverlayModal, .OverlayAlert {
|
||||
.overlay {
|
||||
background-color: rgba(187, 187, 187, 0.75);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
border-radius: 21px;
|
||||
}
|
||||
|
||||
.Modal {
|
||||
.modal {
|
||||
border-radius: 21px;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user