From 9978d12a7098343bdcb5c4c2e2c27920f071a816 Mon Sep 17 00:00:00 2001 From: HF Date: Fri, 12 Aug 2022 13:19:44 +0200 Subject: [PATCH] don't have chat related stuff in general window reducer, handle chat over window args directly --- .../contextmenus/UserContextMenu.jsx | 10 +- src/components/windows/Chat.jsx | 26 ++-- src/store/actions/README.md | 4 +- src/store/actions/index.js | 113 ++++++++++-------- src/store/reducers/chatRead.js | 7 +- src/store/reducers/windows.js | 58 ++------- 6 files changed, 108 insertions(+), 110 deletions(-) diff --git a/src/components/contextmenus/UserContextMenu.jsx b/src/components/contextmenus/UserContextMenu.jsx index ffbf4b1..a93cb14 100644 --- a/src/components/contextmenus/UserContextMenu.jsx +++ b/src/components/contextmenus/UserContextMenu.jsx @@ -11,10 +11,10 @@ import { } from '../hooks/clickOutside'; import { hideContextMenu, - addToChatInputMessageAndFocus, + addToChatInputMessage, startDm, setUserBlock, - setChatChannel, + setWindowArgs, } from '../../store/actions'; import { escapeMd } from '../../core/utils'; @@ -47,7 +47,7 @@ const UserContextMenu = () => { onClick={() => { const ping = `@[${escapeMd(name)}](${uid})`; dispatch( - addToChatInputMessageAndFocus(windowId, ping), + addToChatInputMessage(windowId, ping), ); close(); }} @@ -67,7 +67,9 @@ const UserContextMenu = () => { for (let i = 0; i < cids.length; i += 1) { const cid = cids[i]; if (channels[cid].length === 4 && channels[cid][3] === uid) { - dispatch(setChatChannel(windowId, cid)); + dispatch(setWindowArgs(windowId, { + chatChannel: cid, + })); close(); return; } diff --git a/src/components/windows/Chat.jsx b/src/components/windows/Chat.jsx index 5f31308..78ecf2a 100644 --- a/src/components/windows/Chat.jsx +++ b/src/components/windows/Chat.jsx @@ -14,11 +14,11 @@ import ChannelDropDown from '../contextmenus/ChannelDropDown'; import { showUserAreaModal, - setChatChannel, - setChatInputMessage, fetchChatMessages, showContextMenu, setWindowTitle, + setWindowArgs, + markChannelAsRead, } from '../../store/actions'; import SocketClient from '../../socket/SocketClient'; @@ -35,15 +35,27 @@ const Chat = ({ const dispatch = useDispatch(); const setChannel = useCallback((cid) => { - dispatch(setChatChannel(windowId, cid)); + dispatch(markChannelAsRead(cid)); + dispatch(setWindowArgs(windowId, { + chatChannel: Number(cid), + })); + }, [dispatch]); + + const setChatInputMessage = useCallback((msg) => { + dispatch(setWindowArgs(windowId, { + inputMessage: msg, + })); }, [dispatch]); const ownName = useSelector((state) => state.user.name); // eslint-disable-next-line max-len const fetching = useSelector((state) => state.fetching.fetchingChat); const { channels, messages, blocked } = useSelector((state) => state.chat); - // eslint-disable-next-line max-len - const { chatChannel, inputMessage } = useSelector((state) => state.windows.args[windowId]); + + const { + chatChannel = 1, + inputMessage = '', + } = useSelector((state) => state.windows.args[windowId]); const { stayScrolled } = useStayScrolled(listRef, { initialScroll: Infinity, @@ -89,7 +101,7 @@ const Chat = ({ if (!inptMsg) return; // send message via websocket SocketClient.sendChatMessage(inptMsg, chatChannel); - dispatch(setChatInputMessage(windowId, '')); + dispatch(setChatInputMessage('')); } /* @@ -185,7 +197,7 @@ const Chat = ({ id={`chtipt-${windowId}`} value={inputMessage} onChange={(e) => dispatch( - setChatInputMessage(windowId, e.target.value), + setChatInputMessage(e.target.value), )} autoComplete="off" maxLength="200" diff --git a/src/store/actions/README.md b/src/store/actions/README.md index 02e09ee..b62af77 100644 --- a/src/store/actions/README.md +++ b/src/store/actions/README.md @@ -71,9 +71,7 @@ export type Action = | { type: 'REMOVE_CHAT_CHANNEL', cid: number } | { type: 'MUTE_CHAT_CHANNEL', cid: number } | { type: 'UNMUTE_CHAT_CHANNEL', cid: number } - | { type: 'SET_CHAT_CHANNEL', windowId: number, cid: number } - | { type: 'SET_CHAT_INPUT_MSG', windowId: number, msg: string } - | { type: 'ADD_CHAT_INPUT_MSG', windowId: number, msg: string } + | { type: 'MARK_CHANNEL_AS_READ', cid: number } | { type: 'SET_CHAT_FETCHING', fetching: boolean } | { type: 'OPEN_WINDOW', windowType: string, diff --git a/src/store/actions/index.js b/src/store/actions/index.js index 3aad3eb..9d4edd1 100644 --- a/src/store/actions/index.js +++ b/src/store/actions/index.js @@ -473,6 +473,15 @@ function receiveChatHistory( }; } +export function markChannelAsRead( + cid, +) { + return { + type: 'MARK_CHANNEL_AS_READ', + cid, + }; +} + function setChatFetching(fetching) { return { type: 'SET_CHAT_FETCHING', @@ -553,25 +562,37 @@ export function initTimer() { /* * fullscreen means to open as modal + * Look into store/reducers/windows.js to know what it means */ export function openWindow( windowType, - title, - fullscreen, - cloneable, - args, + title = '', + args = null, + fullscreen = false, + cloneable = true, xPos = null, yPos = null, width = null, height = null, ) { + /* + * default window size + */ + if (!fullscreen + && (!xPos || !width || !yPos || !height)) { + width = 340; + height = 400; + xPos = window.innerWidth - width - 62; + yPos = window.innerHeight - height - 64; + } + return { type: 'OPEN_WINDOW', windowType, title, + args, fullscreen, cloneable, - args, xPos, yPos, width, @@ -579,13 +600,22 @@ export function openWindow( }; } +export function setWindowArgs( + windowId, + args, +) { + return { + type: 'SET_WINDOW_ARGS', + args, + }; +} + export function showModal(modalType, title) { return openWindow( modalType, title, + null, true, - false, - {}, ); } @@ -603,11 +633,17 @@ export function showUserAreaModal() { ); } -export function changeWindowType(windowId, windowType, args = null) { +export function changeWindowType( + windowId, + windowType, + title = '', + args = null, +) { return { type: 'CHANGE_WINDOW_TYPE', windowId, windowType, + title, args, }; } @@ -734,36 +770,26 @@ export function unmuteChatChannel(cid) { }; } -export function setChatChannel(windowId, cid) { - return { - type: 'SET_CHAT_CHANNEL', - windowId, - cid: Number(cid), - }; -} +export function addToChatInputMessage(windowId, msg, focus = true) { + return (dispatch, getState) => { + const args = getState().windows.args[windowId]; + let inputMessage = args && args.inputMessage; + if (!inputMessage) { + inputMessage = ''; + } else if (inputMessage.slice(-1) !== ' ') { + inputMessage += ' '; + } + inputMessage += msg; -export function setChatInputMessage(windowId, msg) { - return { - type: 'SET_CHAT_INPUT_MSG', - windowId, - msg, - }; -} + dispatch(setWindowArgs(windowId, { + inputMessage: msg, + })); -export function addToChatInputMessage(windowId, msg) { - return { - type: 'ADD_CHAT_INPUT_MSG', - windowId, - msg, - }; -} - -export function addToChatInputMessageAndFocus(windowId, msg) { - return (dispatch) => { - dispatch(addToChatInputMessage(windowId, msg)); - const inputElem = document.getElementById(`chtipt-${windowId}`); - if (inputElem) { - inputElem.focus(); + if (focus) { + const inputElem = document.getElementById(`chtipt-${windowId}`); + if (inputElem) { + inputElem.focus(); + } } }; } @@ -846,18 +872,9 @@ export function hideAllWindowTypes( } export function openChatWindow() { - const width = 350; - const height = 350; return openWindow( 'CHAT', '', - false, - true, - { chatChannel: 1, inputMessage: '' }, - window.innerWidth - width - 62, - window.innerHeight - height - 64, - width, - height, ); } @@ -876,9 +893,11 @@ export function startDm(windowId, query) { 'OK', )); } else { - const cid = Object.keys(res)[0]; + const cid = Number(Object.keys(res)[0]); dispatch(addChatChannel(res)); - dispatch(setChatChannel(windowId, cid)); + dispatch(setWindowArgs(windowId, { + chatChannel: cid, + })); } dispatch(setApiFetching(false)); }; diff --git a/src/store/reducers/chatRead.js b/src/store/reducers/chatRead.js index 17ef024..d54dd84 100644 --- a/src/store/reducers/chatRead.js +++ b/src/store/reducers/chatRead.js @@ -98,10 +98,11 @@ export default function chatRead( } case 'OPEN_WINDOW': { - const cid = action.args.chatChannel; - if (!cid) { + const { windowType } = action; + if (windowType !== 'CHAT') { return state; } + const cid = (action.args && action.args.chatChannel) || 1; return { ...state, readTs: { @@ -115,7 +116,7 @@ export default function chatRead( }; } - case 'SET_CHAT_CHANNEL': { + case 'MARK_CHANNEL_AS_READ': { const { cid } = action; return { ...state, diff --git a/src/store/reducers/windows.js b/src/store/reducers/windows.js index dceee6b..f2d0df8 100644 --- a/src/store/reducers/windows.js +++ b/src/store/reducers/windows.js @@ -113,6 +113,7 @@ const initialState = { // z: number, // windowType: string, // title: string, + // title that is additionally shown to the window-type-title // width: number, // height: number, // xPos: percentage, @@ -126,6 +127,10 @@ const initialState = { // ... // } // } + // args is a object with values defining a state of the window + // and can be set by the window itself, + // in order to remember stuff on cloning, maximizing, etc. + // Mostly it is empty or null args: {}, }; @@ -153,6 +158,7 @@ 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 { @@ -350,6 +356,7 @@ export default function windows( const { windowId, windowType, + title, } = action; const args = { ...state.args, @@ -364,7 +371,7 @@ export default function windows( modal: { ...state.modal, windowType, - title: '', + title, }, }; } @@ -373,7 +380,7 @@ export default function windows( return { ...win, windowType, - title: '', + title, }; }); return { @@ -637,34 +644,10 @@ export default function windows( }; } - /* - * args specific actions - */ - case 'ADD_CHAT_INPUT_MSG': { + case 'SET_WINDOW_ARGS': { const { windowId, - msg, - } = action; - let { inputMessage } = state.args[windowId]; - const lastChar = inputMessage.slice(-1); - const pad = (lastChar && lastChar !== ' ') ? ' ' : ''; - inputMessage += pad + msg; - return { - ...state, - args: { - ...state.args, - [windowId]: { - ...state.args[windowId], - inputMessage, - }, - }, - }; - } - - case 'SET_CHAT_CHANNEL': { - const { - windowId, - cid, + args, } = action; return { ...state, @@ -672,24 +655,7 @@ export default function windows( ...state.args, [windowId]: { ...state.args[windowId], - chatChannel: cid, - }, - }, - }; - } - - case 'SET_CHAT_INPUT_MSG': { - const { - windowId, - msg, - } = action; - return { - ...state, - args: { - ...state.args, - [windowId]: { - ...state.args[windowId], - inputMessage: msg, + ...args, }, }, };