0

Add resize handle to chat (#3157)

* add resize handle to chat

* Add chat resize functionality

* window resize only causes chat resize on desktop

* fix parseFloat invocation

* desktop is optional attribute of ChatContainer

---------

Co-authored-by: janWilejan <>
This commit is contained in:
janWilejan 2023-07-11 06:00:28 +00:00 committed by GitHub
parent c92f58df2e
commit 3f4887020d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 7 deletions

View File

@ -31,6 +31,15 @@
font-size: var(--chat-message-text-size);
}
.resizeHandle {
background: linear-gradient(45deg, transparent 0px,transparent 4px, var(--color-owncast-palette-6) 4px, var(--color-owncast-palette-6) 5px, transparent 5px, transparent 9px, var(--color-owncast-palette-6) 9px, var(--color-owncast-palette-6) 10px, transparent 10px, transparent 14px, var(--color-owncast-palette-6) 14px, var(--color-owncast-palette-6) 15px, transparent 15px);
position: absolute;
bottom: 0;
width: 30px;
height: 30px;
cursor: col-resize;
}
.virtuoso {
width: auto;
flex-grow: 1;

View File

@ -30,6 +30,7 @@ export type ChatContainerProps = {
height?: string;
chatAvailable: boolean;
focusInput?: boolean;
desktop?: boolean;
};
function shouldCollapseMessages(message: ChatMessage, previous: ChatMessage): boolean {
@ -77,6 +78,7 @@ export const ChatContainer: FC<ChatContainerProps> = ({
showInput,
height,
chatAvailable: chatEnabled,
desktop,
focusInput = true,
}) => {
const [showScrollToBottomButton, setShowScrollToBottomButton] = useState(false);
@ -266,6 +268,36 @@ export const ChatContainer: FC<ChatContainerProps> = ({
[messages, usernameToHighlight, chatUserId, isModerator, showScrollToBottomButton, isAtBottom],
);
const defaultChatWidth: number = 320;
function clampChatWidth(desired) {
return Math.max(200, Math.min(window.innerWidth * 0.666, desired));
}
function startDrag(dragEvent) {
const container = document.getElementById('chat-container');
function move(event) {
container.style.width = `${clampChatWidth(window.innerWidth - event.x)}px`;
}
function endDrag() {
window.document.removeEventListener('mousemove', move);
window.document.removeEventListener('mouseup', endDrag);
window.document.removeEventListener('focusout', endDrag);
}
window.document.addEventListener('mousemove', move);
window.document.addEventListener('mouseup', endDrag);
window.document.addEventListener('focusout', endDrag);
dragEvent.preventDefault(); // Prevent selecting the page as you resize it
}
// Re-clamp the chat size whenever the window resizes
window.addEventListener('resize', () => {
const container = desktop && document.getElementById('chat-container');
if (container) {
const currentWidth = parseFloat(container.style.width) || defaultChatWidth;
container.style.width = `${clampChatWidth(currentWidth)}px`;
}
});
return (
<ErrorBoundary
// eslint-disable-next-line react/no-unstable-nested-components
@ -277,13 +309,20 @@ export const ChatContainer: FC<ChatContainerProps> = ({
/>
)}
>
<div id="chat-container" className={styles.chatContainer}>
<div
id="chat-container"
className={styles.chatContainer}
style={desktop && { width: `${defaultChatWidth}px` }}
>
{MessagesTable}
{showInput && (
<div className={styles.chatTextField}>
<ChatTextField enabled={chatEnabled} focusInput={focusInput} />
</div>
)}
{desktop && (
<div className={styles.resizeHandle} onMouseDown={startDrag} role="presentation" />
)}
</div>
</ErrorBoundary>
);

View File

@ -5,11 +5,6 @@
flex-direction: row;
overflow: hidden;
height: 100%;
// I'm not quite sure why, but sass ignores `#chat-container` here
[id="chat-container"] {
width: var(--chat-col-width);
}
}
.mainColumn {

View File

@ -321,6 +321,7 @@ export const Content: FC = () => {
isModerator={currentUser.isModerator}
chatAvailable={isChatAvailable}
showInput={!!currentUser}
desktop
/>
)}
{externalActionToDisplay && (

View File

@ -18,7 +18,6 @@
--chat-notification-icon-padding: 6px;
--chat-message-padding: 10px;
--chat-text-highlight-border-radius: 3px;
--chat-col-width: 320px;
--player-container-height: 75vh;
--status-bar-height: 2rem;
--footer-padding-x: 1rem;