Skip to content

Commit

Permalink
Merge branch 'rm/336493' into 'master'
Browse files Browse the repository at this point in the history
Fix: New responsive component for transcript

See merge request kchat/webapp!796
  • Loading branch information
antonbuks committed Jul 18, 2024
2 parents b625317 + 8625288 commit 722891c
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 92 deletions.
93 changes: 57 additions & 36 deletions webapp/channels/src/components/transcript/transcript.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,74 @@

import Popover from '@mui/material/Popover';
import React from 'react';
import {FormattedMessage} from 'react-intl';
import {useSelector} from 'react-redux';

import type {TranscriptData} from '@mattermost/types/transcript';

import Popover from 'components/widgets/popover';
import '../../../src/sass/components/_transcript.scss';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';

import CompassDesignProvider from 'components/compass_design_provider';

interface Props {
transcriptDatas: TranscriptData;
className?: string;
anchorEl: Element | null;
handleClose: () => void;
open: boolean;
}

const TranscriptComponent: React.FC<Props> = ({transcriptDatas, ...restProps}) => {
const TranscriptComponent: React.FC<Props> = ({transcriptDatas, anchorEl, handleClose, open}) => {
const theme = useSelector(getTheme);
const id = open ? 'simple-popover' : undefined;

return (
<div
{...restProps}
className='transcript-container'

>
<Popover className='transcript-popover'>
<div className='transcript-text'>
<FormattedMessage
id='vocals.transcript_title'
defaultMessage='Audio Transcript (auto-generated)'
/>
</div>
<div >
{transcriptDatas.segments.map((segment, index) => {
const minutes = Math.floor(segment.start / 60);
const seconds = Math.floor(segment.start % 60);
const time = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
return (
<div
// eslint-disable-next-line react/no-array-index-key
key={index}
>
<p>
<span className='time-transcript'>
{time}
</span>
{''}
{` ${segment.text.trim()}`}
</p>
</div>
);
})}
<CompassDesignProvider theme={theme}>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<div className='transcript-popover'>
<div className='transcript-text'>
<FormattedMessage
id='vocals.transcript_title'
defaultMessage='Audio Transcript (auto-generated)'
/>
</div>
<div>
{transcriptDatas.segments.map((segment, index) => {
const minutes = Math.floor(segment.start / 60);
const seconds = Math.floor(segment.start % 60);
const time = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
return (
<div
// eslint-disable-next-line react/no-array-index-key
key={index}
>
<p>
<span className='time-transcript'>
{time}
</span>
{''}
{` ${segment.text.trim()}`}
</p>
</div>
);
})}
</div>
</div>
</Popover>
</div>
</CompassDesignProvider>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
useAudioPlayer,
} from 'components/common/hooks/useAudioPlayer';
import * as Menu from 'components/menu';
import OverlayTrigger from 'components/overlay_trigger';
import TranscriptComponent from 'components/transcript/transcript';
import LoadingSpinner from 'components/widgets/loading/loading_spinner';

Expand All @@ -40,23 +39,28 @@ export interface Props {

function VoiceMessageAttachmentPlayer(props: Props) {
const {formatMessage} = useIntl();

const {playerState, duration, elapsed, togglePlayPause} = useAudioPlayer(props.fileId ? `/api/v4/files/${props.fileId}` : '');

const progressValue = elapsed === 0 || duration === 0 ? '0' : (elapsed / duration).toFixed(2);
const [transcript, setTranscript] = useState('');
const [transcriptDatas, setTranscriptDatas] = useState<TranscriptData>();
const [isTranscriptOpen, setIsTranscriptOpen] = useState(false);
const [hasFetchedTranscript, setHasFetchedTranscript] = useState(false);
const [isLoadingTranscript, setIsLoadingTranscript] = useState(false);
const [error, setError] = useState<JSX.Element | null>(null);
const [anchorEl, setAnchorEl] = React.useState<HTMLAnchorElement | null>(null);
const [isTranscriptModalOpen, setIsTranscriptModalOpen] = useState(false);

const open = Boolean(anchorEl);

const handleClick = (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
setAnchorEl(event.currentTarget);
};

const handleClose = () => {
setAnchorEl(null);
};

const fetchTranscript = async () => {
if (isTranscriptOpen) {
setIsTranscriptOpen(false);
return;
}
setIsTranscriptOpen(true);
if (!hasFetchedTranscript) {
setIsLoadingTranscript(true);
const result = await fetchTranscriptData(props.fileId)();
Expand All @@ -71,7 +75,6 @@ function VoiceMessageAttachmentPlayer(props: Props) {
setIsLoadingTranscript(false);
setTranscript((result as TranscriptData).text.trim());
setTranscriptDatas((result as TranscriptData));
setIsTranscriptOpen(true);
setHasFetchedTranscript(true);
}
};
Expand All @@ -81,6 +84,9 @@ function VoiceMessageAttachmentPlayer(props: Props) {
function downloadFile() {
window.location.assign(getFileDownloadUrl(props.fileId));
}
const toggleTranscriptModal = () => {
setIsTranscriptModalOpen(!isTranscriptModalOpen);
};

return (
<>
Expand Down Expand Up @@ -159,13 +165,18 @@ function VoiceMessageAttachmentPlayer(props: Props) {
)}
{!props.isPreview && (
<div
onClick={fetchTranscript}
onClick={() => {
fetchTranscript();
toggleTranscriptModal();
}}
className='post-image__end-button'
>
{isLoadingTranscript ? (<LoadingSpinner/>) : (
<img
src={transcriptIcon()}
/>
{isLoadingTranscript ? (
<LoadingSpinner/>
) : (
<div >
<img src={transcriptIcon()}/>
</div>
)}
</div>)}
{!props.inPost && (
Expand All @@ -183,25 +194,29 @@ function VoiceMessageAttachmentPlayer(props: Props) {
</div>
<div >
<div>
{transcript && isTranscriptOpen && (transcript.length > 300 ? transcript.substring(0, 300) + '... ' : transcript + ' ')}
{transcript && isTranscriptOpen && transcriptDatas &&
<OverlayTrigger
overlay={
<TranscriptComponent
className='transcript-popover'
transcriptDatas={transcriptDatas}
/>
}
trigger={['click']}
rootClose={true}
>
<a className='transcript-link-view'>
<FormattedMessage
id={'vocals.loading_transcript'}
defaultMessage={'View transcript'}
/>
</a>
</OverlayTrigger>
{transcript && transcriptDatas && isTranscriptModalOpen && (
<div>
{transcript.length > 300 ? transcript.substring(0, 300) + '... ' : transcript + ' '}
<a
className='transcript-link-view'
onClick={(event) => {
handleClick(event);
}}
>
<FormattedMessage
id={'vocals.loading_transcript'}
defaultMessage={'View transcript'}
/>
</a>
</div>
)}
{transcriptDatas &&
<TranscriptComponent
transcriptDatas={transcriptDatas}
handleClose={handleClose}
open={open}
anchorEl={anchorEl}
/>
}
</div>
{error && <div className='transcript-error'>{error}</div>}
Expand Down
26 changes: 3 additions & 23 deletions webapp/channels/src/sass/components/_transcript.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,8 @@
margin-top: 3px;
}

.transcript-container{
position: absolute;
width: 0;
height: 0;
}

.transcript-popover{
position: absolute;
top: calc(100% - 400px);
left: 0;
width: 400px;
height: 400px;
overflow: auto;

@media screen and (max-width: 1280px) {
left: unset;
right: 0;
}
@media screen and (max-width: 768px) {
position: fixed;
top: 0;
left: 0;
height: 100vh;
}
padding: 10px;
max-height: 300px;
max-width: 350px;
}

0 comments on commit 722891c

Please sign in to comment.