diff --git a/src/actions/index.js b/src/actions/index.js index c5b8d75..7772874 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -224,6 +224,7 @@ export function receiveChatMessage( channel: number, user: number, isPing: boolean, + isRead: boolean, ): Action { return { type: 'RECEIVE_CHAT_MESSAGE', @@ -233,6 +234,7 @@ export function receiveChatMessage( channel, user, isPing, + isRead, }; } diff --git a/src/actions/types.js b/src/actions/types.js index c9340ed..efb9b93 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -64,6 +64,7 @@ export type Action = channel: number, user: number, isPing: boolean, + isRead: boolean, } | { type: 'RECEIVE_CHAT_HISTORY', cid: number, history: Array } | { type: 'OPEN_CHAT_CHANNEL', cid: number } diff --git a/src/client.js b/src/client.js index d68e0f1..a380699 100644 --- a/src/client.js +++ b/src/client.js @@ -63,14 +63,16 @@ function init() { ) => { const state = store.getState(); const { nameRegExp } = state.user; + const isRead = Object.values(state.windows.args).find(((args) => args.chatChannel === channelId)); const isPing = (nameRegExp && text.match(nameRegExp)); store.dispatch(receiveChatMessage( name, text, country, - Number(channelId), + channelId, userId, isPing, + !!isRead, )); }); ProtocolClient.on('changedMe', () => { diff --git a/src/components/Window.jsx b/src/components/Window.jsx index a9ff9f1..a3268c3 100644 --- a/src/components/Window.jsx +++ b/src/components/Window.jsx @@ -25,6 +25,8 @@ const Window = ({ id }) => { const startMove = useCallback((event) => { event.preventDefault(); + dispatch(focusWindow()); + let { clientX: startX, clientY: startY, @@ -50,6 +52,8 @@ const Window = ({ id }) => { const startResize = useCallback((event) => { event.preventDefault(); + dispatch(focusWindow()); + let { clientX: startX, clientY: startY, @@ -111,7 +115,7 @@ const Window = ({ id }) => { return (
dispatch(focusWindow(id))} + onClick={() => dispatch(focusWindow(id))} style={{ left: xPos, top: yPos, diff --git a/src/reducers/chatRead.js b/src/reducers/chatRead.js index 4ef3970..96fc3d4 100644 --- a/src/reducers/chatRead.js +++ b/src/reducers/chatRead.js @@ -18,17 +18,12 @@ export type ChatReadState = { // booleans if channel is unread // {cid: unread, ...} unread: Object, - // currently open chat channels can contain duplications - // just used to keep track of what channels we are seeing in - // windows to decide if readTS gets changed, - chatChannels: Array, }; const initialState: ChatReadState = { mute: [], readTs: {}, unread: {}, - chatChannels: [], }; @@ -59,38 +54,6 @@ export default function chatRead( }; } - case 'OPEN_CHAT_CHANNEL': { - const { cid } = action; - return { - ...state, - chatChannels: [ - ...state.chatChannels, - cid, - ], - readTs: { - ...state.readTs, - [cid]: Date.now() + TIME_DIFF_THREASHOLD, - }, - unread: { - ...state.unread, - [cid]: false, - }, - }; - } - - case 'CLOSE_CHAT_CHANNEL': { - const { cid } = action; - const chatChannels = [...state.chatChannels]; - const pos = chatChannels.indexOf(cid); - if (pos !== -1) { - chatChannels.splice(pos, 1); - } - return { - ...state, - chatChannels, - }; - } - case 'ADD_CHAT_CHANNEL': { const [cid] = Object.keys(action.channel); return { @@ -123,19 +86,19 @@ export default function chatRead( } case 'RECEIVE_CHAT_MESSAGE': { - const { channel: cid } = action; - const { chatChannels } = state; - const readTs = chatChannels.includes(cid) + const { channel: cid, isRead } = action; + const readTs = isRead ? { ...state.readTs, // 15s treshold for desync [cid]: Date.now() + TIME_DIFF_THREASHOLD, } : state.readTs; - const unread = chatChannels.includes(cid) - ? { + const unread = isRead + ? state.unread + : { ...state.unread, [cid]: true, - } : state.unread; + }; return { ...state, readTs, @@ -143,6 +106,39 @@ export default function chatRead( }; } + case 'OPEN_WINDOW': { + const cid = action.args.chatChannel; + if (!cid) { + return state; + } + return { + ...state, + readTs: { + ...state.readTs, + [cid]: Date.now() + TIME_DIFF_THREASHOLD, + }, + unread: { + ...state.unread, + [cid]: false, + }, + }; + } + + case 'SET_CHAT_CHANNEL': { + const { cid } = action; + return { + ...state, + readTs: { + ...state.readTs, + [cid]: Date.now() + TIME_DIFF_THREASHOLD, + }, + unread: { + ...state.unread, + [cid]: false, + }, + }; + } + case 'MUTE_CHAT_CHANNEL': { const { cid } = action; return { diff --git a/src/socket/ProtocolClient.js b/src/socket/ProtocolClient.js index 1fc7000..e29918e 100644 --- a/src/socket/ProtocolClient.js +++ b/src/socket/ProtocolClient.js @@ -166,7 +166,8 @@ class ProtocolClient extends EventEmitter { case 5: { // chat message const [name, text, country, channelId, userId] = data; - this.emit('chatMessage', name, text, country, channelId, userId); + this.emit('chatMessage', + name, text, country, Number(channelId), userId); return; }