mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-05-14 11:37:48 +00:00
Chat and CC panels showed oldest messages at the top when opened because scrollIntoView was called on hidden (display: none) elements where it silently does nothing. Now we skip scrolling on mount for hidden tabs and defer it to when each tab first becomes visible, while preserving the user's scroll position on subsequent tab switches.
133 lines
4.0 KiB
TypeScript
133 lines
4.0 KiB
TypeScript
import React from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useSelector } from 'react-redux';
|
|
import { makeStyles } from 'tss-react/mui';
|
|
|
|
import Icon from '../../../base/icons/components/Icon';
|
|
import { IconSubtitles } from '../../../base/icons/svg';
|
|
import Button from '../../../base/ui/components/web/Button';
|
|
import LanguageSelector from '../../../subtitles/components/web/LanguageSelector';
|
|
import { ChatTabs } from '../../constants';
|
|
import { getFocusedTab } from '../../functions';
|
|
// @ts-ignore
|
|
import AbstractClosedCaptions, { AbstractProps } from '../AbstractClosedCaptions';
|
|
|
|
import { SubtitlesMessagesContainer } from './SubtitlesMessagesContainer';
|
|
|
|
/**
|
|
* The styles for the ClosedCaptionsTab component.
|
|
*/
|
|
const useStyles = makeStyles()(theme => {
|
|
return {
|
|
subtitlesList: {
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
height: '100%',
|
|
overflowY: 'auto',
|
|
padding: '16px',
|
|
flex: 1,
|
|
boxSizing: 'border-box',
|
|
color: theme.palette.chatMessageText
|
|
},
|
|
container: {
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
height: '100%',
|
|
position: 'relative',
|
|
overflow: 'hidden'
|
|
},
|
|
messagesContainer: {
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
flex: 1,
|
|
overflow: 'hidden'
|
|
},
|
|
emptyContent: {
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
height: '100%',
|
|
padding: '16px',
|
|
boxSizing: 'border-box',
|
|
flexDirection: 'column',
|
|
gap: '16px',
|
|
color: theme.palette.chatMessageText,
|
|
textAlign: 'center'
|
|
},
|
|
emptyIcon: {
|
|
width: '100px',
|
|
padding: '16px',
|
|
|
|
'& svg': {
|
|
width: '100%',
|
|
height: 'auto'
|
|
}
|
|
},
|
|
emptyState: {
|
|
...theme.typography.bodyLongBold,
|
|
color: theme.palette.chatSenderName
|
|
}
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Component that displays the subtitles history in a scrollable list.
|
|
*
|
|
* @returns {JSX.Element} - The ClosedCaptionsTab component.
|
|
*/
|
|
const ClosedCaptionsTab = ({
|
|
canStartSubtitles,
|
|
filteredSubtitles,
|
|
groupedSubtitles,
|
|
isButtonPressed,
|
|
isTranscribing,
|
|
startClosedCaptions
|
|
}: AbstractProps): JSX.Element => {
|
|
const { classes, theme } = useStyles();
|
|
const { t } = useTranslation();
|
|
const isVisible = useSelector(getFocusedTab) === ChatTabs.CLOSED_CAPTIONS;
|
|
|
|
if (!isTranscribing) {
|
|
if (canStartSubtitles) {
|
|
return (
|
|
<div className = { classes.emptyContent }>
|
|
<Button
|
|
accessibilityLabel = 'Start Closed Captions'
|
|
appearance = 'primary'
|
|
disabled = { isButtonPressed }
|
|
labelKey = 'closedCaptionsTab.startClosedCaptionsButton'
|
|
onClick = { startClosedCaptions }
|
|
size = 'large'
|
|
type = 'primary' />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className = { classes.emptyContent }>
|
|
<Icon
|
|
className = { classes.emptyIcon }
|
|
color = { theme.palette.chatEmptyText }
|
|
src = { IconSubtitles } />
|
|
<span className = { classes.emptyState }>
|
|
{ t('closedCaptionsTab.emptyState') }
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className = { classes.container }>
|
|
<LanguageSelector />
|
|
<div className = { classes.messagesContainer }>
|
|
<SubtitlesMessagesContainer
|
|
groups = { groupedSubtitles }
|
|
isVisible = { isVisible }
|
|
messages = { filteredSubtitles } />
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AbstractClosedCaptions(ClosedCaptionsTab);
|