@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
66Please see LICENSE files in the repository root for full details.
77*/
88
9- import React from "react" ;
9+ import React , { type JSX , useEffect , useMemo } from "react" ;
1010import { logger } from "matrix-js-sdk/src/logger" ;
1111import { type IContent } from "matrix-js-sdk/src/matrix" ;
1212import { type MediaEventContent } from "matrix-js-sdk/src/types" ;
@@ -17,8 +17,6 @@ import { _t } from "../../../languageHandler";
1717import MFileBody from "./MFileBody" ;
1818import { type IBodyProps } from "./IBodyProps" ;
1919import { PlaybackManager } from "../../../audio/PlaybackManager" ;
20- import { isVoiceMessage } from "../../../utils/EventUtils" ;
21- import { PlaybackQueue } from "../../../audio/PlaybackQueue" ;
2220import RoomContext , { TimelineRenderingType } from "../../../contexts/RoomContext" ;
2321import MediaProcessingError from "./shared/MediaProcessingError" ;
2422import { AudioPlayerViewModel } from "../../../viewmodels/audio/AudioPlayerViewModel" ;
@@ -27,7 +25,6 @@ import { AudioPlayerView } from "../../../shared-components/audio/AudioPlayerVie
2725interface IState {
2826 error ?: boolean ;
2927 playback ?: Playback ;
30- audioPlayerVm ?: AudioPlayerViewModel ;
3128}
3229
3330export default class MAudioBody extends React . PureComponent < IBodyProps , IState > {
@@ -38,7 +35,6 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
3835
3936 public async componentDidMount ( ) : Promise < void > {
4037 let buffer : ArrayBuffer ;
41-
4238 try {
4339 try {
4440 const blob = await this . props . mediaEventHelper ! . sourceBlob . value ;
@@ -63,18 +59,16 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
6359 // We should have a buffer to work with now: let's set it up
6460 const playback = PlaybackManager . instance . createPlaybackInstance ( buffer , waveform ) ;
6561 playback . clockInfo . populatePlaceholdersFrom ( this . props . mxEvent ) ;
66- this . setState ( { playback, audioPlayerVm : new AudioPlayerViewModel ( { playback, mediaName : content . body } ) } ) ;
67-
68- if ( isVoiceMessage ( this . props . mxEvent ) ) {
69- PlaybackQueue . forRoom ( this . props . mxEvent . getRoomId ( ) ! ) . unsortedEnqueue ( this . props . mxEvent , playback ) ;
70- }
62+ this . setState ( { playback } ) ;
7163
72- // Note: the components later on will handle preparing the Playback class for us.
64+ this . onMount ( playback ) ;
65+ // Note: the components later on will handle preparing the Playback class for us
7366 }
7467
68+ protected onMount ( playback : Playback ) : void { }
69+
7570 public componentWillUnmount ( ) : void {
7671 this . state . playback ?. destroy ( ) ;
77- this . state . audioPlayerVm ?. dispose ( ) ;
7872 }
7973
8074 protected get showFileBody ( ) : boolean {
@@ -116,9 +110,35 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
116110 // At this point we should have a playable state
117111 return (
118112 < span className = "mx_MAudioBody" >
119- { this . state . audioPlayerVm && < AudioPlayerView vm = { this . state . audioPlayerVm } /> }
113+ < AudioPlayer playback = { this . state . playback } mediaName = { this . props . mxEvent . getContent ( ) . body } />
120114 { this . showFileBody && < MFileBody { ...this . props } showGenericPlaceholder = { false } /> }
121115 </ span >
122116 ) ;
123117 }
124118}
119+
120+ interface AudioPlayerProps {
121+ /**
122+ * The playback instance to control audio playback.
123+ */
124+ playback : Playback ;
125+ /**
126+ * The name of the media being played
127+ */
128+ mediaName : string ;
129+ }
130+
131+ /**
132+ * AudioPlayer component that initializes the AudioPlayerViewModel and renders the AudioPlayerView.
133+ */
134+ function AudioPlayer ( { playback, mediaName } : AudioPlayerProps ) : JSX . Element {
135+ const vm = useMemo ( ( ) => new AudioPlayerViewModel ( { playback, mediaName } ) , [ playback , mediaName ] ) ;
136+
137+ useEffect ( ( ) => {
138+ return ( ) => {
139+ vm . dispose ( ) ;
140+ } ;
141+ } , [ vm ] ) ;
142+
143+ return < AudioPlayerView vm = { vm } /> ;
144+ }
0 commit comments