feat(ui) [closes #160] Move transcript scrollbar to content window edge (#212)

* feat(ui): [closes #160] move transcript scrollbar to edge of container
* feat(ui): prevent controls from obscuring transcript
* feat(ui): hide unnecessary hide controls button
This commit is contained in:
Jeremy Kahn 2023-11-23 12:26:07 -06:00 committed by GitHub
parent 1cf4b50ac2
commit 7bceba5acb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 16 deletions

View File

@ -1,9 +1,11 @@
import { HTMLAttributes, useRef, useEffect, useState } from 'react' import { HTMLAttributes, useRef, useEffect, useState, useContext } from 'react'
import cx from 'classnames' import cx from 'classnames'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import useTheme from '@mui/material/styles/useTheme'
import { Message as IMessage, InlineMedia } from 'models/chat' import { Message as IMessage, InlineMedia } from 'models/chat'
import { Message } from 'components/Message' import { Message } from 'components/Message'
import { ShellContext } from 'contexts/ShellContext'
export interface ChatTranscriptProps extends HTMLAttributes<HTMLDivElement> { export interface ChatTranscriptProps extends HTMLAttributes<HTMLDivElement> {
messageLog: Array<IMessage | InlineMedia> messageLog: Array<IMessage | InlineMedia>
@ -15,6 +17,8 @@ export const ChatTranscript = ({
messageLog, messageLog,
userId, userId,
}: ChatTranscriptProps) => { }: ChatTranscriptProps) => {
const { showRoomControls } = useContext(ShellContext)
const theme = useTheme()
const boxRef = useRef<HTMLDivElement>(null) const boxRef = useRef<HTMLDivElement>(null)
const [previousMessageLogLength, setPreviousMessageLogLength] = useState(0) const [previousMessageLogLength, setPreviousMessageLogLength] = useState(0)
@ -53,18 +57,25 @@ export const ChatTranscript = ({
setPreviousMessageLogLength(messageLog.length) setPreviousMessageLogLength(messageLog.length)
}, [messageLog.length]) }, [messageLog.length])
const transcriptMaxWidth = theme.breakpoints.values.md
const transcriptPaddingX = `(50% - ${
transcriptMaxWidth / 2
}px) - ${theme.spacing(1)}`
const transcriptMinPadding = theme.spacing(1)
return ( return (
<Box <Box
ref={boxRef} ref={boxRef}
className={cx('ChatTranscript', className)} className={cx('ChatTranscript', className)}
sx={theme => ({ sx={{
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
mx: 'auto', py: transcriptMinPadding,
paddingY: theme.spacing(1), pt: showRoomControls ? theme.spacing(10) : theme.spacing(2),
px: `max(${transcriptPaddingX}, ${transcriptMinPadding})`,
transition: `padding-top ${theme.transitions.duration.short}ms ${theme.transitions.easing.easeInOut}`,
width: '100%', width: '100%',
maxWidth: theme.breakpoints.values.md, }}
})}
> >
{messageLog.map((message, idx) => { {messageLog.map((message, idx) => {
const previousMessage = messageLog[idx - 1] const previousMessage = messageLog[idx - 1]

View File

@ -1,9 +1,9 @@
import { useContext } from 'react' import { useContext } from 'react'
import { useWindowSize } from '@react-hook/window-size' import { useWindowSize } from '@react-hook/window-size'
import Collapse from '@mui/material/Collapse'
import Zoom from '@mui/material/Zoom' import Zoom from '@mui/material/Zoom'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import Divider from '@mui/material/Divider' import Divider from '@mui/material/Divider'
import useTheme from '@mui/material/styles/useTheme'
import { v4 as uuid } from 'uuid' import { v4 as uuid } from 'uuid'
import { rtcConfig } from 'config/rtcConfig' import { rtcConfig } from 'config/rtcConfig'
@ -22,7 +22,6 @@ import { RoomScreenShareControls } from './RoomScreenShareControls'
import { RoomFileUploadControls } from './RoomFileUploadControls' import { RoomFileUploadControls } from './RoomFileUploadControls'
import { RoomVideoDisplay } from './RoomVideoDisplay' import { RoomVideoDisplay } from './RoomVideoDisplay'
import { RoomShowMessagesControls } from './RoomShowMessagesControls' import { RoomShowMessagesControls } from './RoomShowMessagesControls'
import { RoomHideRoomControls } from './RoomHideRoomControls'
import { TypingStatusBar } from './TypingStatusBar' import { TypingStatusBar } from './TypingStatusBar'
export interface RoomProps { export interface RoomProps {
@ -40,6 +39,7 @@ export function Room({
password, password,
userId, userId,
}: RoomProps) { }: RoomProps) {
const theme = useTheme()
const settingsContext = useContext(SettingsContext) const settingsContext = useContext(SettingsContext)
const { showActiveTypingStatus } = settingsContext.getUserSettings() const { showActiveTypingStatus } = settingsContext.getUserSettings()
const { const {
@ -96,14 +96,16 @@ export function Room({
overflow: 'auto', overflow: 'auto',
}} }}
> >
<Collapse in={showRoomControls}> <Zoom in={showRoomControls}>
<Box <Box
sx={{ sx={{
alignItems: 'flex-start', alignItems: 'flex-start',
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
padding: 1, overflow: 'visible',
overflowX: 'auto', height: 0,
position: 'relative',
top: theme.spacing(1),
}} }}
> >
<RoomAudioControls peerRoom={peerRoom} /> <RoomAudioControls peerRoom={peerRoom} />
@ -118,9 +120,8 @@ export function Room({
<RoomShowMessagesControls /> <RoomShowMessagesControls />
</span> </span>
</Zoom> </Zoom>
<RoomHideRoomControls />
</Box> </Box>
</Collapse> </Zoom>
<Box <Box
sx={{ sx={{
display: 'flex', display: 'flex',
@ -150,7 +151,7 @@ export function Room({
<ChatTranscript <ChatTranscript
messageLog={messageLog} messageLog={messageLog}
userId={userId} userId={userId}
className="grow overflow-auto px-4" className="grow overflow-auto"
/> />
<Divider /> <Divider />
<Box> <Box>

View File

@ -85,7 +85,7 @@ export const ShellAppBar = ({
isFullscreen, isFullscreen,
setIsFullscreen, setIsFullscreen,
}: ShellAppBarProps) => { }: ShellAppBarProps) => {
const { peerList, isEmbedded } = useContext(ShellContext) const { peerList, isEmbedded, showRoomControls } = useContext(ShellContext)
const handleQRCodeClick = () => setIsQRCodeDialogOpen(true) const handleQRCodeClick = () => setIsQRCodeDialogOpen(true)
const onClickFullscreen = () => setIsFullscreen(!isFullscreen) const onClickFullscreen = () => setIsFullscreen(!isFullscreen)
@ -149,7 +149,11 @@ export const ShellAppBar = ({
</Tooltip> </Tooltip>
</> </>
)} )}
<Tooltip title="Show Room Controls"> <Tooltip
title={
showRoomControls ? 'Hide Room Controls' : 'Show Room Controls'
}
>
<IconButton <IconButton
size="large" size="large"
color="inherit" color="inherit"