🆙 Added emoji to the chat

This commit is contained in:
duckietm
2026-02-25 11:03:29 +01:00
parent 3aaa3c4d2d
commit 32cf466fb4
4 changed files with 80 additions and 2 deletions
@@ -0,0 +1,37 @@
import data from '@emoji-mart/data';
import Picker from '@emoji-mart/react';
import { FC, useState } from 'react';
import { Popover } from 'react-tiny-popover';
interface ChatInputEmojiSelectorViewProps
{
addChatEmoji: (emoji: string) => void;
}
export const ChatInputEmojiSelectorView: FC<ChatInputEmojiSelectorViewProps> = props =>
{
const { addChatEmoji = null } = props;
const [ selectorVisible, setSelectorVisible ] = useState(false);
const handleEmojiSelect = (emoji: any) =>
{
addChatEmoji(emoji.native);
setSelectorVisible(false);
};
const toggleSelector = () => setSelectorVisible(prev => !prev);
return (
<div>
<Popover
containerClassName="z-[1070]"
content={ <Picker data={ data } onEmojiSelect={ handleEmojiSelect } /> }
isOpen={ selectorVisible }
positions={ [ 'top' ] }
onClickOutside={ () => setSelectorVisible(false) }
>
<div className="cursor-pointer text-lg select-none px-1" onClick={ toggleSelector }>🙂</div>
</Popover>
</div>
);
};
@@ -4,6 +4,7 @@ import { createPortal } from 'react-dom';
import { ChatMessageTypeEnum, GetClubMemberLevel, GetConfigurationValue, LocalizeText, RoomWidgetUpdateChatInputContentEvent } from '../../../../api';
import { Text } from '../../../../common';
import { useChatInputWidget, useRoom, useSessionInfo, useUiEvent } from '../../../../hooks';
import { ChatInputEmojiSelectorView } from './ChatInputEmojiSelectorView';
import { ChatInputStyleSelectorView } from './ChatInputStyleSelectorView';
export const ChatInputView: FC<{}> = props =>
@@ -119,6 +120,13 @@ export const ChatInputView: FC<{}> = props =>
setChatValue(value);
}, [ setIsTyping, setIsIdle ]);
const addChatEmoji = useCallback((emoji: string) =>
{
setChatValue(prev => prev + emoji);
setIsTyping(true);
inputRef.current?.focus();
}, [ setIsTyping, inputRef ]);
const onKeyDownEvent = useCallback((event: KeyboardEvent) =>
{
if(floodBlocked || !inputRef.current || anotherInputHasFocus()) return;
@@ -235,13 +243,14 @@ export const ChatInputView: FC<{}> = props =>
return (
createPortal(
<div className="nitro-chat-input-container flex justify-center items-center relative h-10 border-2 border-black bg-gray-200 pr-2.5 w-full overflow-hidden rounded-lg">
<div className="items-center input-sizer">
<div className="nitro-chat-input-container flex justify-between items-center relative h-10 border-2 border-black bg-gray-200 pr-2.5 w-full overflow-hidden rounded-lg">
<div className="flex-1 items-center input-sizer">
{ !floodBlocked &&
<input ref={ inputRef } className="[font-size:inherit] placeholder-[#6c757d] bg-transparent border-none focus:border-current focus:shadow-none focus:ring-0 " maxLength={ maxChatLength } placeholder={ LocalizeText('widgets.chatinput.default') } type="text" value={ chatValue } onChange={ event => updateChatInput(event.target.value) } onMouseDown={ event => setInputFocus() } /> }
{ floodBlocked &&
<Text variant="danger">{ LocalizeText('chat.input.alert.flood', [ 'time' ], [ floodBlockedSeconds.toString() ]) } </Text> }
</div>
<ChatInputEmojiSelectorView addChatEmoji={ addChatEmoji } />
<ChatInputStyleSelectorView chatStyleId={ chatStyleId } chatStyleIds={ chatStyleIds } selectChatStyleId={ updateChatStyleId } />
</div>, document.getElementById('toolbar-chat-input-container'))
);
+28
View File
@@ -159,4 +159,32 @@
&:hover {
color: #419AD2;
}
}
.nitro-chat-input-container {
.input-sizer {
display: inline-grid;
vertical-align: top;
height: 100%;
padding: 0 10px;
&::after,
input {
width: auto;
min-width: 1em;
grid-area: 1 / 2;
margin: 0;
resize: none;
background: none;
appearance: none;
border: none;
outline: none;
}
&::after {
content: attr(data-value) ' ';
visibility: hidden;
white-space: pre-wrap;
}
}
}