Browse Source

independently display subtitles based on participants choice

master
Nik 7 years ago
parent
commit
3c27d2ee54

+ 12
- 0
react/features/subtitles/actionTypes.js View File

33
  * }
33
  * }
34
  */
34
  */
35
 export const UPDATE_TRANSCRIPT_MESSAGE = Symbol('UPDATE_TRANSCRIPT_MESSAGE');
35
 export const UPDATE_TRANSCRIPT_MESSAGE = Symbol('UPDATE_TRANSCRIPT_MESSAGE');
36
+
37
+/**
38
+ * The type of (redux) action which indicates that the user pressed the
39
+ * ClosedCaption button, to either enable or disable subtitles based on the
40
+ * current state.
41
+ *
42
+ * {
43
+ *      type: TOGGLE_REQUESTING_SUBTITLES
44
+ * }
45
+ */
46
+export const TOGGLE_REQUESTING_SUBTITLES
47
+    = Symbol('TOGGLE_REQUESTING_SUBTITLES');

+ 14
- 0
react/features/subtitles/actions.js View File

3
 import {
3
 import {
4
     ENDPOINT_MESSAGE_RECEIVED,
4
     ENDPOINT_MESSAGE_RECEIVED,
5
     REMOVE_TRANSCRIPT_MESSAGE,
5
     REMOVE_TRANSCRIPT_MESSAGE,
6
+    TOGGLE_REQUESTING_SUBTITLES,
6
     UPDATE_TRANSCRIPT_MESSAGE
7
     UPDATE_TRANSCRIPT_MESSAGE
7
 } from './actionTypes';
8
 } from './actionTypes';
8
 
9
 
61
         newTranscriptMessage
62
         newTranscriptMessage
62
     };
63
     };
63
 }
64
 }
65
+
66
+/**
67
+ * Signals that the local user has toggled the ClosedCaption button.
68
+ *
69
+ * @returns {{
70
+ *      type: TOGGLE_REQUESTING_SUBTITLES
71
+ * }}
72
+ */
73
+export function toggleRequestingSubtitles() {
74
+    return {
75
+        type: TOGGLE_REQUESTING_SUBTITLES
76
+    };
77
+}

react/features/transcribing/components/ClosedCaptionButton.native.js → react/features/subtitles/components/ClosedCaptionButton.native.js View File


react/features/transcribing/components/ClosedCaptionButton.web.js → react/features/subtitles/components/ClosedCaptionButton.web.js View File

6
 
6
 
7
 import { ToolbarButton } from '../../toolbox/';
7
 import { ToolbarButton } from '../../toolbox/';
8
 
8
 
9
-import { dialTranscriber, stopTranscribing } from '../actions';
9
+import { toggleRequestingSubtitles } from '../actions';
10
 import { createToolbarEvent, sendAnalytics } from '../../analytics';
10
 import { createToolbarEvent, sendAnalytics } from '../../analytics';
11
 
11
 
12
 
12
 
26
     dispatch: Function,
26
     dispatch: Function,
27
 
27
 
28
     /**
28
     /**
29
-     * Boolean value indicating current transcribing status
29
+     * Whether the local participant is currently requesting subtitles.
30
      */
30
      */
31
-    _transcribing: boolean,
32
-
33
-    /**
34
-     * Boolean value indicating current dialing status
35
-     */
36
-    _dialing: boolean
31
+    _requestingSubtitles: Boolean
37
 };
32
 };
38
 
33
 
39
 /**
34
 /**
64
      * @returns {ReactElement}
59
      * @returns {ReactElement}
65
      */
60
      */
66
     render() {
61
     render() {
67
-        const { _dialing, _transcribing, t } = this.props;
68
-        const iconClass = `icon-closed_caption ${_dialing || _transcribing
62
+        const { _requestingSubtitles, t } = this.props;
63
+        const iconClass = `icon-closed_caption ${_requestingSubtitles
69
             ? 'toggled' : ''}`;
64
             ? 'toggled' : ''}`;
70
 
65
 
71
         return (
66
         return (
88
      * @returns {void}
83
      * @returns {void}
89
      */
84
      */
90
     _onToggleButton() {
85
     _onToggleButton() {
91
-        const { _transcribing, _dialing, dispatch } = this.props;
86
+        const { _requestingSubtitles, dispatch } = this.props;
92
 
87
 
93
-        sendAnalytics(createToolbarEvent(
94
-            'transcribing.ccButton',
88
+        sendAnalytics(createToolbarEvent('transcribing.ccButton',
95
             {
89
             {
96
-                'is_transcribing': Boolean(_transcribing),
97
-                'is_dialing': Boolean(_dialing)
90
+                'requesting_subtitles': Boolean(_requestingSubtitles)
98
             }));
91
             }));
99
 
92
 
100
-        if (_dialing) {
101
-            return;
102
-        }
103
-
104
-        if (_transcribing) {
105
-            dispatch(stopTranscribing());
106
-        } else {
107
-            dispatch(dialTranscriber());
108
-        }
93
+        dispatch(toggleRequestingSubtitles());
109
     }
94
     }
110
 
95
 
111
 }
96
 }
120
  * }}
105
  * }}
121
  */
106
  */
122
 function _mapStateToProps(state) {
107
 function _mapStateToProps(state) {
123
-    const { isTranscribing, isDialing } = state['features/transcribing'];
108
+    const { _requestingSubtitles } = state['features/subtitles'];
124
 
109
 
125
     return {
110
     return {
126
-        _transcribing: isTranscribing,
127
-        _dialing: isDialing
111
+        _requestingSubtitles
128
     };
112
     };
129
 }
113
 }
130
 
114
 

+ 18
- 2
react/features/subtitles/components/TranscriptionSubtitles.web.js View File

12
     /**
12
     /**
13
      * Map of transcriptMessageID's with corresponding transcriptMessage.
13
      * Map of transcriptMessageID's with corresponding transcriptMessage.
14
      */
14
      */
15
-    _transcriptMessages: Map<string, Object>
15
+    _transcriptMessages: Map<string, Object>,
16
+
17
+    /**
18
+     * Whether local participant is requesting to see subtitles
19
+     */
20
+    _requestingSubtitles: Boolean
16
 };
21
 };
17
 
22
 
18
 /**
23
 /**
28
      * @returns {ReactElement}
33
      * @returns {ReactElement}
29
      */
34
      */
30
     render() {
35
     render() {
36
+        if (!this.props._requestingSubtitles
37
+             || !this.props._transcriptMessages) {
38
+            return null;
39
+        }
40
+
31
         const paragraphs = [];
41
         const paragraphs = [];
32
 
42
 
33
         for (const [ transcriptMessageID, transcriptMessage ]
43
         for (const [ transcriptMessageID, transcriptMessage ]
73
  * }}
83
  * }}
74
  */
84
  */
75
 function _mapStateToProps(state) {
85
 function _mapStateToProps(state) {
86
+    const {
87
+        _transcriptMessages,
88
+        _requestingSubtitles
89
+    } = state['features/subtitles'];
90
+
76
     return {
91
     return {
77
-        _transcriptMessages: state['features/subtitles'].transcriptMessages
92
+        _transcriptMessages,
93
+        _requestingSubtitles
78
     };
94
     };
79
 }
95
 }
80
 export default connect(_mapStateToProps)(TranscriptionSubtitles);
96
 export default connect(_mapStateToProps)(TranscriptionSubtitles);

+ 1
- 0
react/features/subtitles/components/index.js View File

1
 export { default as TranscriptionSubtitles } from './TranscriptionSubtitles';
1
 export { default as TranscriptionSubtitles } from './TranscriptionSubtitles';
2
+export { default as ClosedCaptionButton } from './ClosedCaptionButton';

+ 32
- 3
react/features/subtitles/middleware.js View File

2
 
2
 
3
 import { MiddlewareRegistry } from '../base/redux';
3
 import { MiddlewareRegistry } from '../base/redux';
4
 
4
 
5
-import { ENDPOINT_MESSAGE_RECEIVED } from './actionTypes';
5
+import {
6
+    ENDPOINT_MESSAGE_RECEIVED,
7
+    TOGGLE_REQUESTING_SUBTITLES
8
+} from './actionTypes';
6
 import {
9
 import {
7
     removeTranscriptMessage,
10
     removeTranscriptMessage,
8
     updateTranscriptMessage
11
     updateTranscriptMessage
28
  */
31
  */
29
 const P_NAME_TRANSLATION_LANGUAGE = 'translation_language';
32
 const P_NAME_TRANSLATION_LANGUAGE = 'translation_language';
30
 
33
 
34
+/**
35
+ * The local participant property which is used to set whether the local
36
+ * participant wants to have a transcriber in the room.
37
+ */
38
+const P_NAME_REQUESTING_TRANSCRIPTION = 'requestingTranscription';
39
+
31
 /**
40
 /**
32
 * Time after which the rendered subtitles will be removed.
41
 * Time after which the rendered subtitles will be removed.
33
 */
42
 */
41
  * @returns {Function}
50
  * @returns {Function}
42
  */
51
  */
43
 MiddlewareRegistry.register(store => next => action => {
52
 MiddlewareRegistry.register(store => next => action => {
44
-
45
     switch (action.type) {
53
     switch (action.type) {
46
     case ENDPOINT_MESSAGE_RECEIVED:
54
     case ENDPOINT_MESSAGE_RECEIVED:
47
         return _endpointMessageReceived(store, next, action);
55
         return _endpointMessageReceived(store, next, action);
56
+    case TOGGLE_REQUESTING_SUBTITLES:
57
+        _requestingSubtitlesToggled(store);
58
+        break;
48
     }
59
     }
49
 
60
 
50
     return next(action);
61
     return next(action);
51
 });
62
 });
52
 
63
 
64
+/**
65
+ * Toggle the local property 'requestingTranscription'. This will cause Jicofo
66
+ * and Jigasi to decide whether the transcriber needs to be in the room.
67
+ *
68
+ * @param {Store} store - The redux store.
69
+ * @private
70
+ * @returns {void}
71
+ */
72
+function _requestingSubtitlesToggled({ getState }) {
73
+    const { _requestingSubtitles } = getState()['features/subtitles'];
74
+    const { conference } = getState()['features/base/conference'];
75
+
76
+    conference.setLocalParticipantProperty(P_NAME_REQUESTING_TRANSCRIPTION,
77
+        !_requestingSubtitles);
78
+}
79
+
53
 /**
80
 /**
54
  * Notifies the feature transcription that the action
81
  * Notifies the feature transcription that the action
55
  * {@code ENDPOINT_MESSAGE_RECEIVED} is being dispatched within a specific redux
82
  * {@code ENDPOINT_MESSAGE_RECEIVED} is being dispatched within a specific redux
109
             // message ID or adds a new transcript message if it does not
136
             // message ID or adds a new transcript message if it does not
110
             // exist in the map.
137
             // exist in the map.
111
             const newTranscriptMessage
138
             const newTranscriptMessage
112
-                = { ...getState()['features/subtitles'].transcriptMessages
139
+                = { ...getState()['features/subtitles']._transcriptMessages
113
                     .get(transcriptMessageID) || { participantName } };
140
                     .get(transcriptMessageID) || { participantName } };
114
 
141
 
115
             setClearerOnTranscriptMessage(dispatch,
142
             setClearerOnTranscriptMessage(dispatch,
120
             if (!isInterim) {
147
             if (!isInterim) {
121
 
148
 
122
                 newTranscriptMessage.final = text;
149
                 newTranscriptMessage.final = text;
150
+
123
                 dispatch(updateTranscriptMessage(transcriptMessageID,
151
                 dispatch(updateTranscriptMessage(transcriptMessageID,
124
                     newTranscriptMessage));
152
                     newTranscriptMessage));
125
             } else if (stability > 0.85) {
153
             } else if (stability > 0.85) {
130
 
158
 
131
                 newTranscriptMessage.stable = text;
159
                 newTranscriptMessage.stable = text;
132
                 newTranscriptMessage.unstable = undefined;
160
                 newTranscriptMessage.unstable = undefined;
161
+
133
                 dispatch(updateTranscriptMessage(transcriptMessageID,
162
                 dispatch(updateTranscriptMessage(transcriptMessageID,
134
                     newTranscriptMessage));
163
                     newTranscriptMessage));
135
             } else {
164
             } else {

+ 11
- 5
react/features/subtitles/reducer.js View File

1
 import { ReducerRegistry } from '../base/redux';
1
 import { ReducerRegistry } from '../base/redux';
2
 
2
 
3
 import {
3
 import {
4
-    REMOVE_TRANSCRIPT_MESSAGE,
4
+    REMOVE_TRANSCRIPT_MESSAGE, TOGGLE_REQUESTING_SUBTITLES,
5
     UPDATE_TRANSCRIPT_MESSAGE
5
     UPDATE_TRANSCRIPT_MESSAGE
6
 } from './actionTypes';
6
 } from './actionTypes';
7
 
7
 
9
  * Default State for 'features/transcription' feature
9
  * Default State for 'features/transcription' feature
10
  */
10
  */
11
 const defaultState = {
11
 const defaultState = {
12
-    transcriptMessages: new Map()
12
+    _transcriptMessages: new Map(),
13
+    _requestingSubtitles: false
13
 };
14
 };
14
 
15
 
15
 /**
16
 /**
21
     switch (action.type) {
22
     switch (action.type) {
22
     case REMOVE_TRANSCRIPT_MESSAGE:
23
     case REMOVE_TRANSCRIPT_MESSAGE:
23
         return _removeTranscriptMessage(state, action);
24
         return _removeTranscriptMessage(state, action);
24
-
25
     case UPDATE_TRANSCRIPT_MESSAGE:
25
     case UPDATE_TRANSCRIPT_MESSAGE:
26
         return _updateTranscriptMessage(state, action);
26
         return _updateTranscriptMessage(state, action);
27
+
28
+    case TOGGLE_REQUESTING_SUBTITLES:
29
+        return {
30
+            ...state,
31
+            _requestingSubtitles: !state._requestingSubtitles
32
+        };
27
     }
33
     }
28
 
34
 
29
     return state;
35
     return state;
46
 
52
 
47
     return {
53
     return {
48
         ...state,
54
         ...state,
49
-        transcriptMessages: newTranscriptMessages
55
+        _transcriptMessages: newTranscriptMessages
50
     };
56
     };
51
 }
57
 }
52
 
58
 
68
 
74
 
69
     return {
75
     return {
70
         ...state,
76
         ...state,
71
-        transcriptMessages: newTranscriptMessages
77
+        _transcriptMessages: newTranscriptMessages
72
     };
78
     };
73
 }
79
 }

+ 3
- 7
react/features/toolbox/components/web/Toolbox.js View File

14
 import {
14
 import {
15
     getLocalParticipant,
15
     getLocalParticipant,
16
     getParticipants,
16
     getParticipants,
17
-    participantUpdated,
18
-    isLocalParticipantModerator
17
+    participantUpdated
19
 } from '../../../base/participants';
18
 } from '../../../base/participants';
20
 import { getLocalVideoTrack, toggleScreensharing } from '../../../base/tracks';
19
 import { getLocalVideoTrack, toggleScreensharing } from '../../../base/tracks';
21
 import { ChatCounter } from '../../../chat';
20
 import { ChatCounter } from '../../../chat';
64
 import VideoMuteButton from '../VideoMuteButton';
63
 import VideoMuteButton from '../VideoMuteButton';
65
 import {
64
 import {
66
     ClosedCaptionButton
65
     ClosedCaptionButton
67
-} from '../../../transcribing';
66
+} from '../../../subtitles';
68
 
67
 
69
 /**
68
 /**
70
  * The type of the React {@code Component} props of {@link Toolbox}.
69
  * The type of the React {@code Component} props of {@link Toolbox}.
1040
         callStatsID,
1039
         callStatsID,
1041
         iAmRecorder
1040
         iAmRecorder
1042
     } = state['features/base/config'];
1041
     } = state['features/base/config'];
1043
-    let {
1042
+    const {
1044
         transcribingEnabled
1043
         transcribingEnabled
1045
     } = state['features/base/config'];
1044
     } = state['features/base/config'];
1046
     const sharedVideoStatus = state['features/shared-video'].status;
1045
     const sharedVideoStatus = state['features/shared-video'].status;
1060
 
1059
 
1061
     let desktopSharingDisabledTooltipKey;
1060
     let desktopSharingDisabledTooltipKey;
1062
 
1061
 
1063
-    transcribingEnabled
1064
-        = isLocalParticipantModerator(state) && transcribingEnabled;
1065
-
1066
     if (state['features/base/config'].enableFeaturesBasedOnToken) {
1062
     if (state['features/base/config'].enableFeaturesBasedOnToken) {
1067
         // we enable desktop sharing if any participant already have this
1063
         // we enable desktop sharing if any participant already have this
1068
         // feature enabled
1064
         // feature enabled

+ 0
- 1
react/features/transcribing/components/index.js View File

1
 export { default as TranscribingLabel } from './TranscribingLabel';
1
 export { default as TranscribingLabel } from './TranscribingLabel';
2
-export { default as ClosedCaptionButton } from './ClosedCaptionButton';

Loading…
Cancel
Save