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:
@@ -31,6 +31,15 @@
|
|||||||
font-size: var(--chat-message-text-size);
|
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 {
|
.virtuoso {
|
||||||
width: auto;
|
width: auto;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export type ChatContainerProps = {
|
|||||||
height?: string;
|
height?: string;
|
||||||
chatAvailable: boolean;
|
chatAvailable: boolean;
|
||||||
focusInput?: boolean;
|
focusInput?: boolean;
|
||||||
|
desktop?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
function shouldCollapseMessages(message: ChatMessage, previous: ChatMessage): boolean {
|
function shouldCollapseMessages(message: ChatMessage, previous: ChatMessage): boolean {
|
||||||
@@ -77,6 +78,7 @@ export const ChatContainer: FC<ChatContainerProps> = ({
|
|||||||
showInput,
|
showInput,
|
||||||
height,
|
height,
|
||||||
chatAvailable: chatEnabled,
|
chatAvailable: chatEnabled,
|
||||||
|
desktop,
|
||||||
focusInput = true,
|
focusInput = true,
|
||||||
}) => {
|
}) => {
|
||||||
const [showScrollToBottomButton, setShowScrollToBottomButton] = useState(false);
|
const [showScrollToBottomButton, setShowScrollToBottomButton] = useState(false);
|
||||||
@@ -266,6 +268,36 @@ export const ChatContainer: FC<ChatContainerProps> = ({
|
|||||||
[messages, usernameToHighlight, chatUserId, isModerator, showScrollToBottomButton, isAtBottom],
|
[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 (
|
return (
|
||||||
<ErrorBoundary
|
<ErrorBoundary
|
||||||
// eslint-disable-next-line react/no-unstable-nested-components
|
// 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}
|
{MessagesTable}
|
||||||
{showInput && (
|
{showInput && (
|
||||||
<div className={styles.chatTextField}>
|
<div className={styles.chatTextField}>
|
||||||
<ChatTextField enabled={chatEnabled} focusInput={focusInput} />
|
<ChatTextField enabled={chatEnabled} focusInput={focusInput} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{desktop && (
|
||||||
|
<div className={styles.resizeHandle} onMouseDown={startDrag} role="presentation" />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,11 +5,6 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
// I'm not quite sure why, but sass ignores `#chat-container` here
|
|
||||||
[id="chat-container"] {
|
|
||||||
width: var(--chat-col-width);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainColumn {
|
.mainColumn {
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ export const Content: FC = () => {
|
|||||||
isModerator={currentUser.isModerator}
|
isModerator={currentUser.isModerator}
|
||||||
chatAvailable={isChatAvailable}
|
chatAvailable={isChatAvailable}
|
||||||
showInput={!!currentUser}
|
showInput={!!currentUser}
|
||||||
|
desktop
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{externalActionToDisplay && (
|
{externalActionToDisplay && (
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
--chat-notification-icon-padding: 6px;
|
--chat-notification-icon-padding: 6px;
|
||||||
--chat-message-padding: 10px;
|
--chat-message-padding: 10px;
|
||||||
--chat-text-highlight-border-radius: 3px;
|
--chat-text-highlight-border-radius: 3px;
|
||||||
--chat-col-width: 320px;
|
|
||||||
--player-container-height: 75vh;
|
--player-container-height: 75vh;
|
||||||
--status-bar-height: 2rem;
|
--status-bar-height: 2rem;
|
||||||
--footer-padding-x: 1rem;
|
--footer-padding-x: 1rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user