Room chat input updates

This commit is contained in:
Bill 2021-05-04 18:41:47 -04:00
parent 6ed7cb6b6f
commit 8f2446186f
2 changed files with 221 additions and 4 deletions

View File

@ -1,3 +1,87 @@
.nitro-chat-input { .nitro-chat-input {
position: fixed;
display: flex;
bottom: 57px;
left: 55px;
pointer-events: none;
z-index: $chatinput-zindex;
.chatinput-container {
position: relative;
height: 30px;
border-radius: 8px;
border: 1.5px solid rgb(0, 0, 0);
background: #EDEDED;
pointer-events: all;
padding-right:30px;
width:100%;
.input-sizer {
display: inline-grid;
vertical-align: top;
align-items: center;
position: relative;
height: 100%;
padding:0 10px;
&::after,
input,
textarea {
width: auto;
min-width: 1em;
grid-area: 1 / 2;
font: inherit;
margin: 0;
resize: none;
background: none;
appearance: none;
border: none;
}
&::after {
content: attr(data-value) ' ';
visibility: hidden;
white-space: pre-wrap;
}
}
.chat-input {
height: 100%;
font-size: 16px;
outline: 0;
border: 0;
position: relative;
background: transparent;
}
&:after {
content: "";
position: absolute;
top:0;
bottom:0;
margin: auto;
left: -5.5px;
height: 9px;
width: 9px;
background: #EDEDED;
transform: rotate(45deg);
border-left: 1.5px solid $black;
border-bottom: 1.5px solid $black;
}
&:before {
content: "";
position: absolute;
width: 98%;
height: 5px;
border-radius: 8px;
top: 1px;
left: 0;
right: 0;
margin: auto;
background: rgb(255, 255, 255);
z-index: 1;
}
}
} }

View File

@ -1,13 +1,146 @@
import { FC } from 'react'; import { createRef, FC, MouseEvent, useCallback, useEffect, useState } from 'react';
import { SendChatTypingMessage } from '../../../../api/nitro/session/SendChatTypingMessage';
import { LocalizeText } from '../../../../utils/LocalizeText'; import { LocalizeText } from '../../../../utils/LocalizeText';
import { ChatInputViewProps } from './ChatInputView.types'; import { ChatInputViewProps } from './ChatInputView.types';
// const chatModeIdShout = LocalizeText('widgets.chatinput.mode.shout');
// const chatModeIdSpeak = LocalizeText('widgets.chatinput.mode.speak');
// const maxChatLength = GetConfiguration<number>('chat.input.maxlength', 100);
let lastContent = '';
export const ChatInputView: FC<ChatInputViewProps> = props => export const ChatInputView: FC<ChatInputViewProps> = props =>
{ {
const [ chatValue, setChatValue ] = useState<string>('');
const [ selectedUsername, setSelectedUsername ] = useState('');
const [ isTyping, setIsTyping ] = useState(false);
const inputRef = createRef<HTMLInputElement>();
const anotherInputHasFocus = useCallback(() =>
{
const activeElement = document.activeElement;
if(!activeElement) return false;
if(inputRef && (inputRef.current === activeElement)) return false;
if(!(activeElement instanceof HTMLInputElement) && !(activeElement instanceof HTMLTextAreaElement)) return false;
return true;
}, [ inputRef ]);
const setInputFocus = useCallback(() =>
{
inputRef.current.focus();
inputRef.current.setSelectionRange((inputRef.current.value.length * 2), (inputRef.current.value.length * 2));
}, [ inputRef ]);
const checkSpecialKeywordForInput = useCallback(() =>
{
setChatValue(prevValue =>
{
if((prevValue !== LocalizeText('widgets.chatinput.mode.whisper')) || !selectedUsername.length) return prevValue;
return (`${ prevValue } ${ selectedUsername }`);
});
}, [ selectedUsername ]);
const sendChatValue = useCallback((shiftKey: boolean = false) =>
{
if(!chatValue || (chatValue === '')) return;
}, [ chatValue ]);
const onKeyDownEvent = useCallback((event: KeyboardEvent) =>
{
if(!inputRef.current) return;
if(anotherInputHasFocus()) return;
if(document.activeElement !== inputRef.current) setInputFocus();
switch(event.key)
{
case 'Space':
checkSpecialKeywordForInput();
return;
case 'Enter':
sendChatValue(event.shiftKey);
return;
case 'Backspace':
return;
}
}, [ inputRef, anotherInputHasFocus, setInputFocus, checkSpecialKeywordForInput, sendChatValue ]);
const onInputMouseDownEvent = useCallback((event: MouseEvent<HTMLInputElement>) =>
{
setInputFocus();
}, [ setInputFocus ]);
useEffect(() =>
{
document.body.addEventListener('keydown', onKeyDownEvent);
return () =>
{
document.body.removeEventListener('keydown', onKeyDownEvent);
}
}, [ onKeyDownEvent ]);
useEffect(() =>
{
let idleTimer: ReturnType<typeof setTimeout> = null;
if(!chatValue || !chatValue.length)
{
setIsTyping(prevValue =>
{
if(!prevValue) return prevValue;
if(prevValue) SendChatTypingMessage(false);
return false;
});
}
else
{
setIsTyping(prevValue =>
{
if(prevValue) return prevValue;
if(!prevValue) SendChatTypingMessage(true);
return true;
});
lastContent = chatValue;
idleTimer = setTimeout(() =>
{
setIsTyping(prevValue =>
{
if(prevValue) SendChatTypingMessage(false);
return false;
});
}, 3000);
}
return () =>
{
if(idleTimer) clearTimeout(idleTimer);
}
}, [ chatValue ]);
return ( return (
<div className="nitro-chat-input fixed-bottom mb-4 d-flex justify-content-center"> <div className="nitro-chat-input">
<div className="nitro-chat-form-input"> <div className="chatinput-container">
<input type="text" className="form-control" placeholder={ LocalizeText('widgets.chatinput.default') } /> <div className="input-sizer">
<input ref={ inputRef } type="text" className="chat-input" placeholder={ LocalizeText('widgets.chatinput.default') } value={ chatValue } onChange={ event => { event.target.parentElement.dataset.value = event.target.value; setChatValue(event.target.value) } } onMouseDown={ onInputMouseDownEvent } />
{/* <input #chatInputView type="text" class="chat-input" placeholder="{{ 'widgets.chatinput.default' | translate }}" (input)="chatInputView.parentElement.dataset.value = chatInputView.value" [disabled]="floodBlocked" [maxLength]="inputMaxLength" /> */}
</div>
</div> </div>
</div> </div>
); );