diff --git a/src/components/Window.jsx b/src/components/Window.jsx index f404ad6..7c898d5 100644 --- a/src/components/Window.jsx +++ b/src/components/Window.jsx @@ -52,6 +52,7 @@ const Window = ({ id }) => { width, height, xPos, yPos, windowType, + z, title, open, hidden, @@ -104,6 +105,7 @@ const Window = ({ id }) => { top: yPos, width, height, + zIndex: z, }} >
state.windows.windows.map((win) => win.windowId); -const WindowsRoot = () => { +const WindowManager = () => { const windowIds = useSelector(selectWindowIds, shallowEqual); const showWindows = useSelector((state) => state.windows.showWindows); if (!showWindows) return null; - return windowIds.map((id) => ( - - )); + return ( +
+ { + windowIds.map((id) => ()) + } +
+ ); }; -export default WindowsRoot; +export default WindowManager; diff --git a/src/components/hooks/drag.js b/src/components/hooks/drag.js index e30f6ec..d7388a9 100644 --- a/src/components/hooks/drag.js +++ b/src/components/hooks/drag.js @@ -15,7 +15,7 @@ function useDrag(elRef, startHandler, diffHandler) { const startDrag = useCallback((event) => { event.preventDefault(); event.stopPropagation(); - startHandler(); + startHandler && startHandler(); let { clientX: startX, diff --git a/src/components/windows/Archive.jsx b/src/components/windows/Archive.jsx index 3593eff..40bf2ac 100644 --- a/src/components/windows/Archive.jsx +++ b/src/components/windows/Archive.jsx @@ -15,7 +15,7 @@ const imageStyle = { }; const Archive = () => ( -

+

{t`While we tend to not delete canvases, some canvases are started for fun or as a request by users who currently like a meme. \ Those canvases can get boring after a while and after weeks of no major change and if they really aren't worth being kept active, we decide to remove them.`}
@@ -42,7 +42,7 @@ Those canvases can get boring after a while and after weeks of no major change a alt="political-compass" src="https://storage.pixelplanet.fun/compass-final.png" /> -

+
); export default Archive; diff --git a/src/components/windows/CanvasSelect.jsx b/src/components/windows/CanvasSelect.jsx index 5e5921d..1b11f78 100644 --- a/src/components/windows/CanvasSelect.jsx +++ b/src/components/windows/CanvasSelect.jsx @@ -21,7 +21,7 @@ const CanvasSelect = ({ windowId }) => { [dispatch]); return ( -

{ ) )) } -

+
); }; diff --git a/src/reducers/windows.js b/src/reducers/windows.js index 289b5e5..44ab288 100644 --- a/src/reducers/windows.js +++ b/src/reducers/windows.js @@ -15,6 +15,8 @@ const MIN_HEIGHT = 50; // if screen smaller than this, hide all windows and just // allow Modals const SCREEN_WIDTH_THRESHOLD = 604; +// how many windows can be open +const MAX_AMOUNT_WINDOWS = 100; function generateWindowId(state) { let windowId = Math.floor(Math.random() * 99999) + 1; @@ -24,6 +26,9 @@ function generateWindowId(state) { return windowId; } +/* + * clamp size and position to screen borders and restrictions + */ function clampSize(prefWidth, prefHeight, margin = false) { const width = prefWidth || 550; const height = prefHeight || 330; @@ -66,10 +71,29 @@ function clampPos(prefXPos, prefYPos, width, height) { ]; } +/* + * resort the zIndex, remove gaps + */ +function sortWindows(newState) { + if (newState.zMax >= MAX_AMOUNT_WINDOWS * 0.5) { + const orderedZ = newState.windows.map((win) => win.z) + .sort((a, b) => !b || (a && a >= b)); + newState.windows = newState.windows.map((win) => ({ + ...win, + z: orderedZ.indexOf(win.z), + })); + newState.zMax = orderedZ.length - 1; + } + return newState; +} + export type WindowsState = { + // if windows get shown, false on small screens + showWindows: boolean, + // highest zIndex of window + zMax: number, // modal is considerd as "fullscreen window" // its windowId is considered 0 and args are under args[0] - showWindows: boolean, modal: { windowType: ?string, title: ?string, @@ -90,6 +114,7 @@ export type WindowsState = { // windowId: number, // open: boolean, // hidden: boolean, + // z: number, // windowType: string, // title: string, // width: number, @@ -110,6 +135,7 @@ export type WindowsState = { const initialState: WindowsState = { showWindows: true, + zMax: 0, modal: { windowType: null, title: null, @@ -168,29 +194,36 @@ export default function windows( }, }; } + if (state.windows.length >= MAX_AMOUNT_WINDOWS) { + return state; + } const windowId = generateWindowId(state); - return { + const newZMax = state.zMax + 1; + let newWindows = [ + ...state.windows, + { + windowId, + windowType, + open: true, + hidden: false, + z: newZMax, + title, + width, + height, + xPos, + yPos, + cloneable, + }, + ]; + return sortWindows({ ...state, - windows: [ - ...state.windows, - { - windowId, - windowType, - open: true, - hidden: false, - title, - width, - height, - xPos, - yPos, - cloneable, - }, - ], + zMax: newZMax, + windows: newWindows, args: { ...state.args, [windowId]: args, }, - }; + }); } case 'REMOVE_WINDOW': { @@ -349,9 +382,7 @@ export default function windows( }; } const newWindows = state.windows.map((win) => { - if (win.windowId !== windowId) { - return win; - } + if (win.windowId !== windowId) return win; return { ...win, windowType, @@ -369,22 +400,30 @@ export default function windows( windowId, } = action; const { - windows: oldWindows, + windows: oldWindows, zMax, } = state; - if (oldWindows.length === 0 - || oldWindows[oldWindows.length - 1].windowId === windowId - ) { - return state; + + let newWindows = []; + + for (let i = 0; i < oldWindows.length; i += 1) { + const win = oldWindows[i]; + if (win.windowId !== windowId) { + newWindows.push(win); + } else { + if (win.z === zMax) { + return state; + } + newWindows.push({ + ...win, + z: zMax + 1, + }); + } } - const newWindows = oldWindows.filter((w) => w.windowId !== windowId); - const win = oldWindows.find((w) => w.windowId === windowId); - if (win) { - newWindows.push(win); - } - return { + return sortWindows({ ...state, + zMax: zMax + 1, windows: newWindows, - }; + }); } case 'MAXIMIZE_WINDOW': { diff --git a/src/styles/default.css b/src/styles/default.css index e160a6b..46e2ce0 100644 --- a/src/styles/default.css +++ b/src/styles/default.css @@ -127,6 +127,11 @@ tr:nth-child(even) { background-color: #dddddd; } +#wm { + position: absolute; + z-index: 3; +} + .window { position: fixed; background-color: rgba(252, 252, 252, 0.95); @@ -134,7 +139,6 @@ tr:nth-child(even) { border-width: thin; overflow: hidden; padding: 3px; - z-index: 3; transition: opacity 200ms ease-in-out; opacity: 0; }