feat: add member to chat input reply

This commit is contained in:
Pavel Prichodko 2022-06-15 16:04:07 +02:00
parent aebf9da6c1
commit d54a9ab1b3
No known key found for this signature in database
GPG Key ID: 8E4C82D464215E83
4 changed files with 23 additions and 21 deletions

View File

@ -1,6 +1,6 @@
import React, { createContext, useContext, useMemo, useReducer } from 'react' import React, { createContext, useContext, useMemo, useReducer } from 'react'
import type { Message } from '../protocol/use-messages' import type { Member, Message } from '../protocol'
import type { Dispatch, Reducer } from 'react' import type { Dispatch, Reducer } from 'react'
type Context = { type Context = {
@ -12,25 +12,27 @@ const ChatContext = createContext<Context | undefined>(undefined)
interface State { interface State {
message?: Message message?: Message
member?: Member
} }
type Action = type Action =
| { type: 'SET_REPLY'; message?: Message } | { type: 'SET_REPLY'; message?: Message; member?: Member }
| { type: 'CANCEL_REPLY' } | { type: 'DELETE_REPLY' }
const reducer: Reducer<State, Action> = (state, action) => { const reducer: Reducer<State, Action> = (state, action) => {
switch (action.type) { switch (action.type) {
case 'SET_REPLY': { case 'SET_REPLY': {
return { ...state, message: action.message } return { ...state, message: action.message, member: action.member }
} }
case 'CANCEL_REPLY': { case 'DELETE_REPLY': {
return { ...state, message: undefined } return { ...initialState }
} }
} }
} }
const initialState: State = { const initialState: State = {
message: undefined, message: undefined,
member: undefined,
} }
interface Props { interface Props {
@ -41,6 +43,7 @@ export const ChatProvider = (props: Props) => {
const { children } = props const { children } = props
const [state, dispatch] = useReducer(reducer, initialState) const [state, dispatch] = useReducer(reducer, initialState)
const value = useMemo(() => ({ state, dispatch }), [state]) const value = useMemo(() => ({ state, dispatch }), [state])
return <ChatContext.Provider value={value}>{children}</ChatContext.Provider> return <ChatContext.Provider value={value}>{children}</ChatContext.Provider>

View File

@ -21,7 +21,7 @@ export const ChatInput = (props: Props) => {
const { value, editing, onSubmit } = props const { value, editing, onSubmit } = props
const [inputValue, setInputValue] = useState(value ?? '') const [inputValue, setInputValue] = useState(value ?? '')
const { state } = useChatContext() const { state, dispatch } = useChatContext()
const inputRef = useRef<HTMLInputElement>(null) const inputRef = useRef<HTMLInputElement>(null)
@ -37,6 +37,7 @@ export const ChatInput = (props: Props) => {
if (event.key === 'Enter' && event.shiftKey === false) { if (event.key === 'Enter' && event.shiftKey === false) {
onSubmit(inputValue) onSubmit(inputValue)
setInputValue('') setInputValue('')
dispatch({ type: 'DELETE_REPLY' })
} }
} }
@ -48,7 +49,9 @@ export const ChatInput = (props: Props) => {
</IconButton> </IconButton>
</Box> </Box>
<Bubble> <Bubble>
{state.message && <InputReply message={state.message} />} {state.message && (
<InputReply message={state.message} member={state.member} />
)}
<InputWrapper> <InputWrapper>
<Input <Input
ref={inputRef} ref={inputRef}

View File

@ -4,34 +4,30 @@ import { useChatContext } from '~/src/contexts/chat-context'
import { CrossIcon } from '~/src/icons/cross-icon' import { CrossIcon } from '~/src/icons/cross-icon'
import { ReplyIcon } from '~/src/icons/reply-icon' import { ReplyIcon } from '~/src/icons/reply-icon'
import { styled } from '~/src/styles/config' import { styled } from '~/src/styles/config'
import { Box, Flex, Icon, IconButton, Image, Text } from '~/src/system' import { Flex, Icon, IconButton, Image, Text } from '~/src/system'
import type { Message } from '~/src/protocol/use-messages' import type { Member, Message } from '~/src/protocol'
interface Props { interface Props {
message: Message message: Message
member: Member
} }
export const InputReply = (props: Props) => { export const InputReply = (props: Props) => {
const { dispatch } = useChatContext() const { dispatch } = useChatContext()
const { message } = props const { message, member } = props
return ( return (
<Wrapper> <Wrapper>
<Flex align="center" justify="between"> <Flex align="center" justify="between">
<Flex gap={1}> <Text size="13" weight="500" truncate={false}>
<Icon hidden> {member.username}
<ReplyIcon /> </Text>
</Icon>
<Text size="13" weight="500" truncate={false}>
TODO: Add name
</Text>
</Flex>
<IconButton <IconButton
label="Cancel reply" label="Cancel reply"
onClick={() => dispatch({ type: 'CANCEL_REPLY' })} onClick={() => dispatch({ type: 'DELETE_REPLY' })}
> >
<CrossIcon /> <CrossIcon />
</IconButton> </IconButton>

View File

@ -85,7 +85,7 @@ export const ChatMessage = (props: Props) => {
} }
const handleReplyClick = () => { const handleReplyClick = () => {
dispatch({ type: 'SET_REPLY', message }) dispatch({ type: 'SET_REPLY', message, member })
} }
const handlePinClick = () => { const handlePinClick = () => {