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;
}