don't have chat related stuff in general window reducer, handle

chat over window args directly
This commit is contained in:
HF 2022-08-12 13:19:44 +02:00
parent 1b20d3f9e7
commit 9978d12a70
6 changed files with 108 additions and 110 deletions

View File

@ -11,10 +11,10 @@ import {
} from '../hooks/clickOutside'; } from '../hooks/clickOutside';
import { import {
hideContextMenu, hideContextMenu,
addToChatInputMessageAndFocus, addToChatInputMessage,
startDm, startDm,
setUserBlock, setUserBlock,
setChatChannel, setWindowArgs,
} from '../../store/actions'; } from '../../store/actions';
import { escapeMd } from '../../core/utils'; import { escapeMd } from '../../core/utils';
@ -47,7 +47,7 @@ const UserContextMenu = () => {
onClick={() => { onClick={() => {
const ping = `@[${escapeMd(name)}](${uid})`; const ping = `@[${escapeMd(name)}](${uid})`;
dispatch( dispatch(
addToChatInputMessageAndFocus(windowId, ping), addToChatInputMessage(windowId, ping),
); );
close(); close();
}} }}
@ -67,7 +67,9 @@ const UserContextMenu = () => {
for (let i = 0; i < cids.length; i += 1) { for (let i = 0; i < cids.length; i += 1) {
const cid = cids[i]; const cid = cids[i];
if (channels[cid].length === 4 && channels[cid][3] === uid) { if (channels[cid].length === 4 && channels[cid][3] === uid) {
dispatch(setChatChannel(windowId, cid)); dispatch(setWindowArgs(windowId, {
chatChannel: cid,
}));
close(); close();
return; return;
} }

View File

@ -14,11 +14,11 @@ import ChannelDropDown from '../contextmenus/ChannelDropDown';
import { import {
showUserAreaModal, showUserAreaModal,
setChatChannel,
setChatInputMessage,
fetchChatMessages, fetchChatMessages,
showContextMenu, showContextMenu,
setWindowTitle, setWindowTitle,
setWindowArgs,
markChannelAsRead,
} from '../../store/actions'; } from '../../store/actions';
import SocketClient from '../../socket/SocketClient'; import SocketClient from '../../socket/SocketClient';
@ -35,15 +35,27 @@ const Chat = ({
const dispatch = useDispatch(); const dispatch = useDispatch();
const setChannel = useCallback((cid) => { 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]); }, [dispatch]);
const ownName = useSelector((state) => state.user.name); const ownName = useSelector((state) => state.user.name);
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
const fetching = useSelector((state) => state.fetching.fetchingChat); const fetching = useSelector((state) => state.fetching.fetchingChat);
const { channels, messages, blocked } = useSelector((state) => state.chat); 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, { const { stayScrolled } = useStayScrolled(listRef, {
initialScroll: Infinity, initialScroll: Infinity,
@ -89,7 +101,7 @@ const Chat = ({
if (!inptMsg) return; if (!inptMsg) return;
// send message via websocket // send message via websocket
SocketClient.sendChatMessage(inptMsg, chatChannel); SocketClient.sendChatMessage(inptMsg, chatChannel);
dispatch(setChatInputMessage(windowId, '')); dispatch(setChatInputMessage(''));
} }
/* /*
@ -185,7 +197,7 @@ const Chat = ({
id={`chtipt-${windowId}`} id={`chtipt-${windowId}`}
value={inputMessage} value={inputMessage}
onChange={(e) => dispatch( onChange={(e) => dispatch(
setChatInputMessage(windowId, e.target.value), setChatInputMessage(e.target.value),
)} )}
autoComplete="off" autoComplete="off"
maxLength="200" maxLength="200"

View File

@ -71,9 +71,7 @@ export type Action =
| { type: 'REMOVE_CHAT_CHANNEL', cid: number } | { type: 'REMOVE_CHAT_CHANNEL', cid: number }
| { type: 'MUTE_CHAT_CHANNEL', cid: number } | { type: 'MUTE_CHAT_CHANNEL', cid: number }
| { type: 'UNMUTE_CHAT_CHANNEL', cid: number } | { type: 'UNMUTE_CHAT_CHANNEL', cid: number }
| { type: 'SET_CHAT_CHANNEL', windowId: number, cid: number } | { type: 'MARK_CHANNEL_AS_READ', cid: number }
| { type: 'SET_CHAT_INPUT_MSG', windowId: number, msg: string }
| { type: 'ADD_CHAT_INPUT_MSG', windowId: number, msg: string }
| { type: 'SET_CHAT_FETCHING', fetching: boolean } | { type: 'SET_CHAT_FETCHING', fetching: boolean }
| { type: 'OPEN_WINDOW', | { type: 'OPEN_WINDOW',
windowType: string, windowType: string,

View File

@ -473,6 +473,15 @@ function receiveChatHistory(
}; };
} }
export function markChannelAsRead(
cid,
) {
return {
type: 'MARK_CHANNEL_AS_READ',
cid,
};
}
function setChatFetching(fetching) { function setChatFetching(fetching) {
return { return {
type: 'SET_CHAT_FETCHING', type: 'SET_CHAT_FETCHING',
@ -553,25 +562,37 @@ export function initTimer() {
/* /*
* fullscreen means to open as modal * fullscreen means to open as modal
* Look into store/reducers/windows.js to know what it means
*/ */
export function openWindow( export function openWindow(
windowType, windowType,
title, title = '',
fullscreen, args = null,
cloneable, fullscreen = false,
args, cloneable = true,
xPos = null, xPos = null,
yPos = null, yPos = null,
width = null, width = null,
height = 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 { return {
type: 'OPEN_WINDOW', type: 'OPEN_WINDOW',
windowType, windowType,
title, title,
args,
fullscreen, fullscreen,
cloneable, cloneable,
args,
xPos, xPos,
yPos, yPos,
width, width,
@ -579,13 +600,22 @@ export function openWindow(
}; };
} }
export function setWindowArgs(
windowId,
args,
) {
return {
type: 'SET_WINDOW_ARGS',
args,
};
}
export function showModal(modalType, title) { export function showModal(modalType, title) {
return openWindow( return openWindow(
modalType, modalType,
title, title,
null,
true, 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 { return {
type: 'CHANGE_WINDOW_TYPE', type: 'CHANGE_WINDOW_TYPE',
windowId, windowId,
windowType, windowType,
title,
args, args,
}; };
} }
@ -734,36 +770,26 @@ export function unmuteChatChannel(cid) {
}; };
} }
export function setChatChannel(windowId, cid) { export function addToChatInputMessage(windowId, msg, focus = true) {
return { return (dispatch, getState) => {
type: 'SET_CHAT_CHANNEL', const args = getState().windows.args[windowId];
windowId, let inputMessage = args && args.inputMessage;
cid: Number(cid), if (!inputMessage) {
}; inputMessage = '';
} } else if (inputMessage.slice(-1) !== ' ') {
inputMessage += ' ';
}
inputMessage += msg;
export function setChatInputMessage(windowId, msg) { dispatch(setWindowArgs(windowId, {
return { inputMessage: msg,
type: 'SET_CHAT_INPUT_MSG', }));
windowId,
msg,
};
}
export function addToChatInputMessage(windowId, msg) { if (focus) {
return { const inputElem = document.getElementById(`chtipt-${windowId}`);
type: 'ADD_CHAT_INPUT_MSG', if (inputElem) {
windowId, inputElem.focus();
msg, }
};
}
export function addToChatInputMessageAndFocus(windowId, msg) {
return (dispatch) => {
dispatch(addToChatInputMessage(windowId, msg));
const inputElem = document.getElementById(`chtipt-${windowId}`);
if (inputElem) {
inputElem.focus();
} }
}; };
} }
@ -846,18 +872,9 @@ export function hideAllWindowTypes(
} }
export function openChatWindow() { export function openChatWindow() {
const width = 350;
const height = 350;
return openWindow( return openWindow(
'CHAT', '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', 'OK',
)); ));
} else { } else {
const cid = Object.keys(res)[0]; const cid = Number(Object.keys(res)[0]);
dispatch(addChatChannel(res)); dispatch(addChatChannel(res));
dispatch(setChatChannel(windowId, cid)); dispatch(setWindowArgs(windowId, {
chatChannel: cid,
}));
} }
dispatch(setApiFetching(false)); dispatch(setApiFetching(false));
}; };

View File

@ -98,10 +98,11 @@ export default function chatRead(
} }
case 'OPEN_WINDOW': { case 'OPEN_WINDOW': {
const cid = action.args.chatChannel; const { windowType } = action;
if (!cid) { if (windowType !== 'CHAT') {
return state; return state;
} }
const cid = (action.args && action.args.chatChannel) || 1;
return { return {
...state, ...state,
readTs: { readTs: {
@ -115,7 +116,7 @@ export default function chatRead(
}; };
} }
case 'SET_CHAT_CHANNEL': { case 'MARK_CHANNEL_AS_READ': {
const { cid } = action; const { cid } = action;
return { return {
...state, ...state,

View File

@ -113,6 +113,7 @@ const initialState = {
// z: number, // z: number,
// windowType: string, // windowType: string,
// title: string, // title: string,
// title that is additionally shown to the window-type-title
// width: number, // width: number,
// height: number, // height: number,
// xPos: percentage, // 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: {}, args: {},
}; };
@ -153,6 +158,7 @@ export default function windows(
const [width, height] = clampSize(prefWidth, prefHeight, true); const [width, height] = clampSize(prefWidth, prefHeight, true);
const [xPos, yPos] = clampPos(prefXPos, prefYPos, width, height); const [xPos, yPos] = clampPos(prefXPos, prefYPos, width, height);
// fullscreen means to open as Modal
const fullscreen = !state.showWindows || action.fullscreen; const fullscreen = !state.showWindows || action.fullscreen;
if (fullscreen) { if (fullscreen) {
return { return {
@ -350,6 +356,7 @@ export default function windows(
const { const {
windowId, windowId,
windowType, windowType,
title,
} = action; } = action;
const args = { const args = {
...state.args, ...state.args,
@ -364,7 +371,7 @@ export default function windows(
modal: { modal: {
...state.modal, ...state.modal,
windowType, windowType,
title: '', title,
}, },
}; };
} }
@ -373,7 +380,7 @@ export default function windows(
return { return {
...win, ...win,
windowType, windowType,
title: '', title,
}; };
}); });
return { return {
@ -637,34 +644,10 @@ export default function windows(
}; };
} }
/* case 'SET_WINDOW_ARGS': {
* args specific actions
*/
case 'ADD_CHAT_INPUT_MSG': {
const { const {
windowId, windowId,
msg, args,
} = 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,
} = action; } = action;
return { return {
...state, ...state,
@ -672,24 +655,7 @@ export default function windows(
...state.args, ...state.args,
[windowId]: { [windowId]: {
...state.args[windowId], ...state.args[windowId],
chatChannel: cid, ...args,
},
},
};
}
case 'SET_CHAT_INPUT_MSG': {
const {
windowId,
msg,
} = action;
return {
...state,
args: {
...state.args,
[windowId]: {
...state.args[windowId],
inputMessage: msg,
}, },
}, },
}; };