Browse Source

Notify for kick and mute (#4328)

* Updates kick showing who kicked us.

* Notify participants that someone was kicked.

* Shows notification to user who is remotely muted.

* Updates the notification type.

* Muted by notification for mobile.

* Moves code to react and adds the kick notifications to mobile.

* Updates lib-jitsi-meet.
master
Дамян Минков 6 years ago
parent
commit
6eb66b639e
No account linked to committer's email address

+ 15
- 2
conference.js View File

86
     localParticipantConnectionStatusChanged,
86
     localParticipantConnectionStatusChanged,
87
     localParticipantRoleChanged,
87
     localParticipantRoleChanged,
88
     participantConnectionStatusChanged,
88
     participantConnectionStatusChanged,
89
+    participantKicked,
90
+    participantMutedUs,
89
     participantPresenceChanged,
91
     participantPresenceChanged,
90
     participantRoleChanged,
92
     participantRoleChanged,
91
     participantUpdated
93
     participantUpdated
103
     getLocationContextRoot,
105
     getLocationContextRoot,
104
     getJitsiMeetGlobalNS
106
     getJitsiMeetGlobalNS
105
 } from './react/features/base/util';
107
 } from './react/features/base/util';
108
+import { notifyKickedOut } from './react/features/conference';
106
 import { addMessage } from './react/features/chat';
109
 import { addMessage } from './react/features/chat';
107
 import { showDesktopPicker } from './react/features/desktop-picker';
110
 import { showDesktopPicker } from './react/features/desktop-picker';
108
 import { appendSuffix } from './react/features/display-name';
111
 import { appendSuffix } from './react/features/display-name';
1858
             APP.UI.setAudioLevel(id, newLvl);
1861
             APP.UI.setAudioLevel(id, newLvl);
1859
         });
1862
         });
1860
 
1863
 
1864
+        room.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED, (_, participantThatMutedUs) => {
1865
+            if (participantThatMutedUs) {
1866
+                APP.store.dispatch(participantMutedUs(participantThatMutedUs));
1867
+            }
1868
+        });
1869
+
1861
         room.on(JitsiConferenceEvents.TALK_WHILE_MUTED, () => {
1870
         room.on(JitsiConferenceEvents.TALK_WHILE_MUTED, () => {
1862
             APP.UI.showToolbar(6000);
1871
             APP.UI.showToolbar(6000);
1863
         });
1872
         });
1958
                 }
1967
                 }
1959
             });
1968
             });
1960
 
1969
 
1961
-        room.on(JitsiConferenceEvents.KICKED, () => {
1970
+        room.on(JitsiConferenceEvents.KICKED, participant => {
1962
             APP.UI.hideStats();
1971
             APP.UI.hideStats();
1963
-            APP.UI.notifyKicked();
1972
+            APP.store.dispatch(notifyKickedOut(participant));
1964
 
1973
 
1965
             // FIXME close
1974
             // FIXME close
1966
         });
1975
         });
1967
 
1976
 
1977
+        room.on(JitsiConferenceEvents.PARTICIPANT_KICKED, (kicker, kicked) => {
1978
+            APP.store.dispatch(participantKicked(kicker, kicked));
1979
+        });
1980
+
1968
         room.on(JitsiConferenceEvents.SUSPEND_DETECTED, () => {
1981
         room.on(JitsiConferenceEvents.SUSPEND_DETECTED, () => {
1969
             APP.store.dispatch(suspendDetected());
1982
             APP.store.dispatch(suspendDetected());
1970
 
1983
 

+ 5
- 2
lang/main.json View File

197
         "internalError": "Oops! Something went wrong. The following error occurred: __error__",
197
         "internalError": "Oops! Something went wrong. The following error occurred: __error__",
198
         "internalErrorTitle": "Internal error",
198
         "internalErrorTitle": "Internal error",
199
         "joinAgain": "Join again",
199
         "joinAgain": "Join again",
200
-        "kickMessage": "Ouch! You have been kicked out of the meet!",
200
+        "kickMessage": "You can contact __participantDisplayName__ for more details.",
201
         "kickParticipantButton": "Kick",
201
         "kickParticipantButton": "Kick",
202
         "kickParticipantDialog": "Are you sure you want to kick this participant?",
202
         "kickParticipantDialog": "Are you sure you want to kick this participant?",
203
         "kickParticipantTitle": "Kick this member?",
203
         "kickParticipantTitle": "Kick this member?",
204
-        "kickTitle": "Kicked from meeting",
204
+        "kickTitle": "Ouch! __participantDisplayName__ kicked you out of the meeting",
205
         "liveStreaming": "Live Streaming",
205
         "liveStreaming": "Live Streaming",
206
         "liveStreamingDisabledForGuestTooltip": "Guests can't start live streaming.",
206
         "liveStreamingDisabledForGuestTooltip": "Guests can't start live streaming.",
207
         "liveStreamingDisabledTooltip": "Start live stream disabled.",
207
         "liveStreamingDisabledTooltip": "Start live stream disabled.",
472
         "focus": "Conference focus",
472
         "focus": "Conference focus",
473
         "focusFail": "__component__ not available - retry in __ms__ sec",
473
         "focusFail": "__component__ not available - retry in __ms__ sec",
474
         "grantedTo": "Moderator rights granted to __to__!",
474
         "grantedTo": "Moderator rights granted to __to__!",
475
+        "kickParticipant": "__kicked__ was kicked by __kicker__",
475
         "me": "Me",
476
         "me": "Me",
476
         "moderator": "Moderator rights granted!",
477
         "moderator": "Moderator rights granted!",
477
         "muted": "You have started the conversation muted.",
478
         "muted": "You have started the conversation muted.",
478
         "mutedTitle": "You're muted!",
479
         "mutedTitle": "You're muted!",
480
+        "mutedRemotelyTitle": "You have been muted by __participantDisplayName__!",
481
+        "mutedRemotelyDescription": "You can always unmute when you're ready to speak. Mute back when you're done to keep noise away from the meeting.",
479
         "raisedHand": "__name__ would like to speak.",
482
         "raisedHand": "__name__ would like to speak.",
480
         "somebody": "Somebody",
483
         "somebody": "Somebody",
481
         "startSilentTitle": "You joined with no audio output!",
484
         "startSilentTitle": "You joined with no audio output!",

+ 0
- 11
modules/UI/UI.js View File

99
     });
99
     });
100
 };
100
 };
101
 
101
 
102
-/**
103
- * Notify user that he has been kicked from the server.
104
- */
105
-UI.notifyKicked = function() {
106
-    messageHandler.showError({
107
-        hideErrorSupportLink: true,
108
-        descriptionKey: 'dialog.kickMessage',
109
-        titleKey: 'dialog.kickTitle'
110
-    });
111
-};
112
-
113
 /**
102
 /**
114
  * Notify user that conference was destroyed.
103
  * Notify user that conference was destroyed.
115
  * @param reason {string} the reason text
104
  * @param reason {string} the reason text

+ 2
- 2
package-lock.json View File

8946
       }
8946
       }
8947
     },
8947
     },
8948
     "lib-jitsi-meet": {
8948
     "lib-jitsi-meet": {
8949
-      "version": "github:jitsi/lib-jitsi-meet#25ca5cbd2a93150e74f029075bc7ac734ed97a2f",
8950
-      "from": "github:jitsi/lib-jitsi-meet#25ca5cbd2a93150e74f029075bc7ac734ed97a2f",
8949
+      "version": "github:jitsi/lib-jitsi-meet#15e09476cdae1dee8f633c628681449be26d12be",
8950
+      "from": "github:jitsi/lib-jitsi-meet#15e09476cdae1dee8f633c628681449be26d12be",
8951
       "requires": {
8951
       "requires": {
8952
         "@jitsi/sdp-interop": "0.1.14",
8952
         "@jitsi/sdp-interop": "0.1.14",
8953
         "@jitsi/sdp-simulcast": "0.2.1",
8953
         "@jitsi/sdp-simulcast": "0.2.1",

+ 1
- 1
package.json View File

52
     "js-utils": "github:jitsi/js-utils#73a67a7a60d52f8e895f50939c8fcbd1f20fe7b5",
52
     "js-utils": "github:jitsi/js-utils#73a67a7a60d52f8e895f50939c8fcbd1f20fe7b5",
53
     "jsrsasign": "8.0.12",
53
     "jsrsasign": "8.0.12",
54
     "jwt-decode": "2.2.0",
54
     "jwt-decode": "2.2.0",
55
-    "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#25ca5cbd2a93150e74f029075bc7ac734ed97a2f",
55
+    "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#15e09476cdae1dee8f633c628681449be26d12be",
56
     "libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
56
     "libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
57
     "lodash": "4.17.11",
57
     "lodash": "4.17.11",
58
     "moment": "2.19.4",
58
     "moment": "2.19.4",

+ 22
- 4
react/features/base/conference/actions.js View File

14
     dominantSpeakerChanged,
14
     dominantSpeakerChanged,
15
     getNormalizedDisplayName,
15
     getNormalizedDisplayName,
16
     participantConnectionStatusChanged,
16
     participantConnectionStatusChanged,
17
+    participantKicked,
18
+    participantMutedUs,
17
     participantPresenceChanged,
19
     participantPresenceChanged,
18
     participantRoleChanged,
20
     participantRoleChanged,
19
     participantUpdated
21
     participantUpdated
89
 
91
 
90
     conference.on(
92
     conference.on(
91
         JitsiConferenceEvents.KICKED,
93
         JitsiConferenceEvents.KICKED,
92
-        () => dispatch(kickedOut(conference)));
94
+        (...args) => dispatch(kickedOut(conference, ...args)));
95
+
96
+    conference.on(
97
+        JitsiConferenceEvents.PARTICIPANT_KICKED,
98
+        (kicker, kicked) => dispatch(participantKicked(kicker, kicked)));
93
 
99
 
94
     conference.on(
100
     conference.on(
95
         JitsiConferenceEvents.LOCK_STATE_CHANGED,
101
         JitsiConferenceEvents.LOCK_STATE_CHANGED,
129
         JitsiConferenceEvents.TRACK_REMOVED,
135
         JitsiConferenceEvents.TRACK_REMOVED,
130
         t => t && !t.isLocal() && dispatch(trackRemoved(t)));
136
         t => t && !t.isLocal() && dispatch(trackRemoved(t)));
131
 
137
 
138
+    conference.on(
139
+        JitsiConferenceEvents.TRACK_MUTE_CHANGED,
140
+        (_, participantThatMutedUs) => {
141
+            if (participantThatMutedUs) {
142
+                dispatch(participantMutedUs(participantThatMutedUs));
143
+            }
144
+        });
145
+
132
     // Dispatches into features/base/participants follow:
146
     // Dispatches into features/base/participants follow:
133
     conference.on(
147
     conference.on(
134
         JitsiConferenceEvents.DISPLAY_NAME_CHANGED,
148
         JitsiConferenceEvents.DISPLAY_NAME_CHANGED,
432
  *
446
  *
433
  * @param {JitsiConference} conference - The {@link JitsiConference} instance
447
  * @param {JitsiConference} conference - The {@link JitsiConference} instance
434
  * for which the event is being signaled.
448
  * for which the event is being signaled.
449
+ * @param {JitsiParticipant} participant - The {@link JitsiParticipant}
450
+ * instance which initiated the kick event.
435
  * @returns {{
451
  * @returns {{
436
  *     type: KICKED_OUT,
452
  *     type: KICKED_OUT,
437
- *     conference: JitsiConference
453
+ *     conference: JitsiConference,
454
+ *     participant: JitsiParticipant
438
  * }}
455
  * }}
439
  */
456
  */
440
-export function kickedOut(conference: Object) {
457
+export function kickedOut(conference: Object, participant: Object) {
441
     return {
458
     return {
442
         type: KICKED_OUT,
459
         type: KICKED_OUT,
443
-        conference
460
+        conference,
461
+        participant
444
     };
462
     };
445
 }
463
 }
446
 
464
 

+ 50
- 1
react/features/base/participants/actions.js View File

17
     PARTICIPANT_UPDATED,
17
     PARTICIPANT_UPDATED,
18
     PIN_PARTICIPANT
18
     PIN_PARTICIPANT
19
 } from './actionTypes';
19
 } from './actionTypes';
20
-import { getLocalParticipant, getNormalizedDisplayName } from './functions';
20
+import {
21
+    getLocalParticipant,
22
+    getNormalizedDisplayName,
23
+    getParticipantDisplayName
24
+} from './functions';
21
 
25
 
22
 /**
26
 /**
23
  * Create an action for when dominant speaker changes.
27
  * Create an action for when dominant speaker changes.
382
     };
386
     };
383
 }
387
 }
384
 
388
 
389
+/**
390
+ * Action to signal that a participant has muted us.
391
+ *
392
+ * @param {JitsiParticipant} participant - Information about participant.
393
+ * @returns {Promise}
394
+ */
395
+export function participantMutedUs(participant) {
396
+    return (dispatch, getState) => {
397
+        if (!participant) {
398
+            return;
399
+        }
400
+
401
+        dispatch(showNotification({
402
+            descriptionKey: 'notify.mutedRemotelyDescription',
403
+            titleKey: 'notify.mutedRemotelyTitle',
404
+            titleArguments: {
405
+                participantDisplayName:
406
+                    getParticipantDisplayName(getState, participant.getId())
407
+            }
408
+        }));
409
+    };
410
+}
411
+
412
+/**
413
+ * Action to signal that a participant had been kicked.
414
+ *
415
+ * @param {JitsiParticipant} kicker - Information about participant performing the kick.
416
+ * @param {JitsiParticipant} kicked - Information about participant that was kicked.
417
+ * @returns {Promise}
418
+ */
419
+export function participantKicked(kicker, kicked) {
420
+    return (dispatch, getState) => {
421
+
422
+        dispatch(showNotification({
423
+            titleArguments: {
424
+                kicked:
425
+                    getParticipantDisplayName(getState, kicked.getId()),
426
+                kicker:
427
+                    getParticipantDisplayName(getState, kicker.getId())
428
+            },
429
+            titleKey: 'notify.kickParticipant'
430
+        }, NOTIFICATION_TIMEOUT * 2)); // leave more time for this
431
+    };
432
+}
433
+
385
 /**
434
 /**
386
  * Create an action which pins a conference participant.
435
  * Create an action which pins a conference participant.
387
  *
436
  *

+ 31
- 0
react/features/conference/actions.native.js View File

1
+// @flow
2
+
3
+import type { Dispatch } from 'redux';
4
+
5
+import {
6
+    AlertDialog,
7
+    openDialog
8
+} from '../base/dialog';
9
+import { getParticipantDisplayName } from '../base/participants';
10
+
11
+/**
12
+ * Notify that we've been kicked out of the conference.
13
+ *
14
+ * @param {JitsiParticipant} participant - The {@link JitsiParticipant}
15
+ * instance which initiated the kick event.
16
+ * @param {?Function} submit - The function to execute after submiting the dialog.
17
+ * @returns {Function}
18
+ */
19
+export function notifyKickedOut(participant: Object, submit: ?Function) {
20
+    return (dispatch: Dispatch<any>, getState: Function) => {
21
+        dispatch(openDialog(AlertDialog, {
22
+            contentKey: {
23
+                key: 'dialog.kickTitle',
24
+                params: {
25
+                    participantDisplayName: getParticipantDisplayName(getState, participant.getId())
26
+                }
27
+            },
28
+            onSubmit: submit
29
+        }));
30
+    };
31
+}

+ 35
- 0
react/features/conference/actions.web.js View File

1
+// @flow
2
+
3
+import type { Dispatch } from 'redux';
4
+
5
+import {
6
+    NOTIFICATION_TYPE,
7
+    showNotification
8
+} from '../notifications';
9
+import { getParticipantDisplayName } from '../base/participants';
10
+
11
+/**
12
+ * Notify that we've been kicked out of the conference.
13
+ *
14
+ * @param {JitsiParticipant} participant - The {@link JitsiParticipant}
15
+ * instance which initiated the kick event.
16
+ * @param {?Function} _ - Used only in native code.
17
+ * @returns {Function}
18
+ */
19
+export function notifyKickedOut(participant: Object, _: ?Function) { // eslint-disable-line no-unused-vars
20
+    return (dispatch: Dispatch<any>, getState: Function) => {
21
+        const args = {
22
+            participantDisplayName:
23
+                getParticipantDisplayName(getState, participant.getDisplayName())
24
+        };
25
+
26
+        dispatch(showNotification({
27
+            appearance: NOTIFICATION_TYPE.ERROR,
28
+            hideErrorSupportLink: true,
29
+            descriptionKey: 'dialog.kickMessage',
30
+            descriptionArguments: args,
31
+            titleKey: 'dialog.kickTitle',
32
+            titleArguments: args
33
+        }));
34
+    };
35
+}

+ 1
- 1
react/features/conference/index.js View File

1
 // @flow
1
 // @flow
2
-
2
+export * from './actions';
3
 export * from './components';
3
 export * from './components';
4
 
4
 
5
 import './middleware';
5
 import './middleware';

+ 10
- 4
react/features/conference/middleware.js View File

1
 // @flow
1
 // @flow
2
-
2
+import { notifyKickedOut } from './actions';
3
 import { appNavigate } from '../app';
3
 import { appNavigate } from '../app';
4
 import {
4
 import {
5
     CONFERENCE_JOINED,
5
     CONFERENCE_JOINED,
43
     case KICKED_OUT: {
43
     case KICKED_OUT: {
44
         const { dispatch } = store;
44
         const { dispatch } = store;
45
 
45
 
46
-        dispatch(
47
-            conferenceFailed(action.conference, JitsiConferenceEvents.KICKED));
48
-        dispatch(appNavigate(undefined));
46
+        dispatch(notifyKickedOut(
47
+            action.participant,
48
+            () => {
49
+                dispatch(
50
+                    conferenceFailed(action.conference, JitsiConferenceEvents.KICKED));
51
+                dispatch(appNavigate(undefined));
52
+            }
53
+        ));
54
+
49
         break;
55
         break;
50
     }
56
     }
51
     }
57
     }

Loading…
Cancel
Save