feat: persistent text input

This commit is contained in:
cha0s 2020-07-26 15:50:02 -05:00
parent 5486103d78
commit 0a657c02d7
2 changed files with 42 additions and 9 deletions

View File

@ -1,10 +1,14 @@
import './chat--messages.scss';
import React, {useRef, useState} from 'react';
import React, {useRef} from 'react';
import {useDispatch, useSelector} from 'react-redux';
import {v4 as uuidv4} from 'uuid';
import {submitMessage} from '~/common/state/chat';
import {
inputChannelSelector,
inputText,
submitMessage,
} from '~/common/state/chat';
import {userSelector} from '~/common/state/user';
import useChannel from '~/client/hooks/useChannel';
@ -14,7 +18,8 @@ export default function ChatSubmitMessage() {
const dispatch = useDispatch();
const $form = useRef(null);
const user = useSelector(userSelector);
const [text, setText] = useState('');
const text = useSelector((state) => inputChannelSelector(state, channel));
const setText = (text) => dispatch(inputText({channel, text}));
return (
<div className="chat--messageSubmit">
<form
@ -42,16 +47,14 @@ export default function ChatSubmitMessage() {
className="chat--messagesTextarea"
name="message"
type="textarea"
onChange={(event) => {
setText(event.target.value);
}}
onChange={(event) => setText(event.target.value)}
onKeyDown={(event) => {
if ('Enter' === event.key && !event.shiftKey) {
$form.current?.dispatchEvent(new Event('submit', {cancelable: true}));
event.preventDefault();
}
}}
value={text}
value={text || ''}
/>
</form>
</div>

View File

@ -5,8 +5,14 @@ import {
} from '@reduxjs/toolkit';
import hydration from './hydration';
import storage from './storage';
export const channelsSelector = (state) => state.chat.channels;
export const chatSelector = (state) => state.chat;
export const channelsSelector = createSelector(
chatSelector,
(chat) => chat.channels,
);
export const channelSelector = createSelector(
[channelsSelector, (_, channel) => channel],
@ -18,7 +24,20 @@ export const channelUsersSelector = createSelector(
(channel) => (channel ? channel.users : []),
);
export const messagesSelector = (state) => state.chat.messages;
export const inputSelector = createSelector(
chatSelector,
(chat) => chat.input,
);
export const inputChannelSelector = createSelector(
[inputSelector, (_, channel) => channel],
(input, channel) => input[channel],
);
export const messagesSelector = createSelector(
chatSelector,
(chat) => chat.messages,
);
export const channelMessagesSelector = createSelector(
[channelSelector, messagesSelector],
@ -29,8 +48,10 @@ const slice = createSlice({
name: 'chat',
initialState: {
channels: {},
input: {},
messages: {},
...(hydration('chat') || {}),
...(storage(chatSelector) || {}),
},
reducers: {
addMessage: ({
@ -56,6 +77,14 @@ const slice = createSlice({
editMessage: ({messages}, {payload: {uuid, message}}) => {
messages[uuid].message = message;
},
inputText: ({input}, {payload: {channel, text}}) => {
if (!text) {
delete input[channel];
}
else {
input[channel] = text;
}
},
join: ({channels, messages}, {payload: {channel, messages: channelMessages, users}}) => {
channelMessages.forEach((message) => {
messages[message.uuid] = message;
@ -94,6 +123,7 @@ export const {
addMessage,
confirmMessage,
editMessage,
inputText,
join,
joined,
leave,