diff --git a/conference.js b/conference.js index 57ecec6de..3ec751eb7 100644 --- a/conference.js +++ b/conference.js @@ -91,7 +91,10 @@ import { import { statsEmitter } from './react/features/connection-indicator'; import { showDesktopPicker } from './react/features/desktop-picker'; import { appendSuffix } from './react/features/display-name'; -import { maybeOpenFeedbackDialog } from './react/features/feedback'; +import { + maybeOpenFeedbackDialog, + submitFeedback +} from './react/features/feedback'; import { mediaPermissionPromptVisibilityChanged, suspendDetected @@ -2798,5 +2801,21 @@ export default { setAudioMuteStatus(muted) { APP.UI.setAudioMuted(this.getMyUserId(), muted); APP.API.notifyAudioMutedStatusChanged(muted); + }, + + /** + * Dispatches the passed in feedback for submission. The submitted score + * should be a number inclusively between 1 through 5, or -1 for no score. + * + * @param {number} score - a number between 1 and 5 (inclusive) or -1 for no + * score. + * @param {string} message - An optional message to attach to the feedback + * in addition to the score. + * @returns {void} + */ + submitFeedback(score = -1, message = '') { + if (score === -1 || (score >= 1 && score <= 5)) { + APP.store.dispatch(submitFeedback(score, message, room)); + } } }; diff --git a/modules/API/API.js b/modules/API/API.js index 07943baa5..a1dcae336 100644 --- a/modules/API/API.js +++ b/modules/API/API.js @@ -59,6 +59,10 @@ function initCommands() { sendAnalytics(createApiEvent('display.name.changed')); APP.conference.changeLocalDisplayName(displayName); }, + 'submit-feedback': feedback => { + sendAnalytics(createApiEvent('submit.feedback')); + APP.conference.submitFeedback(feedback.score, feedback.message); + }, 'toggle-audio': () => { sendAnalytics(createApiEvent('toggle-audio')); logger.log('Audio toggle: API command received'); @@ -456,6 +460,16 @@ class API { }); } + /** + * Notify external application (if API is enabled) that conference feedback + * has been submitted. Intended to be used in conjunction with the + * submit-feedback command to get notified if feedback was submitted. + * + * @returns {void} + */ + notifyFeedbackSubmitted() { + this._sendEvent({ name: 'feedback-submitted' }); + } /** * Disposes the allocated resources. diff --git a/modules/API/external/external_api.js b/modules/API/external/external_api.js index 1a3a4a53a..9408effb2 100644 --- a/modules/API/external/external_api.js +++ b/modules/API/external/external_api.js @@ -21,6 +21,7 @@ const commands = { displayName: 'display-name', email: 'email', hangup: 'video-hangup', + submitFeedback: 'submit-feedback', toggleAudio: 'toggle-audio', toggleChat: 'toggle-chat', toggleContactList: 'toggle-contact-list', @@ -38,6 +39,7 @@ const events = { 'audio-availability-changed': 'audioAvailabilityChanged', 'audio-mute-status-changed': 'audioMuteStatusChanged', 'display-name-change': 'displayNameChange', + 'feedback-submitted': 'feedbackSubmitted', 'incoming-message': 'incomingMessage', 'outgoing-message': 'outgoingMessage', 'participant-joined': 'participantJoined', diff --git a/react/features/feedback/index.js b/react/features/feedback/index.js index b2e9c09f6..a29aa08e0 100644 --- a/react/features/feedback/index.js +++ b/react/features/feedback/index.js @@ -2,4 +2,5 @@ export * from './actions'; export * from './actionTypes'; export * from './components'; +import './middleware'; import './reducer'; diff --git a/react/features/feedback/middleware.js b/react/features/feedback/middleware.js new file mode 100644 index 000000000..26b3baa8f --- /dev/null +++ b/react/features/feedback/middleware.js @@ -0,0 +1,26 @@ +/* @flow */ + +import { MiddlewareRegistry } from '../base/redux'; + +import { SUBMIT_FEEDBACK } from './actionTypes'; + +declare var APP: Object; + +/** + * Implements the middleware of the feature feedback. + * + * @param {Store} store - The redux store. + * @returns {Function} + */ +// eslint-disable-next-line no-unused-vars +MiddlewareRegistry.register(store => next => action => { + switch (action.type) { + case SUBMIT_FEEDBACK: + if (typeof APP === 'object') { + APP.API.notifyFeedbackSubmitted(); + } + break; + } + + return next(action); +});