move windows by zIndex instead of rearranging them, to keep scroll positions
This commit is contained in:
parent
403a5493e5
commit
a2ca757e0b
|
@ -52,6 +52,7 @@ const Window = ({ id }) => {
|
||||||
width, height,
|
width, height,
|
||||||
xPos, yPos,
|
xPos, yPos,
|
||||||
windowType,
|
windowType,
|
||||||
|
z,
|
||||||
title,
|
title,
|
||||||
open,
|
open,
|
||||||
hidden,
|
hidden,
|
||||||
|
@ -104,6 +105,7 @@ const Window = ({ id }) => {
|
||||||
top: yPos,
|
top: yPos,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
zIndex: z,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -11,15 +11,19 @@ import Window from './Window';
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
const selectWindowIds = (state) => state.windows.windows.map((win) => win.windowId);
|
const selectWindowIds = (state) => state.windows.windows.map((win) => win.windowId);
|
||||||
|
|
||||||
const WindowsRoot = () => {
|
const WindowManager = () => {
|
||||||
const windowIds = useSelector(selectWindowIds, shallowEqual);
|
const windowIds = useSelector(selectWindowIds, shallowEqual);
|
||||||
const showWindows = useSelector((state) => state.windows.showWindows);
|
const showWindows = useSelector((state) => state.windows.showWindows);
|
||||||
|
|
||||||
if (!showWindows) return null;
|
if (!showWindows) return null;
|
||||||
|
|
||||||
return windowIds.map((id) => (
|
return (
|
||||||
<Window key={id} id={id} />
|
<div id="wm">
|
||||||
));
|
{
|
||||||
|
windowIds.map((id) => (<Window key={id} id={id} />))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default WindowsRoot;
|
export default WindowManager;
|
||||||
|
|
|
@ -15,7 +15,7 @@ function useDrag(elRef, startHandler, diffHandler) {
|
||||||
const startDrag = useCallback((event) => {
|
const startDrag = useCallback((event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
startHandler();
|
startHandler && startHandler();
|
||||||
|
|
||||||
let {
|
let {
|
||||||
clientX: startX,
|
clientX: startX,
|
||||||
|
|
|
@ -15,7 +15,7 @@ const imageStyle = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Archive = () => (
|
const Archive = () => (
|
||||||
<p style={{ textAlign: 'center', paddingLeft: '5%', paddingRight: '5%' }}>
|
<div style={{ textAlign: 'center', paddingLeft: '5%', paddingRight: '5%' }}>
|
||||||
<p className="modaltext">
|
<p className="modaltext">
|
||||||
{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. \
|
{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.`}<br />
|
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.`}<br />
|
||||||
|
@ -42,7 +42,7 @@ Those canvases can get boring after a while and after weeks of no major change a
|
||||||
alt="political-compass"
|
alt="political-compass"
|
||||||
src="https://storage.pixelplanet.fun/compass-final.png"
|
src="https://storage.pixelplanet.fun/compass-final.png"
|
||||||
/>
|
/>
|
||||||
</p>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Archive;
|
export default Archive;
|
||||||
|
|
|
@ -21,7 +21,7 @@ const CanvasSelect = ({ windowId }) => {
|
||||||
[dispatch]);
|
[dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p style={{
|
<div style={{
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
paddingLeft: '5%',
|
paddingLeft: '5%',
|
||||||
paddingRight: '5%',
|
paddingRight: '5%',
|
||||||
|
@ -51,7 +51,7 @@ const CanvasSelect = ({ windowId }) => {
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</p>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ const MIN_HEIGHT = 50;
|
||||||
// if screen smaller than this, hide all windows and just
|
// if screen smaller than this, hide all windows and just
|
||||||
// allow Modals
|
// allow Modals
|
||||||
const SCREEN_WIDTH_THRESHOLD = 604;
|
const SCREEN_WIDTH_THRESHOLD = 604;
|
||||||
|
// how many windows can be open
|
||||||
|
const MAX_AMOUNT_WINDOWS = 100;
|
||||||
|
|
||||||
function generateWindowId(state) {
|
function generateWindowId(state) {
|
||||||
let windowId = Math.floor(Math.random() * 99999) + 1;
|
let windowId = Math.floor(Math.random() * 99999) + 1;
|
||||||
|
@ -24,6 +26,9 @@ function generateWindowId(state) {
|
||||||
return windowId;
|
return windowId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clamp size and position to screen borders and restrictions
|
||||||
|
*/
|
||||||
function clampSize(prefWidth, prefHeight, margin = false) {
|
function clampSize(prefWidth, prefHeight, margin = false) {
|
||||||
const width = prefWidth || 550;
|
const width = prefWidth || 550;
|
||||||
const height = prefHeight || 330;
|
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 = {
|
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"
|
// modal is considerd as "fullscreen window"
|
||||||
// its windowId is considered 0 and args are under args[0]
|
// its windowId is considered 0 and args are under args[0]
|
||||||
showWindows: boolean,
|
|
||||||
modal: {
|
modal: {
|
||||||
windowType: ?string,
|
windowType: ?string,
|
||||||
title: ?string,
|
title: ?string,
|
||||||
|
@ -90,6 +114,7 @@ export type WindowsState = {
|
||||||
// windowId: number,
|
// windowId: number,
|
||||||
// open: boolean,
|
// open: boolean,
|
||||||
// hidden: boolean,
|
// hidden: boolean,
|
||||||
|
// z: number,
|
||||||
// windowType: string,
|
// windowType: string,
|
||||||
// title: string,
|
// title: string,
|
||||||
// width: number,
|
// width: number,
|
||||||
|
@ -110,6 +135,7 @@ export type WindowsState = {
|
||||||
|
|
||||||
const initialState: WindowsState = {
|
const initialState: WindowsState = {
|
||||||
showWindows: true,
|
showWindows: true,
|
||||||
|
zMax: 0,
|
||||||
modal: {
|
modal: {
|
||||||
windowType: null,
|
windowType: null,
|
||||||
title: null,
|
title: null,
|
||||||
|
@ -168,16 +194,19 @@ export default function windows(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (state.windows.length >= MAX_AMOUNT_WINDOWS) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
const windowId = generateWindowId(state);
|
const windowId = generateWindowId(state);
|
||||||
return {
|
const newZMax = state.zMax + 1;
|
||||||
...state,
|
let newWindows = [
|
||||||
windows: [
|
|
||||||
...state.windows,
|
...state.windows,
|
||||||
{
|
{
|
||||||
windowId,
|
windowId,
|
||||||
windowType,
|
windowType,
|
||||||
open: true,
|
open: true,
|
||||||
hidden: false,
|
hidden: false,
|
||||||
|
z: newZMax,
|
||||||
title,
|
title,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
@ -185,12 +214,16 @@ export default function windows(
|
||||||
yPos,
|
yPos,
|
||||||
cloneable,
|
cloneable,
|
||||||
},
|
},
|
||||||
],
|
];
|
||||||
|
return sortWindows({
|
||||||
|
...state,
|
||||||
|
zMax: newZMax,
|
||||||
|
windows: newWindows,
|
||||||
args: {
|
args: {
|
||||||
...state.args,
|
...state.args,
|
||||||
[windowId]: args,
|
[windowId]: args,
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'REMOVE_WINDOW': {
|
case 'REMOVE_WINDOW': {
|
||||||
|
@ -349,9 +382,7 @@ export default function windows(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const newWindows = state.windows.map((win) => {
|
const newWindows = state.windows.map((win) => {
|
||||||
if (win.windowId !== windowId) {
|
if (win.windowId !== windowId) return win;
|
||||||
return win;
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
...win,
|
...win,
|
||||||
windowType,
|
windowType,
|
||||||
|
@ -369,22 +400,30 @@ export default function windows(
|
||||||
windowId,
|
windowId,
|
||||||
} = action;
|
} = action;
|
||||||
const {
|
const {
|
||||||
windows: oldWindows,
|
windows: oldWindows, zMax,
|
||||||
} = state;
|
} = state;
|
||||||
if (oldWindows.length === 0
|
|
||||||
|| oldWindows[oldWindows.length - 1].windowId === windowId
|
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;
|
return state;
|
||||||
}
|
}
|
||||||
const newWindows = oldWindows.filter((w) => w.windowId !== windowId);
|
newWindows.push({
|
||||||
const win = oldWindows.find((w) => w.windowId === windowId);
|
...win,
|
||||||
if (win) {
|
z: zMax + 1,
|
||||||
newWindows.push(win);
|
});
|
||||||
}
|
}
|
||||||
return {
|
}
|
||||||
|
return sortWindows({
|
||||||
...state,
|
...state,
|
||||||
|
zMax: zMax + 1,
|
||||||
windows: newWindows,
|
windows: newWindows,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'MAXIMIZE_WINDOW': {
|
case 'MAXIMIZE_WINDOW': {
|
||||||
|
|
|
@ -127,6 +127,11 @@ tr:nth-child(even) {
|
||||||
background-color: #dddddd;
|
background-color: #dddddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#wm {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
.window {
|
.window {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
background-color: rgba(252, 252, 252, 0.95);
|
background-color: rgba(252, 252, 252, 0.95);
|
||||||
|
@ -134,7 +139,6 @@ tr:nth-child(even) {
|
||||||
border-width: thin;
|
border-width: thin;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
z-index: 3;
|
|
||||||
transition: opacity 200ms ease-in-out;
|
transition: opacity 200ms ease-in-out;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user