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

View File

@ -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"

View File

@ -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,

View File

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

View File

@ -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,

View File

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