123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551 |
- import { NOTIFICATION_TIMEOUT, showNotification } from '../../notifications';
- import { set } from '../redux';
-
- import {
- DOMINANT_SPEAKER_CHANGED,
- HIDDEN_PARTICIPANT_JOINED,
- HIDDEN_PARTICIPANT_LEFT,
- GRANT_MODERATOR,
- KICK_PARTICIPANT,
- MUTE_REMOTE_PARTICIPANT,
- PARTICIPANT_ID_CHANGED,
- PARTICIPANT_JOINED,
- PARTICIPANT_KICKED,
- PARTICIPANT_LEFT,
- PARTICIPANT_UPDATED,
- PIN_PARTICIPANT,
- SET_LOADABLE_AVATAR_URL
- } from './actionTypes';
- import {
- DISCO_REMOTE_CONTROL_FEATURE
- } from './constants';
- import {
- getLocalParticipant,
- getNormalizedDisplayName,
- getParticipantDisplayName,
- getParticipantById
- } from './functions';
- import logger from './logger';
-
- /**
- * Create an action for when dominant speaker changes.
- *
- * @param {string} id - Participant's ID.
- * @param {JitsiConference} conference - The {@code JitsiConference} associated
- * with the participant identified by the specified {@code id}. Only the local
- * participant is allowed to not specify an associated {@code JitsiConference}
- * instance.
- * @returns {{
- * type: DOMINANT_SPEAKER_CHANGED,
- * participant: {
- * conference: JitsiConference,
- * id: string
- * }
- * }}
- */
- export function dominantSpeakerChanged(id, conference) {
- return {
- type: DOMINANT_SPEAKER_CHANGED,
- participant: {
- conference,
- id
- }
- };
- }
-
- /**
- * Create an action for granting moderator to a participant.
- *
- * @param {string} id - Participant's ID.
- * @returns {{
- * type: GRANT_MODERATOR,
- * id: string
- * }}
- */
- export function grantModerator(id) {
- return {
- type: GRANT_MODERATOR,
- id
- };
- }
-
- /**
- * Create an action for removing a participant from the conference.
- *
- * @param {string} id - Participant's ID.
- * @returns {{
- * type: KICK_PARTICIPANT,
- * id: string
- * }}
- */
- export function kickParticipant(id) {
- return {
- type: KICK_PARTICIPANT,
- id
- };
- }
-
- /**
- * Creates an action to signal the connection status of the local participant
- * has changed.
- *
- * @param {string} connectionStatus - The current connection status of the local
- * participant, as enumerated by the library's participantConnectionStatus
- * constants.
- * @returns {Function}
- */
- export function localParticipantConnectionStatusChanged(connectionStatus) {
- return (dispatch, getState) => {
- const participant = getLocalParticipant(getState);
-
- if (participant) {
- return dispatch(participantConnectionStatusChanged(
- participant.id,
- connectionStatus));
- }
- };
- }
-
- /**
- * Action to signal that the ID of local participant has changed. It happens
- * when the local participant joins a new conference or leaves an existing
- * conference.
- *
- * @param {string} id - New ID for local participant.
- * @returns {Function}
- */
- export function localParticipantIdChanged(id) {
- return (dispatch, getState) => {
- const participant = getLocalParticipant(getState);
-
- if (participant) {
- return dispatch({
- type: PARTICIPANT_ID_CHANGED,
-
- // XXX A participant is identified by an id-conference pair.
- // Only the local participant is with an undefined conference.
- conference: undefined,
- newValue: id,
- oldValue: participant.id
- });
- }
- };
- }
-
- /**
- * Action to signal that a local participant has joined.
- *
- * @param {Participant} participant={} - Information about participant.
- * @returns {{
- * type: PARTICIPANT_JOINED,
- * participant: Participant
- * }}
- */
- export function localParticipantJoined(participant = {}) {
- return participantJoined(set(participant, 'local', true));
- }
-
- /**
- * Action to remove a local participant.
- *
- * @returns {Function}
- */
- export function localParticipantLeft() {
- return (dispatch, getState) => {
- const participant = getLocalParticipant(getState);
-
- if (participant) {
- return (
- dispatch(
- participantLeft(
- participant.id,
-
- // XXX Only the local participant is allowed to leave
- // without stating the JitsiConference instance because
- // the local participant is uniquely identified by the
- // very fact that there is only one local participant
- // (and the fact that the local participant "joins" at
- // the beginning of the app and "leaves" at the end of
- // the app).
- undefined)));
- }
- };
- }
-
- /**
- * Action to signal the role of the local participant has changed. It can happen
- * when the participant has joined a conference, even before a non-default local
- * id has been set, or after a moderator leaves.
- *
- * @param {string} role - The new role of the local participant.
- * @returns {Function}
- */
- export function localParticipantRoleChanged(role) {
- return (dispatch, getState) => {
- const participant = getLocalParticipant(getState);
-
- if (participant) {
- return dispatch(participantRoleChanged(participant.id, role));
- }
- };
- }
-
- /**
- * Create an action for muting another participant in the conference.
- *
- * @param {string} id - Participant's ID.
- * @param {MEDIA_TYPE} mediaType - The media to mute.
- * @returns {{
- * type: MUTE_REMOTE_PARTICIPANT,
- * id: string,
- * mediaType: MEDIA_TYPE
- * }}
- */
- export function muteRemoteParticipant(id, mediaType) {
- return {
- type: MUTE_REMOTE_PARTICIPANT,
- id,
- mediaType
- };
- }
-
- /**
- * Action to update a participant's connection status.
- *
- * @param {string} id - Participant's ID.
- * @param {string} connectionStatus - The new connection status of the
- * participant.
- * @returns {{
- * type: PARTICIPANT_UPDATED,
- * participant: {
- * connectionStatus: string,
- * id: string
- * }
- * }}
- */
- export function participantConnectionStatusChanged(id, connectionStatus) {
- return {
- type: PARTICIPANT_UPDATED,
- participant: {
- connectionStatus,
- id
- }
- };
- }
-
- /**
- * Action to signal that a participant has joined.
- *
- * @param {Participant} participant - Information about participant.
- * @returns {{
- * type: PARTICIPANT_JOINED,
- * participant: Participant
- * }}
- */
- export function participantJoined(participant) {
- // Only the local participant is not identified with an id-conference pair.
- if (participant.local) {
- return {
- type: PARTICIPANT_JOINED,
- participant
- };
- }
-
- // In other words, a remote participant is identified with an id-conference
- // pair.
- const { conference } = participant;
-
- if (!conference) {
- throw Error(
- 'A remote participant must be associated with a JitsiConference!');
- }
-
- return (dispatch, getState) => {
- // A remote participant is only expected to join in a joined or joining
- // conference. The following check is really necessary because a
- // JitsiConference may have moved into leaving but may still manage to
- // sneak a PARTICIPANT_JOINED in if its leave is delayed for any purpose
- // (which is not outragous given that leaving involves network
- // requests.)
- const stateFeaturesBaseConference
- = getState()['features/base/conference'];
-
- if (conference === stateFeaturesBaseConference.conference
- || conference === stateFeaturesBaseConference.joining) {
- return dispatch({
- type: PARTICIPANT_JOINED,
- participant
- });
- }
- };
- }
-
- /**
- * Updates the features of a remote participant.
- *
- * @param {JitsiParticipant} jitsiParticipant - The ID of the participant.
- * @returns {{
- * type: PARTICIPANT_UPDATED,
- * participant: Participant
- * }}
- */
- export function updateRemoteParticipantFeatures(jitsiParticipant) {
- return (dispatch, getState) => {
- if (!jitsiParticipant) {
- return;
- }
-
- const id = jitsiParticipant.getId();
-
- jitsiParticipant.getFeatures()
- .then(features => {
- const supportsRemoteControl = features.has(DISCO_REMOTE_CONTROL_FEATURE);
- const participant = getParticipantById(getState(), id);
-
- if (!participant || participant.local) {
- return;
- }
-
- if (participant?.supportsRemoteControl !== supportsRemoteControl) {
- return dispatch({
- type: PARTICIPANT_UPDATED,
- participant: {
- id,
- supportsRemoteControl
- }
- });
- }
- })
- .catch(error => {
- logger.error(`Failed to get participant features for ${id}!`, error);
- });
- };
- }
-
- /**
- * Action to signal that a hidden participant has joined the conference.
- *
- * @param {string} id - The id of the participant.
- * @param {string} displayName - The display name, or undefined when
- * unknown.
- * @returns {{
- * type: HIDDEN_PARTICIPANT_JOINED,
- * displayName: string,
- * id: string
- * }}
- */
- export function hiddenParticipantJoined(id, displayName) {
- return {
- type: HIDDEN_PARTICIPANT_JOINED,
- id,
- displayName
- };
- }
-
- /**
- * Action to signal that a hidden participant has left the conference.
- *
- * @param {string} id - The id of the participant.
- * @returns {{
- * type: HIDDEN_PARTICIPANT_LEFT,
- * id: string
- * }}
- */
- export function hiddenParticipantLeft(id) {
- return {
- type: HIDDEN_PARTICIPANT_LEFT,
- id
- };
- }
-
- /**
- * Action to signal that a participant has left.
- *
- * @param {string} id - Participant's ID.
- * @param {JitsiConference} conference - The {@code JitsiConference} associated
- * with the participant identified by the specified {@code id}. Only the local
- * participant is allowed to not specify an associated {@code JitsiConference}
- * instance.
- * @returns {{
- * type: PARTICIPANT_LEFT,
- * participant: {
- * conference: JitsiConference,
- * id: string
- * }
- * }}
- */
- export function participantLeft(id, conference) {
- return {
- type: PARTICIPANT_LEFT,
- participant: {
- conference,
- id
- }
- };
- }
-
- /**
- * Action to signal that a participant's presence status has changed.
- *
- * @param {string} id - Participant's ID.
- * @param {string} presence - Participant's new presence status.
- * @returns {{
- * type: PARTICIPANT_UPDATED,
- * participant: {
- * id: string,
- * presence: string
- * }
- * }}
- */
- export function participantPresenceChanged(id, presence) {
- return participantUpdated({
- id,
- presence
- });
- }
-
- /**
- * Action to signal that a participant's role has changed.
- *
- * @param {string} id - Participant's ID.
- * @param {PARTICIPANT_ROLE} role - Participant's new role.
- * @returns {{
- * type: PARTICIPANT_UPDATED,
- * participant: {
- * id: string,
- * role: PARTICIPANT_ROLE
- * }
- * }}
- */
- export function participantRoleChanged(id, role) {
- return participantUpdated({
- id,
- role
- });
- }
-
- /**
- * Action to signal that some of participant properties has been changed.
- *
- * @param {Participant} participant={} - Information about participant. To
- * identify the participant the object should contain either property id with
- * value the id of the participant or property local with value true (if the
- * local participant hasn't joined the conference yet).
- * @returns {{
- * type: PARTICIPANT_UPDATED,
- * participant: Participant
- * }}
- */
- export function participantUpdated(participant = {}) {
- const participantToUpdate = {
- ...participant
- };
-
- if (participant.name) {
- participantToUpdate.name = getNormalizedDisplayName(participant.name);
- }
-
- return {
- type: PARTICIPANT_UPDATED,
- participant: participantToUpdate
- };
- }
-
- /**
- * Action to signal that a participant has muted us.
- *
- * @param {JitsiParticipant} participant - Information about participant.
- * @param {JitsiLocalTrack} track - Information about the track that has been muted.
- * @returns {Promise}
- */
- export function participantMutedUs(participant, track) {
- return (dispatch, getState) => {
- if (!participant) {
- return;
- }
-
- const isAudio = track.isAudioTrack();
-
- dispatch(showNotification({
- descriptionKey: isAudio ? 'notify.mutedRemotelyDescription' : 'notify.videoMutedRemotelyDescription',
- titleKey: isAudio ? 'notify.mutedRemotelyTitle' : 'notify.videoMutedRemotelyTitle',
- titleArguments: {
- participantDisplayName:
- getParticipantDisplayName(getState, participant.getId())
- }
- }));
- };
- }
-
- /**
- * Action to signal that a participant had been kicked.
- *
- * @param {JitsiParticipant} kicker - Information about participant performing the kick.
- * @param {JitsiParticipant} kicked - Information about participant that was kicked.
- * @returns {Promise}
- */
- export function participantKicked(kicker, kicked) {
- return (dispatch, getState) => {
-
- dispatch({
- type: PARTICIPANT_KICKED,
- kicked: kicked.getId(),
- kicker: kicker.getId()
- });
-
- dispatch(showNotification({
- titleArguments: {
- kicked:
- getParticipantDisplayName(getState, kicked.getId()),
- kicker:
- getParticipantDisplayName(getState, kicker.getId())
- },
- titleKey: 'notify.kickParticipant'
- }, NOTIFICATION_TIMEOUT * 2)); // leave more time for this
- };
- }
-
- /**
- * Create an action which pins a conference participant.
- *
- * @param {string|null} id - The ID of the conference participant to pin or null
- * if none of the conference's participants are to be pinned.
- * @returns {{
- * type: PIN_PARTICIPANT,
- * participant: {
- * id: string
- * }
- * }}
- */
- export function pinParticipant(id) {
- return {
- type: PIN_PARTICIPANT,
- participant: {
- id
- }
- };
- }
-
- /**
- * Creates an action which notifies the app that the loadable URL of the avatar of a participant got updated.
- *
- * @param {string} participantId - The ID of the participant.
- * @param {string} url - The new URL.
- * @returns {{
- * type: SET_LOADABLE_AVATAR_URL,
- * participant: {
- * id: string,
- * loadableAvatarUrl: string
- * }
- * }}
- */
- export function setLoadableAvatarUrl(participantId, url) {
- return {
- type: SET_LOADABLE_AVATAR_URL,
- participant: {
- id: participantId,
- loadableAvatarUrl: url
- }
- };
- }
|