mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
🆙 Added emoji to the chat
This commit is contained in:
@@ -11,9 +11,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.26.9",
|
||||
"@emoji-mart/data": "^1.2.1",
|
||||
"@emoji-mart/react": "^1.1.1",
|
||||
"@tanstack/react-virtual": "3.2.0",
|
||||
"@types/react-transition-group": "^4.4.10",
|
||||
"dompurify": "^3.1.5",
|
||||
"emoji-mart": "^5.6.0",
|
||||
"emoji-toolkit": "10.0.0",
|
||||
"framer-motion": "^11.2.12",
|
||||
"react": "^19.2.4",
|
||||
"react-bootstrap": "^2.10.10",
|
||||
|
||||
@@ -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'))
|
||||
);
|
||||
|
||||
@@ -160,3 +160,31 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user