diff --git a/react/features/base/conference/actions.js b/react/features/base/conference/actions.js index fb28781a7..ff86b55cb 100644 --- a/react/features/base/conference/actions.js +++ b/react/features/base/conference/actions.js @@ -15,6 +15,7 @@ import { participantConnectionStatusChanged, participantJoined, participantLeft, + participantPresenceChanged, participantRoleChanged, participantUpdated } from '../participants'; @@ -146,6 +147,7 @@ function _addConferenceListeners(conference, dispatch) { conference, id, name: user.getDisplayName(), + presence: user.getStatus(), role: user.getRole() }))); conference.on( @@ -155,6 +157,9 @@ function _addConferenceListeners(conference, dispatch) { conference.on( JitsiConferenceEvents.USER_ROLE_CHANGED, (...args) => dispatch(participantRoleChanged(...args))); + conference.on( + JitsiConferenceEvents.USER_STATUS_CHANGED, + (...args) => dispatch(participantPresenceChanged(...args))); conference.addCommandListener( AVATAR_ID_COMMAND, diff --git a/react/features/base/media/components/AbstractAudio.js b/react/features/base/media/components/AbstractAudio.js index 28c3d6853..93319db07 100644 --- a/react/features/base/media/components/AbstractAudio.js +++ b/react/features/base/media/components/AbstractAudio.js @@ -10,7 +10,8 @@ export type AudioElement = { currentTime?: number, pause: () => void, play: () => void, - setSinkId?: string => void + setSinkId?: string => void, + stop: () => void }; /** @@ -61,8 +62,6 @@ export default class AbstractAudio extends Component { this.setAudioElementImpl = this.setAudioElementImpl.bind(this); } - pause: () => void; - /** * Attempts to pause the playback of the media. * @@ -73,10 +72,8 @@ export default class AbstractAudio extends Component { this._audioElementImpl && this._audioElementImpl.pause(); } - play: () => void; - /** - * Attempts to being the playback of the media. + * Attempts to begin the playback of the media. * * @public * @returns {void} @@ -106,8 +103,6 @@ export default class AbstractAudio extends Component { typeof setRef === 'function' && setRef(element ? this : null); } - setSinkId: string => void; - /** * Sets the sink ID (output device ID) on the underlying audio element. * NOTE: Currently, implemented only on Web. @@ -120,4 +115,14 @@ export default class AbstractAudio extends Component { && typeof this._audioElementImpl.setSinkId === 'function' && this._audioElementImpl.setSinkId(sinkId); } + + /** + * Attempts to stop the playback of the media. + * + * @public + * @returns {void} + */ + stop(): void { + this._audioElementImpl && this._audioElementImpl.stop(); + } } diff --git a/react/features/base/media/components/native/Audio.js b/react/features/base/media/components/native/Audio.js index 418c75ce7..e9007b2f7 100644 --- a/react/features/base/media/components/native/Audio.js +++ b/react/features/base/media/components/native/Audio.js @@ -12,11 +12,10 @@ const logger = require('jitsi-meet-logger').getLogger(__filename); * {@link RTCView}. */ export default class Audio extends AbstractAudio { - /** * Reference to 'react-native-sound} {@link Sound} instance. */ - _sound: Sound + _sound: ?Sound; /** * A callback passed to the 'react-native-sound''s {@link Sound} instance, @@ -56,9 +55,22 @@ export default class Audio extends AbstractAudio { */ componentWillUnmount() { if (this._sound) { - this.setAudioElementImpl(null); this._sound.release(); this._sound = null; + this.setAudioElementImpl(null); + } + } + + /** + * Attempts to begin the playback of the media. + * + * @inheritdoc + * @override + */ + play() { + if (this._sound) { + this._sound.setNumberOfLoops(this.props.loop ? -1 : 0); + super.play(); } } @@ -81,10 +93,8 @@ export default class Audio extends AbstractAudio { * @returns {void} */ stop() { - // Currently not implemented for mobile. If needed, a possible - // implementation is: - // if (this._sound) { - // this._sound.stop(); - // } + if (this._sound) { + this._sound.stop(); + } } }