mirror of
https://github.com/duckietm/Nitro-Cool-UI.git
synced 2025-06-21 22:36:58 +00:00
Feat: emoji-mart in the Chatbar instead of a list
This commit is contained in:
parent
659a715374
commit
ae267e9430
@ -11,10 +11,13 @@
|
||||
"eslint": "eslint src --ext .ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emoji-mart/data": "^1.1.2",
|
||||
"@emoji-mart/react": "^1.1.1",
|
||||
"@nitrots/nitro-renderer": "file:submodules/renderer",
|
||||
"@tanstack/react-virtual": "^3.0.0-beta.60",
|
||||
"dompurify": "^3.0.9",
|
||||
"emoji-toolkit": "^7.0.1",
|
||||
"emoji-mart": "^5.5.2",
|
||||
"emoji-toolkit": "8.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.7.2",
|
||||
"react-dom": "^18.2.0",
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { FC, MouseEvent, useEffect, useRef, useState } from 'react';
|
||||
import { Overlay, Popover } from 'react-bootstrap';
|
||||
import { Base, Flex, Grid, NitroCardContentView } from '../../../../common';
|
||||
import { emojiList } from './EmojiList';
|
||||
import data from '@emoji-mart/data'
|
||||
import Picker from '@emoji-mart/react'
|
||||
|
||||
interface ChatInputEmojiSelectorViewProps
|
||||
{
|
||||
@ -15,7 +16,17 @@ export const ChatInputEmojiSelectorView: FC<ChatInputEmojiSelectorViewProps> = p
|
||||
const [ target, setTarget ] = useState<(EventTarget & HTMLElement)>(null);
|
||||
const iconRef = useRef<HTMLDivElement>(null);
|
||||
const componentRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleEmojiSelect = (emoji: any) => {
|
||||
addChatEmoji(emoji.native);
|
||||
setSelectorVisible(false);
|
||||
}
|
||||
|
||||
const addEmojiToChat = (emoji: string) => {
|
||||
setChatValue(chatValue + emoji);
|
||||
setIsTyping(true);
|
||||
};
|
||||
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
const className = 'emoji-icon';
|
||||
if (componentRef.current && !componentRef.current.contains(event.target as Node) && !(event.target as Element).classList.contains(className)) {
|
||||
@ -48,19 +59,9 @@ export const ChatInputEmojiSelectorView: FC<ChatInputEmojiSelectorViewProps> = p
|
||||
return (
|
||||
<>
|
||||
<Base pointer onClick={toggleSelector} innerRef={iconRef}>🙂</Base>
|
||||
<Overlay show={selectorVisible} target={iconRef} placement="top">
|
||||
<Popover className="nitro-chat-style-selector-container">
|
||||
<NitroCardContentView overflow="hidden" className="bg-transparent">
|
||||
<Grid columnCount={3} overflow="auto">
|
||||
{emojiList && emojiList.length > 0 && emojiList.map((emojiId) => {
|
||||
return (
|
||||
<Flex center pointer key={emojiId} onClick={(event) => selectEmoji(emojiId)}>
|
||||
<Base className="emoji" textColor="black" style={{ fontSize: '20px' }}>{emojiId}</Base>
|
||||
</Flex>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
</NitroCardContentView>
|
||||
<Overlay show={selectorVisible} target={iconRef} placement="top-end">
|
||||
<Popover>
|
||||
<Picker data={data} onEmojiSelect={handleEmojiSelect} />
|
||||
</Popover>
|
||||
</Overlay>
|
||||
</>
|
||||
|
@ -78,7 +78,15 @@
|
||||
}
|
||||
|
||||
.nitro-chat-input-container .input-sizer input{
|
||||
width: calc(100% - 80px)!important;
|
||||
width: auto;
|
||||
min-width: 1em;
|
||||
grid-area: 1 / 2;
|
||||
margin: 0;
|
||||
resize: none;
|
||||
background: none;
|
||||
appearance: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.nitro-chat-style-selector-container {
|
||||
|
@ -218,11 +218,11 @@ export const ChatInputView: FC<{}> = props =>
|
||||
return styleIds;
|
||||
}, []);
|
||||
|
||||
const addEmojiToChat = (emoji: string) =>
|
||||
{
|
||||
setChatValue(chatValue + emoji);
|
||||
setIsTyping(true);
|
||||
}
|
||||
const addEmojiToChat = (emoji: string) => {
|
||||
setChatValue(chatValue + emoji);
|
||||
setIsTyping(true);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
document.body.addEventListener('keydown', onKeyDownEvent);
|
||||
@ -241,13 +241,22 @@ export const ChatInputView: FC<{}> = props =>
|
||||
}, [ chatValue ]);
|
||||
|
||||
if(!roomSession || roomSession.isSpectator) return null;
|
||||
|
||||
|
||||
return (
|
||||
createPortal(
|
||||
<div className="nitro-chat-input-container" onMouseEnter={ () => setShowInfohabboPages(true) } onMouseLeave={ () => setTimeout(() => setShowInfohabboPages(false), 100) }>
|
||||
<div className="input-sizer align-items-center">
|
||||
{ !floodBlocked &&
|
||||
<input ref={ inputRef } type="text" className="chat-input" placeholder={ LocalizeText('widgets.chatinput.default') } value={ chatValue } maxLength={ maxChatLength } onChange={ event => updateChatInput(event.target.value) } onMouseDown={ event => setInputFocus() } /> }
|
||||
<input
|
||||
ref={ inputRef }
|
||||
type="text"
|
||||
className="chat-input"
|
||||
placeholder={ LocalizeText('widgets.chatinput.default') }
|
||||
value={ chatValue }
|
||||
maxLength={ maxChatLength }
|
||||
onChange={ event => updateChatInput(event.target.value) }
|
||||
onMouseDown={ event => setInputFocus() } />
|
||||
}
|
||||
{ floodBlocked &&
|
||||
<Text variant="danger">{ LocalizeText('chat.input.alert.flood', [ 'time' ], [ floodBlockedSeconds.toString() ]) } </Text> }
|
||||
</div>
|
||||
|
File diff suppressed because one or more lines are too long
@ -8,15 +8,15 @@ interface ChatWidgetMessageViewProps
|
||||
chat: ChatBubbleMessage;
|
||||
makeRoom: (chat: ChatBubbleMessage) => void;
|
||||
bubbleWidth?: number;
|
||||
selectedEmoji?: string;
|
||||
}
|
||||
|
||||
export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
||||
{
|
||||
const { chat = null, makeRoom = null, bubbleWidth = RoomChatSettings.CHAT_BUBBLE_WIDTH_NORMAL } = props;
|
||||
export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props => {
|
||||
const { chat = null, makeRoom = null, bubbleWidth = RoomChatSettings.CHAT_BUBBLE_WIDTH_NORMAL, selectedEmoji } = props;
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ isReady, setIsReady ] = useState<boolean>(false);
|
||||
const { onClickChat = null } = useOnClickChat();
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
const { onClickChat = null } = useOnClickChat();
|
||||
const elementRef = useRef<HTMLDivElement>();;
|
||||
|
||||
const getBubbleWidth = useMemo(() =>
|
||||
{
|
||||
@ -78,8 +78,9 @@ export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
||||
}, [ chat, isReady, isVisible, makeRoom ]);
|
||||
|
||||
return (
|
||||
<div ref={ elementRef } className={ `bubble-container newbubblehe ${ isVisible ? 'visible' : 'invisible' }` } onClick={ event => GetRoomEngine().selectRoomObject(chat.roomId, chat.senderId, RoomObjectCategory.UNIT) }>
|
||||
{ (chat.styleId === 0) &&
|
||||
<div ref={elementRef} className={`bubble-container newbubblehe ${isVisible ? 'visible' : 'invisible'}`} onClick={event => GetRoomEngine().selectRoomObject(chat.roomId, chat.senderId, RoomObjectCategory.UNIT)}>
|
||||
{selectedEmoji && <span>{selectedEmoji}</span>}
|
||||
{ (chat.styleId === 0) &&
|
||||
<div className="user-container-bg" style={ { backgroundColor: chat.color } } /> }
|
||||
<div className={ `chat-bubble bubble-${ chat.styleId } type-${ chat.type }` } style={ { maxWidth: getBubbleWidth } }>
|
||||
<div className="user-container">
|
||||
@ -94,4 +95,4 @@ export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user