From c11976cdcab6ed8b0dc83b130df7768e956c9a33 Mon Sep 17 00:00:00 2001 From: HF Date: Fri, 30 Apr 2021 13:30:08 +0200 Subject: [PATCH] remember window position and size on maximize fix screen width check on receive_me fix font color in windows set default chat window size and position --- src/actions/index.js | 25 ++++- src/actions/types.js | 2 +- src/client.js | 2 +- src/reducers/windows.js | 165 +++++++++++++++++++++------- src/styles/theme-dark-round.css | 5 + src/styles/theme-dark-sstraight.css | 5 + src/styles/theme-dark.css | 5 + 7 files changed, 160 insertions(+), 49 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 9db7089..0bd844d 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -163,11 +163,9 @@ export function setMobile(mobile: boolean): Action { }; } -export function windowResize(width: number, height: number): Action { +export function windowResize(): Action { return { type: 'WINDOW_RESIZE', - width, - height, }; } @@ -572,6 +570,10 @@ export function openWindow( fullscreen: boolean, cloneable: boolean, args: Object, + xPos: number = null, + yPos: number = null, + width: number = null, + height: number = null, ): Action { return { type: 'OPEN_WINDOW', @@ -580,6 +582,10 @@ export function openWindow( fullscreen, cloneable, args, + xPos, + yPos, + width, + height, }; } @@ -823,8 +829,17 @@ export function hideAllWindowTypes( } export function openChatWindow(): Action { - return openWindow('CHAT', t`Chat`, false, true, - { chatChannel: 1, inputMessage: '' }); + return openWindow( + 'CHAT', + t`Chat`, + false, + true, + { chatChannel: 1, inputMessage: '' }, + window.innerWidth - 350 - 62, + window.innerHeight - 220 - 64, + 350, + 220, + ); } /* diff --git a/src/actions/types.js b/src/actions/types.js index 6c066de..0d0f5d3 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -35,7 +35,7 @@ export type Action = | { type: 'SET_WAIT', wait: ?number } | { type: 'RECEIVE_COOLDOWN', wait: number } | { type: 'SET_MOBILE', mobile: boolean } - | { type: 'WINDOW_RESIZE', width: number, height: number } + | { type: 'WINDOW_RESIZE'} | { type: 'COOLDOWN_END' } | { type: 'COOLDOWN_SET', coolDown: number } | { type: 'COOLDOWN_DELTA', delta: number } diff --git a/src/client.js b/src/client.js index 0d726c1..0f2820f 100644 --- a/src/client.js +++ b/src/client.js @@ -108,7 +108,7 @@ function init() { // listen for resize // function onWindowResize() { - store.dispatch(windowResize(window.innerWidth, window.innerHeight)); + store.dispatch(windowResize()); } window.addEventListener('resize', onWindowResize); onWindowResize(); diff --git a/src/reducers/windows.js b/src/reducers/windows.js index 467818c..8c6140f 100644 --- a/src/reducers/windows.js +++ b/src/reducers/windows.js @@ -24,6 +24,48 @@ function generateWindowId(state) { return windowId; } +function clampSize(prefWidth, prefHeight, margin = false) { + const width = prefWidth || 550; + const height = prefHeight || 330; + let maxWidth = window.innerWidth; + let maxHeight = window.innerHeight; + if (margin) { + maxWidth = Math.floor(maxWidth * 0.75); + maxHeight = Math.floor(maxHeight * 0.75); + } + return [ + clamp( + width, + MIN_WIDTH, + maxWidth, + ), + clamp( + height, + MIN_HEIGHT, + maxHeight, + ), + ]; +} + +function clampPos(prefXPos, prefYPos, width, height) { + const xPos = (prefXPos || prefXPos === 0) ? prefXPos + : Math.floor((window.innerWidth - width) / 2); + const yPos = (prefYPos || prefYPos === 0) ? prefYPos + : Math.floor((window.innerHeight - height) / 2); + return [ + clamp( + xPos, + SCREEN_MARGIN_EW - width, + window.innerWidth - SCREEN_MARGIN_EW, + ), + clamp( + yPos, + 0, + window.innerHeight - SCREEN_MARGIN_S, + ), + ]; +} + export type WindowsState = { // modal is considerd as "fullscreen window" // its windowId is considered 0 and args are under args[0] @@ -32,6 +74,16 @@ export type WindowsState = { windowType: ?string, title: ?string, open: boolean, + // used to remember and restore the size + // of a maximized window when restoring + // { + // xPos: number, + // yPos: number, + // width: number, + // height: number, + // cloneable: boolean, + // } + prevWinSize: Object, }, // [ // { @@ -62,6 +114,7 @@ const initialState: WindowsState = { windowType: null, title: null, open: false, + prevWinSize: {}, }, windows: [], args: {}, @@ -73,12 +126,24 @@ export default function windows( ): WindowsState { switch (action.type) { case 'OPEN_WINDOW': { + /* + * prefered xPos, yPos, height adn width + * can be given in action (but doesn't have to) + */ const { windowType, title, cloneable, args, + xPos: prefXPos, + yPos: prefYPos, + width: prefWidth, + height: prefHeight, } = action; + + const [width, height] = clampSize(prefWidth, prefHeight, true); + const [xPos, yPos] = clampPos(prefXPos, prefYPos, width, height); + const fullscreen = !state.showWindows || action.fullscreen; if (fullscreen) { return { @@ -87,6 +152,13 @@ export default function windows( windowType, title, open: true, + prevWinSize: { + width, + height, + xPos, + yPos, + cloneable, + }, }, args: { ...state.args, @@ -97,12 +169,6 @@ export default function windows( }; } const windowId = generateWindowId(state); - const { - innerWidth: screenWidth, - innerHeight: screenHeight, - } = window; - const width = Math.min(550, Math.floor(screenWidth * 0.75)); - const height = Math.min(300, Math.floor(screenHeight * 0.75)); return { ...state, windows: [ @@ -115,8 +181,8 @@ export default function windows( title, width, height, - xPos: Math.floor((screenWidth - width) / 2), - yPos: Math.floor((screenHeight - height) / 2), + xPos, + yPos, cloneable, }, ], @@ -141,6 +207,7 @@ export default function windows( windowType: null, title: null, open: false, + prevWinSize: {}, }, args, }; @@ -291,7 +358,15 @@ export default function windows( ...state.args, 0: state.args[windowId], }; - const { windowType, title } = state.windows + const { + windowType, + title, + xPos, + yPos, + width, + height, + cloneable, + } = state.windows .find((w) => w.windowId === windowId); delete args[windowId]; return { @@ -300,6 +375,13 @@ export default function windows( windowType, title, open: true, + prevWinSize: { + xPos, + yPos, + width, + height, + cloneable, + }, }, windows: state.windows.filter((w) => w.windowId !== windowId), args, @@ -308,14 +390,18 @@ export default function windows( case 'RESTORE_WINDOW': { const windowId = generateWindowId(state); - const { windowType, title } = state.modal; - const cloneable = true; - const { - innerWidth: screenWidth, - innerHeight: screenHeight, - } = window; - const width = Math.min(550, Math.floor(screenWidth * 0.75)); - const height = Math.min(300, Math.floor(screenHeight * 0.75)); + 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; return { ...state, modal: { @@ -332,8 +418,8 @@ export default function windows( title, width, height, - xPos: Math.floor((screenWidth - width) / 2), - yPos: Math.floor((screenHeight - height) / 2), + xPos, + yPos, cloneable, }, ], @@ -352,20 +438,18 @@ export default function windows( xDiff, yDiff, } = action; - const { - innerWidth: width, - innerHeight: height, - } = window; const newWindows = state.windows.map((win) => { if (win.windowId !== windowId) return win; + const [xPos, yPos] = clampPos( + win.xPos + xDiff, + win.yPos + yDiff, + win.width, + win.height, + ); return { ...win, - xPos: clamp( - win.xPos + xDiff, - -win.width + SCREEN_MARGIN_EW, - width - SCREEN_MARGIN_EW, - ), - yPos: clamp(win.yPos + yDiff, 0, height - SCREEN_MARGIN_S), + xPos, + yPos, }; }); return { @@ -382,18 +466,15 @@ export default function windows( } = action; const newWindows = state.windows.map((win) => { if (win.windowId !== windowId) return win; + const [width, height] = clampSize( + win.width + xDiff, + win.height + yDiff, + false, + ); return { ...win, - width: clamp( - win.width + xDiff, - Math.max(MIN_WIDTH, SCREEN_MARGIN_EW - win.xPos), - window.innerWidth, - ), - height: clamp( - win.height + yDiff, - MIN_HEIGHT, - window.innerHeight, - ), + width: Math.max(width, SCREEN_MARGIN_EW - win.xPos), + height, }; }); return { @@ -405,9 +486,9 @@ export default function windows( case 'RECEIVE_ME': case 'WINDOW_RESIZE': { const { - width, - height, - } = action; + innerWidth: width, + innerHeight: height, + } = window; if (width <= SCREEN_WIDTH_THRESHOLD) { return { diff --git a/src/styles/theme-dark-round.css b/src/styles/theme-dark-round.css index c8f61e8..1c5340e 100644 --- a/src/styles/theme-dark-round.css +++ b/src/styles/theme-dark-round.css @@ -33,12 +33,17 @@ tr:nth-child(even) { .window { background-color: rgba(59, 59, 59, 0.98); border-radius: 5px; + color: #f4f4f4; } .win-title { background-color: #c1c1c1; } +.win-topbar { + color: black; +} + .win-title:hover { background-color: #dedede; } diff --git a/src/styles/theme-dark-sstraight.css b/src/styles/theme-dark-sstraight.css index 67cce08..fe8b9a4 100644 --- a/src/styles/theme-dark-sstraight.css +++ b/src/styles/theme-dark-sstraight.css @@ -33,6 +33,11 @@ tr:nth-child(even) { .window { background-color: rgba(59, 59, 59, 0.98); border-radius: 4px; + color: #ff8c22; +} + +.win-topbar { + color: black; } .win-title { diff --git a/src/styles/theme-dark.css b/src/styles/theme-dark.css index 6b04e21..67263a3 100644 --- a/src/styles/theme-dark.css +++ b/src/styles/theme-dark.css @@ -32,12 +32,17 @@ tr:nth-child(even) { .window { background-color: rgba(59, 59, 59, 0.98); + color: #f4f4f4; } .win-title { background-color: #c1c1c1; } +.win-topbar { + color: black; +} + .win-title:hover { background-color: #dedede; }