jiti-meet/react/features/chat/middleware.ts

561 lines
18 KiB
TypeScript
Raw Normal View History

/* eslint-disable lines-around-comment */
import { AnyAction } from 'redux';
import { IReduxState, IStore } from '../app/types';
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app/actionTypes';
import { CONFERENCE_JOINED } from '../base/conference/actionTypes';
import { getCurrentConference } from '../base/conference/functions';
import { IJitsiConference } from '../base/conference/reducer';
import { openDialog } from '../base/dialog/actions';
2019-10-09 08:34:01 +00:00
import {
JitsiConferenceErrors,
JitsiConferenceEvents
} from '../base/lib-jitsi-meet';
import {
2019-10-07 12:35:04 +00:00
getLocalParticipant,
getParticipantById,
getParticipantDisplayName
} from '../base/participants/functions';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import { playSound, registerSound, unregisterSound } from '../base/sounds/actions';
import { addGif } from '../gifs/actions';
import { GIF_PREFIX } from '../gifs/constants';
import { getGifDisplayMode, isGifMessage } from '../gifs/functions';
import { showMessageNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
feat(polls) Ability to create polls inside Jitsi (#9166) * feat(polls) Added boilerplate code for polls feature * feat(polls) Implemented simple poll creation and answer modals in web app feat(polls) Added button to create a poll in toolbar feat(polls) Added Modal to answer an incoming poll feat(polls) Implemented basic client-side sending and reception of polls feat(polls): linked Poll creation to poll answering fix(polls) Linted code feat(polls.create) Added fields for question and answers (#3) * feat(polls.create) Added fields for question and answers + keyboard navigation * feat(polls.create) Minor changes, added some comments feat(PollAnswer Component): Component to display modal to answer poll #1 (#2) * fix(polls) removing necessity of current_poll_id variable * fix(polls) linting, polls are now updated when an answer is sent * feat(polls answer) added translation * fix(polls answer) remove extra comments, fixed typo * improvement (polls answer) use useSelector instead of mapStateToProps. cleaner code * fix (polls create) renamed sender to senderId * fix (polls answer) turned arrow function into useCallBack feat(PollResults Component): Component to display poll results (#1) * feat(PollResults Component): fist version of the component * feat(detailed votes): Display the detailed results of a poll * feat(Poll results): Use display name instead of ids in detailed results mode * fix(Poll): change title to question * fix(Poll type): import Poll type from types.js * fix(Poll): change title to question * fix(Poll): get participants out of the map * fix(Poll): replace filter with find feat(polls.create) Added "+" and "x" buttons in poll creation form + improved keyboard navigation a bit feat (polls) Answer modal now display results in real time after validation or skip feat(polls.create) Minor improvements to poll creation form feat(poll result) Added default message when trying to display no answer fix (polls) result windows is now small by default fix (polls) sanitizes imports to allow startup on react native * feat(polls.native) Implemented native toolbar button & poll create modal feat( poll native) added poll creation button in native toolbar improvement(polls) only one file used for PollCreateButton feat (polls native) added an example dialog feat (polls native) added possibility to create and delete options in poll creation improvement (polls) better styling for PollCreateDialog * feat(polls) Added ability to drag&drop answers in web poll creation form * feat(polls) Added native poll answer modal + chat integration, refactored components Merge branch 'polls-native' of https://github.com/jade-guiton/jitsi-meet into polls-native improvement (poll) Better styling for poll answer, now uses icons feat(poll.PollResults): Add native version of PollResults feat(poll.PollResults): Post results in chat in Native fix(poll.PollResults): Fix linter error in ChatMessage feat(polls.native) Improved styling for native poll answer dialog (required some internal changes) * fix(polls) Heavily refactored and added bars to poll results, other minor changes fix(poll.create): Move title to Dialog title feat(poll.create) Minor changes to poll creation / answer dialogs fix(poll.create) Refactored and improved translations feat(poll) Improved CSS for modals in web version fix(poll.pollcreate): Fix button size in native fix(polls) Refactored poll results component and other minor changes fix (polls) remove double import refactor(poll) Heavily refactored poll results (native + web) feat(polls.results) Added percentage bars and vote counts in web poll results, minor changes to mobile poll results * fix(polls) Fixes and linting fix(polls) Reformatted and fixed some linter and Flow errors fix(polls.results) Fixed voter list border appearing with 0 voters * feat(polls): Add modal with detailed votes that can be open from the result summary in the chat * fix(polls) Fixes, refactorings, and minor design changes feat(polls.results): Refactored poll chat message and improved design in web app feat(polls.results) Same as last commit, but for mobile version refactor(polls.results) Refactored PollResultsMessage and removed unnecessary prop in PollResults fix(polls.results) Fixed all remaining linter and Flow errors improvement(polls) removed console logs, added comments fix (polls) linting fix(polls.results) Fixed bug with poll chat message displaying the wrong name feat(polls.results) Minor improvement on poll results display (web) fix(poll.results): Use getParticipantDisplayName to get participant name and avoid empty string as name * Feat(poll.results): Remember voters names to display after they left the conference (#10) * feat(poll.results): Add the sender name in Poll object to remember names if participants leave the conference. Names are also updated if changed * refactor(poll.results): Refactor the memorization of the names of voters to use the same logic as in the chat * refactor(poll.results): use Map instead of Array.From( * refactor(poll.answer): change the way names are stored in poll answers to persist if participant left the call * Update react/features/polls/components/AbstractPollAnswerDialog.js * Update react/features/polls/components/AbstractPollCreateDialog.js * refactor(poll.answer): use voterName instead of senderName to avoid confusion with senderId the id of the sender of the poll * improvement(polls) Simplified poll answer voter name logic Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Jade Guiton <guiton.jade@gmail.com> * fix(poll.native): Fix UI overflow when asking long questions & long options in the mobile app (#11) Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> * fix(polls) Fixed close button behavior in answer and results dialog (#12) * fix(polls) Fixed close button behavior in answer and results dialog * fix(polls) Fixed linter error * fix(polls) Added a poll queue to avoid overwriting open modals (#13) * fix(polls) Added a poll queue to avoid overwriting open modals * fix(polls) Updated documentation for action RECEIVE_POLL * Refactor(poll.chatresults): Add message in chat with hidden results until the participant has answered (#14) * refactor(poll.chat): Display poll results in chat when the poll is created instead of when the participant has ansered * refactor(poll.chat): Hide results until the participant has answered, skipped or canceled a responde to the poll * Use getParticipantDisplayName instead of only getStore() * Hide results also in native * fix(polls) Fixed previous merge Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Jade Guiton <jade.guiton@centralesupelec.fr> * minor improvements (polls) refactor (polls) uniformized string for command names refactor (polls) changed pollId type to number everywhere * feat(polls) Added persistence to polls using sendMessage instead of sendCommandOnce (#16) * feat(polls) Using sendMessage instead of sendCommandOnce, switched poll IDs to string, and ability to receive old polls from backend * improvement(polls) Linted everything, fixed Flow errors, and added Prosody plugin for polls * improvement(polls) Historic polls are now displayed in chronological order * (polls) Minor improvements (#17) * renaming (polls) Renaming senderId -> voterID for voters * improvement (polls) sender's name is now provided with poll * comments (polls) updated comments for senderName types * fix(polls) Finished merging with json-messages feature * fix(polls) Fixed incorrect json-message sent with 0 polls Co-authored-by: Jade Guiton <guiton.jade@gmail.com> * Move polls to tab (#23) * Draft(polls): Move polls to polls-pane ; first version for web * Draft(polls): Move polls to polls-pane ; clean styled.js and remove Participant objects * fix missing newline at the end of file * Change behaviour to allow answer poll later * Fix(polls): change pollId type from number to string for consistency * feat(polls-pane): Ability to answer to a poll in polls-pane * feat(polls-pane): Ability to create to a poll in polls-pane * feat (polls.pane) display a notification when a new poll arrives * refactor(polls-pane): Update CSS to have a design closer to the mockups * fix(poll.vote count): Fix votes counting when computing percentage * fix(poll.vote count): Fix votes counting when computing percentage * refresh fork with jitsi/jitsi-meet * design (polls) Better look for poll creation * refactor(polls pane): Move polls-pane as a chat tab * Remove the first version of the polls-pane and the button to open it * Fix notifications and typo * Translate new polls tab in chat * Change polls_pane to polls-pane * Remove unless functions * Remove usage of styled.js * Improve responsiveness * Separate web and native logic * Remove Create a Poll button in web toolbox * improvement (polls) added auto scrolling to bottom when a new poll arrives * Add tabs to swicth between polls and chat in native * Add AbstractPollsPane * Add AbstractPollCreate * Add AbstractPollAnswer * Add PollAnswer, PollItem and PollList for native * Add PollCreate for native * Remove dialogs in web and native * Remove dialog queue * Remove useless files * Move _polls.scss outside dialog folder * Add possibility to skip answer * Add (useless for now) see details link * Add possibility to show detailed results for a poll * Resize progress bar to make details display * refactor, design (polls) better style to native design chat * fix (polls) Removed unecessary files * translate (polls) added french translation to empty polls * design fix (polls.native) 'show details' now correctly switch between progress bar and voters mode * Change See detailed results for Show details and add cursor: pointer * Fix progress bars not aligned with text * fix (polls.native) added autoselection of newly created option * Remove poll answer * improvement(polls.create) Improved web poll creation form marginally * improvement(polls.change) Simplified answer removal by reusing poll-answer command * fix linter * Fix(translation): update translation Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: spineki <marras.antoine@gmail.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@viarezo.fr> * Merge pull request #22 from jade-guiton/polls-with-notification feat (polls) chat notification badge now display the sum of unread messages and unread polls fix(translation): Fix missing translation Fix flow error * Cleaned up, fixed, and uniformized translations * Small improvements to PollAnswer and PollResult + Much refactoring Specifically: - "Change vote" button now says "Vote" if voting was skipped - Clicking on "Change vote" resets the voting form to the last submitted answers instead of a blank slate - The "answered" field of Polls was replaced by "showResults" and "lastVote" - The "setAnsweredStatus" action was replaced by "registerVote" and "retractVote" - Some newly unreachable/useless code was removed - "showDetails" state is now handled by AbstractPollResults instead of PollItem * fix(polls tab): change tab underline color to #525252 * fix(poll create): Enforce at least two options to create a poll * fix(poll create): change 'remove option' color to #E04757 * fix(poll create): Update Poll create CSS to adapt to design * fix(poll answer): Adapt CSS to make poll answer closer to mockup * fix(poll result): Udpdate poll result CSS to match mockups * fix(poll result): Udpdate poll result CSS to match mockups * fix(poll create): Display 'remove option' only when there is at least 3 options * fix(polls button): Add hover, active, focus and disabled state to polls buttons * Last improvements for web * Native design fixes * Fix rebase issue in land/main.json * Fix french translation after rebase * Fixmobile behaviour * Fixed keyboard navigation in web poll creation form * Fixed Flow error related to "no polls" icon in PollsList * fix(polls): Enabled polls Prosody module in Debian config files * doc(polls) Added comments to the Prosody module code * fix(polls): Switched from using an internal LJM event to ones from the public API * Capitalize I of setIsPollsTabFocused * extract the 2 button modes into a const * remove extra new lines * Rename CLOSE_POLL_TAB for POLL_TAB_CLOSED for clarity * Rename answers2 for answersParsed for clarity * use switch instead of if/else chain * improve syntax for localId fetching * Refactor: Use BUTTON_MODE.CONTAINED variable instead of 'contained' * Disable send poll button if not enough data is provided in the form (#30) * Feat: Add notification badge on chat and poll tabs (#31) * Feat: Add notification badge on chat and poll tabs * Add badge equivalent for native * Update displayNameForm text to mention polls (#34) * Disable polls UI with a config in config.js (#33) * Change remove option text color from red to grey (#32) Co-authored-by: spineki <marras.antoine@gmail.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Fabien Zucchet <80532941+fabienzucchet@users.noreply.github.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@viarezo.fr>
2021-08-14 13:29:42 +00:00
import { resetNbUnreadPollsMessages } from '../polls/actions';
import { ADD_REACTION_MESSAGE } from '../reactions/actionTypes';
import { pushReactions } from '../reactions/actions.any';
import { ENDPOINT_REACTION_NAME } from '../reactions/constants';
import { getReactionMessageFromBuffer, isReactionsEnabled } from '../reactions/functions.any';
import { endpointMessageReceived } from '../subtitles/actions.any';
// @ts-ignore
import { showToolbox } from '../toolbox/actions';
import { ADD_MESSAGE, CLOSE_CHAT, OPEN_CHAT, SEND_MESSAGE, SET_IS_POLL_TAB_FOCUSED } from './actionTypes';
import { addMessage, clearMessages, closeChat } from './actions.any';
// @ts-ignore
2019-10-07 12:35:04 +00:00
import { ChatPrivacyDialog } from './components';
2020-04-22 09:33:49 +00:00
import {
INCOMING_MSG_SOUND_ID,
LOBBY_CHAT_MESSAGE,
2020-04-22 09:33:49 +00:00
MESSAGE_TYPE_ERROR,
MESSAGE_TYPE_LOCAL,
MESSAGE_TYPE_REMOTE
} from './constants';
import { getUnreadCount } from './functions';
import { INCOMING_MSG_SOUND_FILE } from './sounds';
2019-10-07 12:35:04 +00:00
/**
* Timeout for when to show the privacy notice after a private message was received.
*
2021-11-04 21:10:43 +00:00
* E.g. If this value is 20 secs (20000ms), then we show the privacy notice when sending a non private
2019-10-07 12:35:04 +00:00
* message after we have received a private message in the last 20 seconds.
*/
const PRIVACY_NOTICE_TIMEOUT = 20 * 1000;
/**
* Implements the middleware of the chat feature.
*
* @param {Store} store - The redux store.
* @returns {Function}
*/
MiddlewareRegistry.register(store => next => action => {
const { dispatch, getState } = store;
const localParticipant = getLocalParticipant(getState());
let isOpen, unreadCount;
2019-10-07 12:35:04 +00:00
switch (action.type) {
case ADD_MESSAGE:
unreadCount = getUnreadCount(getState());
if (action.isReaction) {
action.hasRead = false;
} else {
unreadCount = action.hasRead ? 0 : unreadCount + 1;
}
isOpen = getState()['features/chat'].isOpen;
if (typeof APP !== 'undefined') {
APP.API.notifyChatUpdated(unreadCount, isOpen);
}
break;
case APP_WILL_MOUNT:
2019-10-07 12:35:04 +00:00
dispatch(
registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE));
break;
case APP_WILL_UNMOUNT:
2019-10-07 12:35:04 +00:00
dispatch(unregisterSound(INCOMING_MSG_SOUND_ID));
break;
case CONFERENCE_JOINED:
_addChatMsgListener(action.conference, store);
break;
case OPEN_CHAT:
unreadCount = 0;
if (typeof APP !== 'undefined') {
APP.API.notifyChatUpdated(unreadCount, true);
}
break;
feat(polls) Ability to create polls inside Jitsi (#9166) * feat(polls) Added boilerplate code for polls feature * feat(polls) Implemented simple poll creation and answer modals in web app feat(polls) Added button to create a poll in toolbar feat(polls) Added Modal to answer an incoming poll feat(polls) Implemented basic client-side sending and reception of polls feat(polls): linked Poll creation to poll answering fix(polls) Linted code feat(polls.create) Added fields for question and answers (#3) * feat(polls.create) Added fields for question and answers + keyboard navigation * feat(polls.create) Minor changes, added some comments feat(PollAnswer Component): Component to display modal to answer poll #1 (#2) * fix(polls) removing necessity of current_poll_id variable * fix(polls) linting, polls are now updated when an answer is sent * feat(polls answer) added translation * fix(polls answer) remove extra comments, fixed typo * improvement (polls answer) use useSelector instead of mapStateToProps. cleaner code * fix (polls create) renamed sender to senderId * fix (polls answer) turned arrow function into useCallBack feat(PollResults Component): Component to display poll results (#1) * feat(PollResults Component): fist version of the component * feat(detailed votes): Display the detailed results of a poll * feat(Poll results): Use display name instead of ids in detailed results mode * fix(Poll): change title to question * fix(Poll type): import Poll type from types.js * fix(Poll): change title to question * fix(Poll): get participants out of the map * fix(Poll): replace filter with find feat(polls.create) Added "+" and "x" buttons in poll creation form + improved keyboard navigation a bit feat (polls) Answer modal now display results in real time after validation or skip feat(polls.create) Minor improvements to poll creation form feat(poll result) Added default message when trying to display no answer fix (polls) result windows is now small by default fix (polls) sanitizes imports to allow startup on react native * feat(polls.native) Implemented native toolbar button & poll create modal feat( poll native) added poll creation button in native toolbar improvement(polls) only one file used for PollCreateButton feat (polls native) added an example dialog feat (polls native) added possibility to create and delete options in poll creation improvement (polls) better styling for PollCreateDialog * feat(polls) Added ability to drag&drop answers in web poll creation form * feat(polls) Added native poll answer modal + chat integration, refactored components Merge branch 'polls-native' of https://github.com/jade-guiton/jitsi-meet into polls-native improvement (poll) Better styling for poll answer, now uses icons feat(poll.PollResults): Add native version of PollResults feat(poll.PollResults): Post results in chat in Native fix(poll.PollResults): Fix linter error in ChatMessage feat(polls.native) Improved styling for native poll answer dialog (required some internal changes) * fix(polls) Heavily refactored and added bars to poll results, other minor changes fix(poll.create): Move title to Dialog title feat(poll.create) Minor changes to poll creation / answer dialogs fix(poll.create) Refactored and improved translations feat(poll) Improved CSS for modals in web version fix(poll.pollcreate): Fix button size in native fix(polls) Refactored poll results component and other minor changes fix (polls) remove double import refactor(poll) Heavily refactored poll results (native + web) feat(polls.results) Added percentage bars and vote counts in web poll results, minor changes to mobile poll results * fix(polls) Fixes and linting fix(polls) Reformatted and fixed some linter and Flow errors fix(polls.results) Fixed voter list border appearing with 0 voters * feat(polls): Add modal with detailed votes that can be open from the result summary in the chat * fix(polls) Fixes, refactorings, and minor design changes feat(polls.results): Refactored poll chat message and improved design in web app feat(polls.results) Same as last commit, but for mobile version refactor(polls.results) Refactored PollResultsMessage and removed unnecessary prop in PollResults fix(polls.results) Fixed all remaining linter and Flow errors improvement(polls) removed console logs, added comments fix (polls) linting fix(polls.results) Fixed bug with poll chat message displaying the wrong name feat(polls.results) Minor improvement on poll results display (web) fix(poll.results): Use getParticipantDisplayName to get participant name and avoid empty string as name * Feat(poll.results): Remember voters names to display after they left the conference (#10) * feat(poll.results): Add the sender name in Poll object to remember names if participants leave the conference. Names are also updated if changed * refactor(poll.results): Refactor the memorization of the names of voters to use the same logic as in the chat * refactor(poll.results): use Map instead of Array.From( * refactor(poll.answer): change the way names are stored in poll answers to persist if participant left the call * Update react/features/polls/components/AbstractPollAnswerDialog.js * Update react/features/polls/components/AbstractPollCreateDialog.js * refactor(poll.answer): use voterName instead of senderName to avoid confusion with senderId the id of the sender of the poll * improvement(polls) Simplified poll answer voter name logic Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Jade Guiton <guiton.jade@gmail.com> * fix(poll.native): Fix UI overflow when asking long questions & long options in the mobile app (#11) Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> * fix(polls) Fixed close button behavior in answer and results dialog (#12) * fix(polls) Fixed close button behavior in answer and results dialog * fix(polls) Fixed linter error * fix(polls) Added a poll queue to avoid overwriting open modals (#13) * fix(polls) Added a poll queue to avoid overwriting open modals * fix(polls) Updated documentation for action RECEIVE_POLL * Refactor(poll.chatresults): Add message in chat with hidden results until the participant has answered (#14) * refactor(poll.chat): Display poll results in chat when the poll is created instead of when the participant has ansered * refactor(poll.chat): Hide results until the participant has answered, skipped or canceled a responde to the poll * Use getParticipantDisplayName instead of only getStore() * Hide results also in native * fix(polls) Fixed previous merge Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Jade Guiton <jade.guiton@centralesupelec.fr> * minor improvements (polls) refactor (polls) uniformized string for command names refactor (polls) changed pollId type to number everywhere * feat(polls) Added persistence to polls using sendMessage instead of sendCommandOnce (#16) * feat(polls) Using sendMessage instead of sendCommandOnce, switched poll IDs to string, and ability to receive old polls from backend * improvement(polls) Linted everything, fixed Flow errors, and added Prosody plugin for polls * improvement(polls) Historic polls are now displayed in chronological order * (polls) Minor improvements (#17) * renaming (polls) Renaming senderId -> voterID for voters * improvement (polls) sender's name is now provided with poll * comments (polls) updated comments for senderName types * fix(polls) Finished merging with json-messages feature * fix(polls) Fixed incorrect json-message sent with 0 polls Co-authored-by: Jade Guiton <guiton.jade@gmail.com> * Move polls to tab (#23) * Draft(polls): Move polls to polls-pane ; first version for web * Draft(polls): Move polls to polls-pane ; clean styled.js and remove Participant objects * fix missing newline at the end of file * Change behaviour to allow answer poll later * Fix(polls): change pollId type from number to string for consistency * feat(polls-pane): Ability to answer to a poll in polls-pane * feat(polls-pane): Ability to create to a poll in polls-pane * feat (polls.pane) display a notification when a new poll arrives * refactor(polls-pane): Update CSS to have a design closer to the mockups * fix(poll.vote count): Fix votes counting when computing percentage * fix(poll.vote count): Fix votes counting when computing percentage * refresh fork with jitsi/jitsi-meet * design (polls) Better look for poll creation * refactor(polls pane): Move polls-pane as a chat tab * Remove the first version of the polls-pane and the button to open it * Fix notifications and typo * Translate new polls tab in chat * Change polls_pane to polls-pane * Remove unless functions * Remove usage of styled.js * Improve responsiveness * Separate web and native logic * Remove Create a Poll button in web toolbox * improvement (polls) added auto scrolling to bottom when a new poll arrives * Add tabs to swicth between polls and chat in native * Add AbstractPollsPane * Add AbstractPollCreate * Add AbstractPollAnswer * Add PollAnswer, PollItem and PollList for native * Add PollCreate for native * Remove dialogs in web and native * Remove dialog queue * Remove useless files * Move _polls.scss outside dialog folder * Add possibility to skip answer * Add (useless for now) see details link * Add possibility to show detailed results for a poll * Resize progress bar to make details display * refactor, design (polls) better style to native design chat * fix (polls) Removed unecessary files * translate (polls) added french translation to empty polls * design fix (polls.native) 'show details' now correctly switch between progress bar and voters mode * Change See detailed results for Show details and add cursor: pointer * Fix progress bars not aligned with text * fix (polls.native) added autoselection of newly created option * Remove poll answer * improvement(polls.create) Improved web poll creation form marginally * improvement(polls.change) Simplified answer removal by reusing poll-answer command * fix linter * Fix(translation): update translation Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: spineki <marras.antoine@gmail.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@viarezo.fr> * Merge pull request #22 from jade-guiton/polls-with-notification feat (polls) chat notification badge now display the sum of unread messages and unread polls fix(translation): Fix missing translation Fix flow error * Cleaned up, fixed, and uniformized translations * Small improvements to PollAnswer and PollResult + Much refactoring Specifically: - "Change vote" button now says "Vote" if voting was skipped - Clicking on "Change vote" resets the voting form to the last submitted answers instead of a blank slate - The "answered" field of Polls was replaced by "showResults" and "lastVote" - The "setAnsweredStatus" action was replaced by "registerVote" and "retractVote" - Some newly unreachable/useless code was removed - "showDetails" state is now handled by AbstractPollResults instead of PollItem * fix(polls tab): change tab underline color to #525252 * fix(poll create): Enforce at least two options to create a poll * fix(poll create): change 'remove option' color to #E04757 * fix(poll create): Update Poll create CSS to adapt to design * fix(poll answer): Adapt CSS to make poll answer closer to mockup * fix(poll result): Udpdate poll result CSS to match mockups * fix(poll result): Udpdate poll result CSS to match mockups * fix(poll create): Display 'remove option' only when there is at least 3 options * fix(polls button): Add hover, active, focus and disabled state to polls buttons * Last improvements for web * Native design fixes * Fix rebase issue in land/main.json * Fix french translation after rebase * Fixmobile behaviour * Fixed keyboard navigation in web poll creation form * Fixed Flow error related to "no polls" icon in PollsList * fix(polls): Enabled polls Prosody module in Debian config files * doc(polls) Added comments to the Prosody module code * fix(polls): Switched from using an internal LJM event to ones from the public API * Capitalize I of setIsPollsTabFocused * extract the 2 button modes into a const * remove extra new lines * Rename CLOSE_POLL_TAB for POLL_TAB_CLOSED for clarity * Rename answers2 for answersParsed for clarity * use switch instead of if/else chain * improve syntax for localId fetching * Refactor: Use BUTTON_MODE.CONTAINED variable instead of 'contained' * Disable send poll button if not enough data is provided in the form (#30) * Feat: Add notification badge on chat and poll tabs (#31) * Feat: Add notification badge on chat and poll tabs * Add badge equivalent for native * Update displayNameForm text to mention polls (#34) * Disable polls UI with a config in config.js (#33) * Change remove option text color from red to grey (#32) Co-authored-by: spineki <marras.antoine@gmail.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Fabien Zucchet <80532941+fabienzucchet@users.noreply.github.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@viarezo.fr>
2021-08-14 13:29:42 +00:00
case CLOSE_CHAT: {
const isPollTabOpen = getState()['features/chat'].isPollsTabFocused;
unreadCount = 0;
if (typeof APP !== 'undefined') {
APP.API.notifyChatUpdated(unreadCount, false);
}
feat(polls) Ability to create polls inside Jitsi (#9166) * feat(polls) Added boilerplate code for polls feature * feat(polls) Implemented simple poll creation and answer modals in web app feat(polls) Added button to create a poll in toolbar feat(polls) Added Modal to answer an incoming poll feat(polls) Implemented basic client-side sending and reception of polls feat(polls): linked Poll creation to poll answering fix(polls) Linted code feat(polls.create) Added fields for question and answers (#3) * feat(polls.create) Added fields for question and answers + keyboard navigation * feat(polls.create) Minor changes, added some comments feat(PollAnswer Component): Component to display modal to answer poll #1 (#2) * fix(polls) removing necessity of current_poll_id variable * fix(polls) linting, polls are now updated when an answer is sent * feat(polls answer) added translation * fix(polls answer) remove extra comments, fixed typo * improvement (polls answer) use useSelector instead of mapStateToProps. cleaner code * fix (polls create) renamed sender to senderId * fix (polls answer) turned arrow function into useCallBack feat(PollResults Component): Component to display poll results (#1) * feat(PollResults Component): fist version of the component * feat(detailed votes): Display the detailed results of a poll * feat(Poll results): Use display name instead of ids in detailed results mode * fix(Poll): change title to question * fix(Poll type): import Poll type from types.js * fix(Poll): change title to question * fix(Poll): get participants out of the map * fix(Poll): replace filter with find feat(polls.create) Added "+" and "x" buttons in poll creation form + improved keyboard navigation a bit feat (polls) Answer modal now display results in real time after validation or skip feat(polls.create) Minor improvements to poll creation form feat(poll result) Added default message when trying to display no answer fix (polls) result windows is now small by default fix (polls) sanitizes imports to allow startup on react native * feat(polls.native) Implemented native toolbar button & poll create modal feat( poll native) added poll creation button in native toolbar improvement(polls) only one file used for PollCreateButton feat (polls native) added an example dialog feat (polls native) added possibility to create and delete options in poll creation improvement (polls) better styling for PollCreateDialog * feat(polls) Added ability to drag&drop answers in web poll creation form * feat(polls) Added native poll answer modal + chat integration, refactored components Merge branch 'polls-native' of https://github.com/jade-guiton/jitsi-meet into polls-native improvement (poll) Better styling for poll answer, now uses icons feat(poll.PollResults): Add native version of PollResults feat(poll.PollResults): Post results in chat in Native fix(poll.PollResults): Fix linter error in ChatMessage feat(polls.native) Improved styling for native poll answer dialog (required some internal changes) * fix(polls) Heavily refactored and added bars to poll results, other minor changes fix(poll.create): Move title to Dialog title feat(poll.create) Minor changes to poll creation / answer dialogs fix(poll.create) Refactored and improved translations feat(poll) Improved CSS for modals in web version fix(poll.pollcreate): Fix button size in native fix(polls) Refactored poll results component and other minor changes fix (polls) remove double import refactor(poll) Heavily refactored poll results (native + web) feat(polls.results) Added percentage bars and vote counts in web poll results, minor changes to mobile poll results * fix(polls) Fixes and linting fix(polls) Reformatted and fixed some linter and Flow errors fix(polls.results) Fixed voter list border appearing with 0 voters * feat(polls): Add modal with detailed votes that can be open from the result summary in the chat * fix(polls) Fixes, refactorings, and minor design changes feat(polls.results): Refactored poll chat message and improved design in web app feat(polls.results) Same as last commit, but for mobile version refactor(polls.results) Refactored PollResultsMessage and removed unnecessary prop in PollResults fix(polls.results) Fixed all remaining linter and Flow errors improvement(polls) removed console logs, added comments fix (polls) linting fix(polls.results) Fixed bug with poll chat message displaying the wrong name feat(polls.results) Minor improvement on poll results display (web) fix(poll.results): Use getParticipantDisplayName to get participant name and avoid empty string as name * Feat(poll.results): Remember voters names to display after they left the conference (#10) * feat(poll.results): Add the sender name in Poll object to remember names if participants leave the conference. Names are also updated if changed * refactor(poll.results): Refactor the memorization of the names of voters to use the same logic as in the chat * refactor(poll.results): use Map instead of Array.From( * refactor(poll.answer): change the way names are stored in poll answers to persist if participant left the call * Update react/features/polls/components/AbstractPollAnswerDialog.js * Update react/features/polls/components/AbstractPollCreateDialog.js * refactor(poll.answer): use voterName instead of senderName to avoid confusion with senderId the id of the sender of the poll * improvement(polls) Simplified poll answer voter name logic Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Jade Guiton <guiton.jade@gmail.com> * fix(poll.native): Fix UI overflow when asking long questions & long options in the mobile app (#11) Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> * fix(polls) Fixed close button behavior in answer and results dialog (#12) * fix(polls) Fixed close button behavior in answer and results dialog * fix(polls) Fixed linter error * fix(polls) Added a poll queue to avoid overwriting open modals (#13) * fix(polls) Added a poll queue to avoid overwriting open modals * fix(polls) Updated documentation for action RECEIVE_POLL * Refactor(poll.chatresults): Add message in chat with hidden results until the participant has answered (#14) * refactor(poll.chat): Display poll results in chat when the poll is created instead of when the participant has ansered * refactor(poll.chat): Hide results until the participant has answered, skipped or canceled a responde to the poll * Use getParticipantDisplayName instead of only getStore() * Hide results also in native * fix(polls) Fixed previous merge Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Jade Guiton <jade.guiton@centralesupelec.fr> * minor improvements (polls) refactor (polls) uniformized string for command names refactor (polls) changed pollId type to number everywhere * feat(polls) Added persistence to polls using sendMessage instead of sendCommandOnce (#16) * feat(polls) Using sendMessage instead of sendCommandOnce, switched poll IDs to string, and ability to receive old polls from backend * improvement(polls) Linted everything, fixed Flow errors, and added Prosody plugin for polls * improvement(polls) Historic polls are now displayed in chronological order * (polls) Minor improvements (#17) * renaming (polls) Renaming senderId -> voterID for voters * improvement (polls) sender's name is now provided with poll * comments (polls) updated comments for senderName types * fix(polls) Finished merging with json-messages feature * fix(polls) Fixed incorrect json-message sent with 0 polls Co-authored-by: Jade Guiton <guiton.jade@gmail.com> * Move polls to tab (#23) * Draft(polls): Move polls to polls-pane ; first version for web * Draft(polls): Move polls to polls-pane ; clean styled.js and remove Participant objects * fix missing newline at the end of file * Change behaviour to allow answer poll later * Fix(polls): change pollId type from number to string for consistency * feat(polls-pane): Ability to answer to a poll in polls-pane * feat(polls-pane): Ability to create to a poll in polls-pane * feat (polls.pane) display a notification when a new poll arrives * refactor(polls-pane): Update CSS to have a design closer to the mockups * fix(poll.vote count): Fix votes counting when computing percentage * fix(poll.vote count): Fix votes counting when computing percentage * refresh fork with jitsi/jitsi-meet * design (polls) Better look for poll creation * refactor(polls pane): Move polls-pane as a chat tab * Remove the first version of the polls-pane and the button to open it * Fix notifications and typo * Translate new polls tab in chat * Change polls_pane to polls-pane * Remove unless functions * Remove usage of styled.js * Improve responsiveness * Separate web and native logic * Remove Create a Poll button in web toolbox * improvement (polls) added auto scrolling to bottom when a new poll arrives * Add tabs to swicth between polls and chat in native * Add AbstractPollsPane * Add AbstractPollCreate * Add AbstractPollAnswer * Add PollAnswer, PollItem and PollList for native * Add PollCreate for native * Remove dialogs in web and native * Remove dialog queue * Remove useless files * Move _polls.scss outside dialog folder * Add possibility to skip answer * Add (useless for now) see details link * Add possibility to show detailed results for a poll * Resize progress bar to make details display * refactor, design (polls) better style to native design chat * fix (polls) Removed unecessary files * translate (polls) added french translation to empty polls * design fix (polls.native) 'show details' now correctly switch between progress bar and voters mode * Change See detailed results for Show details and add cursor: pointer * Fix progress bars not aligned with text * fix (polls.native) added autoselection of newly created option * Remove poll answer * improvement(polls.create) Improved web poll creation form marginally * improvement(polls.change) Simplified answer removal by reusing poll-answer command * fix linter * Fix(translation): update translation Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: spineki <marras.antoine@gmail.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@viarezo.fr> * Merge pull request #22 from jade-guiton/polls-with-notification feat (polls) chat notification badge now display the sum of unread messages and unread polls fix(translation): Fix missing translation Fix flow error * Cleaned up, fixed, and uniformized translations * Small improvements to PollAnswer and PollResult + Much refactoring Specifically: - "Change vote" button now says "Vote" if voting was skipped - Clicking on "Change vote" resets the voting form to the last submitted answers instead of a blank slate - The "answered" field of Polls was replaced by "showResults" and "lastVote" - The "setAnsweredStatus" action was replaced by "registerVote" and "retractVote" - Some newly unreachable/useless code was removed - "showDetails" state is now handled by AbstractPollResults instead of PollItem * fix(polls tab): change tab underline color to #525252 * fix(poll create): Enforce at least two options to create a poll * fix(poll create): change 'remove option' color to #E04757 * fix(poll create): Update Poll create CSS to adapt to design * fix(poll answer): Adapt CSS to make poll answer closer to mockup * fix(poll result): Udpdate poll result CSS to match mockups * fix(poll result): Udpdate poll result CSS to match mockups * fix(poll create): Display 'remove option' only when there is at least 3 options * fix(polls button): Add hover, active, focus and disabled state to polls buttons * Last improvements for web * Native design fixes * Fix rebase issue in land/main.json * Fix french translation after rebase * Fixmobile behaviour * Fixed keyboard navigation in web poll creation form * Fixed Flow error related to "no polls" icon in PollsList * fix(polls): Enabled polls Prosody module in Debian config files * doc(polls) Added comments to the Prosody module code * fix(polls): Switched from using an internal LJM event to ones from the public API * Capitalize I of setIsPollsTabFocused * extract the 2 button modes into a const * remove extra new lines * Rename CLOSE_POLL_TAB for POLL_TAB_CLOSED for clarity * Rename answers2 for answersParsed for clarity * use switch instead of if/else chain * improve syntax for localId fetching * Refactor: Use BUTTON_MODE.CONTAINED variable instead of 'contained' * Disable send poll button if not enough data is provided in the form (#30) * Feat: Add notification badge on chat and poll tabs (#31) * Feat: Add notification badge on chat and poll tabs * Add badge equivalent for native * Update displayNameForm text to mention polls (#34) * Disable polls UI with a config in config.js (#33) * Change remove option text color from red to grey (#32) Co-authored-by: spineki <marras.antoine@gmail.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Fabien Zucchet <80532941+fabienzucchet@users.noreply.github.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@viarezo.fr>
2021-08-14 13:29:42 +00:00
if (isPollTabOpen) {
dispatch(resetNbUnreadPollsMessages());
}
break;
feat(polls) Ability to create polls inside Jitsi (#9166) * feat(polls) Added boilerplate code for polls feature * feat(polls) Implemented simple poll creation and answer modals in web app feat(polls) Added button to create a poll in toolbar feat(polls) Added Modal to answer an incoming poll feat(polls) Implemented basic client-side sending and reception of polls feat(polls): linked Poll creation to poll answering fix(polls) Linted code feat(polls.create) Added fields for question and answers (#3) * feat(polls.create) Added fields for question and answers + keyboard navigation * feat(polls.create) Minor changes, added some comments feat(PollAnswer Component): Component to display modal to answer poll #1 (#2) * fix(polls) removing necessity of current_poll_id variable * fix(polls) linting, polls are now updated when an answer is sent * feat(polls answer) added translation * fix(polls answer) remove extra comments, fixed typo * improvement (polls answer) use useSelector instead of mapStateToProps. cleaner code * fix (polls create) renamed sender to senderId * fix (polls answer) turned arrow function into useCallBack feat(PollResults Component): Component to display poll results (#1) * feat(PollResults Component): fist version of the component * feat(detailed votes): Display the detailed results of a poll * feat(Poll results): Use display name instead of ids in detailed results mode * fix(Poll): change title to question * fix(Poll type): import Poll type from types.js * fix(Poll): change title to question * fix(Poll): get participants out of the map * fix(Poll): replace filter with find feat(polls.create) Added "+" and "x" buttons in poll creation form + improved keyboard navigation a bit feat (polls) Answer modal now display results in real time after validation or skip feat(polls.create) Minor improvements to poll creation form feat(poll result) Added default message when trying to display no answer fix (polls) result windows is now small by default fix (polls) sanitizes imports to allow startup on react native * feat(polls.native) Implemented native toolbar button & poll create modal feat( poll native) added poll creation button in native toolbar improvement(polls) only one file used for PollCreateButton feat (polls native) added an example dialog feat (polls native) added possibility to create and delete options in poll creation improvement (polls) better styling for PollCreateDialog * feat(polls) Added ability to drag&drop answers in web poll creation form * feat(polls) Added native poll answer modal + chat integration, refactored components Merge branch 'polls-native' of https://github.com/jade-guiton/jitsi-meet into polls-native improvement (poll) Better styling for poll answer, now uses icons feat(poll.PollResults): Add native version of PollResults feat(poll.PollResults): Post results in chat in Native fix(poll.PollResults): Fix linter error in ChatMessage feat(polls.native) Improved styling for native poll answer dialog (required some internal changes) * fix(polls) Heavily refactored and added bars to poll results, other minor changes fix(poll.create): Move title to Dialog title feat(poll.create) Minor changes to poll creation / answer dialogs fix(poll.create) Refactored and improved translations feat(poll) Improved CSS for modals in web version fix(poll.pollcreate): Fix button size in native fix(polls) Refactored poll results component and other minor changes fix (polls) remove double import refactor(poll) Heavily refactored poll results (native + web) feat(polls.results) Added percentage bars and vote counts in web poll results, minor changes to mobile poll results * fix(polls) Fixes and linting fix(polls) Reformatted and fixed some linter and Flow errors fix(polls.results) Fixed voter list border appearing with 0 voters * feat(polls): Add modal with detailed votes that can be open from the result summary in the chat * fix(polls) Fixes, refactorings, and minor design changes feat(polls.results): Refactored poll chat message and improved design in web app feat(polls.results) Same as last commit, but for mobile version refactor(polls.results) Refactored PollResultsMessage and removed unnecessary prop in PollResults fix(polls.results) Fixed all remaining linter and Flow errors improvement(polls) removed console logs, added comments fix (polls) linting fix(polls.results) Fixed bug with poll chat message displaying the wrong name feat(polls.results) Minor improvement on poll results display (web) fix(poll.results): Use getParticipantDisplayName to get participant name and avoid empty string as name * Feat(poll.results): Remember voters names to display after they left the conference (#10) * feat(poll.results): Add the sender name in Poll object to remember names if participants leave the conference. Names are also updated if changed * refactor(poll.results): Refactor the memorization of the names of voters to use the same logic as in the chat * refactor(poll.results): use Map instead of Array.From( * refactor(poll.answer): change the way names are stored in poll answers to persist if participant left the call * Update react/features/polls/components/AbstractPollAnswerDialog.js * Update react/features/polls/components/AbstractPollCreateDialog.js * refactor(poll.answer): use voterName instead of senderName to avoid confusion with senderId the id of the sender of the poll * improvement(polls) Simplified poll answer voter name logic Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Jade Guiton <guiton.jade@gmail.com> * fix(poll.native): Fix UI overflow when asking long questions & long options in the mobile app (#11) Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> * fix(polls) Fixed close button behavior in answer and results dialog (#12) * fix(polls) Fixed close button behavior in answer and results dialog * fix(polls) Fixed linter error * fix(polls) Added a poll queue to avoid overwriting open modals (#13) * fix(polls) Added a poll queue to avoid overwriting open modals * fix(polls) Updated documentation for action RECEIVE_POLL * Refactor(poll.chatresults): Add message in chat with hidden results until the participant has answered (#14) * refactor(poll.chat): Display poll results in chat when the poll is created instead of when the participant has ansered * refactor(poll.chat): Hide results until the participant has answered, skipped or canceled a responde to the poll * Use getParticipantDisplayName instead of only getStore() * Hide results also in native * fix(polls) Fixed previous merge Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Jade Guiton <jade.guiton@centralesupelec.fr> * minor improvements (polls) refactor (polls) uniformized string for command names refactor (polls) changed pollId type to number everywhere * feat(polls) Added persistence to polls using sendMessage instead of sendCommandOnce (#16) * feat(polls) Using sendMessage instead of sendCommandOnce, switched poll IDs to string, and ability to receive old polls from backend * improvement(polls) Linted everything, fixed Flow errors, and added Prosody plugin for polls * improvement(polls) Historic polls are now displayed in chronological order * (polls) Minor improvements (#17) * renaming (polls) Renaming senderId -> voterID for voters * improvement (polls) sender's name is now provided with poll * comments (polls) updated comments for senderName types * fix(polls) Finished merging with json-messages feature * fix(polls) Fixed incorrect json-message sent with 0 polls Co-authored-by: Jade Guiton <guiton.jade@gmail.com> * Move polls to tab (#23) * Draft(polls): Move polls to polls-pane ; first version for web * Draft(polls): Move polls to polls-pane ; clean styled.js and remove Participant objects * fix missing newline at the end of file * Change behaviour to allow answer poll later * Fix(polls): change pollId type from number to string for consistency * feat(polls-pane): Ability to answer to a poll in polls-pane * feat(polls-pane): Ability to create to a poll in polls-pane * feat (polls.pane) display a notification when a new poll arrives * refactor(polls-pane): Update CSS to have a design closer to the mockups * fix(poll.vote count): Fix votes counting when computing percentage * fix(poll.vote count): Fix votes counting when computing percentage * refresh fork with jitsi/jitsi-meet * design (polls) Better look for poll creation * refactor(polls pane): Move polls-pane as a chat tab * Remove the first version of the polls-pane and the button to open it * Fix notifications and typo * Translate new polls tab in chat * Change polls_pane to polls-pane * Remove unless functions * Remove usage of styled.js * Improve responsiveness * Separate web and native logic * Remove Create a Poll button in web toolbox * improvement (polls) added auto scrolling to bottom when a new poll arrives * Add tabs to swicth between polls and chat in native * Add AbstractPollsPane * Add AbstractPollCreate * Add AbstractPollAnswer * Add PollAnswer, PollItem and PollList for native * Add PollCreate for native * Remove dialogs in web and native * Remove dialog queue * Remove useless files * Move _polls.scss outside dialog folder * Add possibility to skip answer * Add (useless for now) see details link * Add possibility to show detailed results for a poll * Resize progress bar to make details display * refactor, design (polls) better style to native design chat * fix (polls) Removed unecessary files * translate (polls) added french translation to empty polls * design fix (polls.native) 'show details' now correctly switch between progress bar and voters mode * Change See detailed results for Show details and add cursor: pointer * Fix progress bars not aligned with text * fix (polls.native) added autoselection of newly created option * Remove poll answer * improvement(polls.create) Improved web poll creation form marginally * improvement(polls.change) Simplified answer removal by reusing poll-answer command * fix linter * Fix(translation): update translation Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: spineki <marras.antoine@gmail.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@viarezo.fr> * Merge pull request #22 from jade-guiton/polls-with-notification feat (polls) chat notification badge now display the sum of unread messages and unread polls fix(translation): Fix missing translation Fix flow error * Cleaned up, fixed, and uniformized translations * Small improvements to PollAnswer and PollResult + Much refactoring Specifically: - "Change vote" button now says "Vote" if voting was skipped - Clicking on "Change vote" resets the voting form to the last submitted answers instead of a blank slate - The "answered" field of Polls was replaced by "showResults" and "lastVote" - The "setAnsweredStatus" action was replaced by "registerVote" and "retractVote" - Some newly unreachable/useless code was removed - "showDetails" state is now handled by AbstractPollResults instead of PollItem * fix(polls tab): change tab underline color to #525252 * fix(poll create): Enforce at least two options to create a poll * fix(poll create): change 'remove option' color to #E04757 * fix(poll create): Update Poll create CSS to adapt to design * fix(poll answer): Adapt CSS to make poll answer closer to mockup * fix(poll result): Udpdate poll result CSS to match mockups * fix(poll result): Udpdate poll result CSS to match mockups * fix(poll create): Display 'remove option' only when there is at least 3 options * fix(polls button): Add hover, active, focus and disabled state to polls buttons * Last improvements for web * Native design fixes * Fix rebase issue in land/main.json * Fix french translation after rebase * Fixmobile behaviour * Fixed keyboard navigation in web poll creation form * Fixed Flow error related to "no polls" icon in PollsList * fix(polls): Enabled polls Prosody module in Debian config files * doc(polls) Added comments to the Prosody module code * fix(polls): Switched from using an internal LJM event to ones from the public API * Capitalize I of setIsPollsTabFocused * extract the 2 button modes into a const * remove extra new lines * Rename CLOSE_POLL_TAB for POLL_TAB_CLOSED for clarity * Rename answers2 for answersParsed for clarity * use switch instead of if/else chain * improve syntax for localId fetching * Refactor: Use BUTTON_MODE.CONTAINED variable instead of 'contained' * Disable send poll button if not enough data is provided in the form (#30) * Feat: Add notification badge on chat and poll tabs (#31) * Feat: Add notification badge on chat and poll tabs * Add badge equivalent for native * Update displayNameForm text to mention polls (#34) * Disable polls UI with a config in config.js (#33) * Change remove option text color from red to grey (#32) Co-authored-by: spineki <marras.antoine@gmail.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@student-cs.fr> Co-authored-by: Fabien Zucchet <80532941+fabienzucchet@users.noreply.github.com> Co-authored-by: Fabien Zucchet <fabien.zucchet@viarezo.fr>
2021-08-14 13:29:42 +00:00
}
case SET_IS_POLL_TAB_FOCUSED: {
dispatch(resetNbUnreadPollsMessages());
break;
}
case SEND_MESSAGE: {
2019-10-07 12:35:04 +00:00
const state = store.getState();
const conference = getCurrentConference(state);
if (conference) {
2019-10-07 12:35:04 +00:00
// There may be cases when we intend to send a private message but we forget to set the
// recipient. This logic tries to mitigate this risk.
const shouldSendPrivateMessageTo = _shouldSendPrivateMessageTo(state, action);
if (shouldSendPrivateMessageTo) {
dispatch(openDialog(ChatPrivacyDialog, {
message: action.message,
participantID: shouldSendPrivateMessageTo
}));
} else {
// Sending the message if privacy notice doesn't need to be shown.
const { privateMessageRecipient, isLobbyChatActive, lobbyMessageRecipient }
= state['features/chat'];
2019-10-07 12:35:04 +00:00
if (typeof APP !== 'undefined') {
APP.API.notifySendingChatMessage(action.message, Boolean(privateMessageRecipient));
2019-10-07 12:35:04 +00:00
}
if (isLobbyChatActive && lobbyMessageRecipient) {
conference.sendLobbyMessage({
type: LOBBY_CHAT_MESSAGE,
message: action.message
}, lobbyMessageRecipient.id);
_persistSentPrivateMessage(store, lobbyMessageRecipient.id, action.message, true);
} else if (privateMessageRecipient) {
2019-10-07 12:35:04 +00:00
conference.sendPrivateTextMessage(privateMessageRecipient.id, action.message);
_persistSentPrivateMessage(store, privateMessageRecipient.id, action.message);
} else {
conference.sendTextMessage(action.message);
}
}
}
break;
}
case ADD_REACTION_MESSAGE: {
if (localParticipant?.id) {
_handleReceivedMessage(store, {
id: localParticipant.id,
message: action.message,
privateMessage: false,
timestamp: Date.now(),
lobbyChat: false
}, false, true);
}
}
}
return next(action);
});
/**
* Set up state change listener to perform maintenance tasks when the conference
2021-11-04 21:10:43 +00:00
* is left or failed, e.g. Clear messages or close the chat modal if it's left
* open.
*/
StateListenerRegistry.register(
state => getCurrentConference(state),
(conference, { dispatch, getState }, previousConference) => {
if (conference !== previousConference) {
// conference changed, left or failed...
if (getState()['features/chat'].isOpen) {
// Closes the chat if it's left open.
dispatch(closeChat());
}
// Clear chat messages.
dispatch(clearMessages());
}
});
2019-07-17 22:06:10 +00:00
StateListenerRegistry.register(
state => state['features/chat'].isOpen,
(isOpen, { dispatch }) => {
if (typeof APP !== 'undefined' && isOpen) {
dispatch(showToolbox());
}
}
);
/**
* Registers listener for {@link JitsiConferenceEvents.MESSAGE_RECEIVED} that
* will perform various chat related activities.
*
* @param {JitsiConference} conference - The conference instance on which the
* new event listener will be registered.
* @param {Object} store - The redux store object.
* @private
* @returns {void}
*/
function _addChatMsgListener(conference: IJitsiConference, store: IStore) {
if (store.getState()['features/base/config'].iAmRecorder) {
// We don't register anything on web if we are in iAmRecorder mode
return;
}
conference.on(
JitsiConferenceEvents.MESSAGE_RECEIVED,
(id: string, message: string, timestamp: number) => {
_onConferenceMessageReceived(store, { id,
2019-10-07 12:35:04 +00:00
message,
timestamp,
privateMessage: false });
2019-10-07 12:35:04 +00:00
}
);
2019-10-07 12:35:04 +00:00
conference.on(
JitsiConferenceEvents.PRIVATE_MESSAGE_RECEIVED,
(id: string, message: string, timestamp: number) => {
_onConferenceMessageReceived(store, {
id,
message,
timestamp,
privateMessage: true
2019-10-07 12:35:04 +00:00
});
}
);
2019-10-09 08:34:01 +00:00
conference.on(
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
(...args: any) => {
const state = store.getState();
if (!isReactionsEnabled(state)) {
return;
}
// @ts-ignore
store.dispatch(endpointMessageReceived(...args));
if (args && args.length >= 2) {
const [ { _id }, eventData ] = args;
if (eventData.name === ENDPOINT_REACTION_NAME) {
store.dispatch(pushReactions(eventData.reactions));
_handleReceivedMessage(store, {
id: _id,
message: getReactionMessageFromBuffer(eventData.reactions),
privateMessage: false,
lobbyChat: false,
timestamp: eventData.timestamp
}, false, true);
}
}
});
2019-10-09 08:34:01 +00:00
conference.on(
JitsiConferenceEvents.CONFERENCE_ERROR, (errorType: string, error: Error) => {
2019-10-09 08:34:01 +00:00
errorType === JitsiConferenceErrors.CHAT_ERROR && _handleChatError(store, error);
});
}
/**
* Handles a received message.
*
* @param {Object} store - Redux store.
* @param {Object} message - The message object.
* @returns {void}
*/
function _onConferenceMessageReceived(store: IStore, { id, message, timestamp, privateMessage }: {
id: string; message: string; privateMessage: boolean; timestamp: number; }) {
const isGif = isGifMessage(message);
if (isGif) {
_handleGifMessageReceived(store, id, message);
if (getGifDisplayMode(store.getState()) === 'tile') {
return;
}
}
_handleReceivedMessage(store, {
id,
message,
privateMessage,
lobbyChat: false,
timestamp
}, true, isGif);
}
/**
* Handles a received gif message.
*
* @param {Object} store - Redux store.
* @param {string} id - Id of the participant that sent the message.
* @param {string} message - The message sent.
* @returns {void}
*/
function _handleGifMessageReceived(store: IStore, id: string, message: string) {
const url = message.substring(GIF_PREFIX.length, message.length - 1);
store.dispatch(addGif(id, url));
}
2019-10-09 08:34:01 +00:00
/**
* Handles a chat error received from the xmpp server.
*
* @param {Store} store - The Redux store.
* @param {string} error - The error message.
* @returns {void}
*/
function _handleChatError({ dispatch }: IStore, error: Error) {
2019-10-09 08:34:01 +00:00
dispatch(addMessage({
hasRead: true,
2019-10-15 14:08:23 +00:00
messageType: MESSAGE_TYPE_ERROR,
2019-10-09 08:34:01 +00:00
message: error,
privateMessage: false,
timestamp: Date.now()
}));
2019-10-07 12:35:04 +00:00
}
/**
* Function to handle an incoming chat message from lobby room.
*
* @param {string} message - The message received.
* @param {string} participantId - The participant id.
* @returns {Function}
*/
export function handleLobbyMessageReceived(message: string, participantId: string) {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
_handleReceivedMessage({ dispatch,
getState }, { id: participantId,
message,
privateMessage: false,
lobbyChat: true,
timestamp: Date.now() });
};
}
/**
* Function to get lobby chat user display name.
*
* @param {Store} state - The Redux store.
* @param {string} id - The knocking participant id.
* @returns {string}
*/
function getLobbyChatDisplayName(state: IReduxState, id: string) {
const { knockingParticipants } = state['features/lobby'];
const { lobbyMessageRecipient } = state['features/chat'];
if (id === lobbyMessageRecipient?.id) {
return lobbyMessageRecipient.name;
}
const knockingParticipant = knockingParticipants.find(p => p.id === id);
if (knockingParticipant) {
return knockingParticipant.name;
}
}
2019-10-07 12:35:04 +00:00
/**
* Function to handle an incoming chat message.
*
* @param {Store} store - The Redux store.
* @param {Object} message - The message object.
* @param {boolean} shouldPlaySound - Whether or not to play the incoming message sound.
* @param {boolean} isReaction - Whether or not the message is a reaction message.
2019-10-07 12:35:04 +00:00
* @returns {void}
*/
function _handleReceivedMessage({ dispatch, getState }: IStore,
{ id, message, privateMessage, timestamp, lobbyChat }: {
id: string; lobbyChat: boolean; message: string; privateMessage: boolean; timestamp: number; },
shouldPlaySound = true,
isReaction = false
) {
2019-10-07 12:35:04 +00:00
// Logic for all platforms:
const state = getState();
const { isOpen: isChatOpen } = state['features/chat'];
const { iAmRecorder } = state['features/base/config'];
const { soundsIncomingMessage: soundEnabled, userSelectedNotifications } = state['features/base/settings'];
if (soundEnabled && shouldPlaySound && !isChatOpen) {
2019-10-07 12:35:04 +00:00
dispatch(playSound(INCOMING_MSG_SOUND_ID));
}
2019-10-07 12:35:04 +00:00
// Provide a default for for the case when a message is being
// backfilled for a participant that has left the conference.
const participant = getParticipantById(state, id) || { local: undefined };
2019-10-07 12:35:04 +00:00
const localParticipant = getLocalParticipant(getState);
const displayName = lobbyChat
? getLobbyChatDisplayName(state, id)
: getParticipantDisplayName(state, id);
2019-10-07 12:35:04 +00:00
const hasRead = participant.local || isChatOpen;
const timestampToDate = timestamp ? new Date(timestamp) : new Date();
2019-10-07 12:35:04 +00:00
const millisecondsTimestamp = timestampToDate.getTime();
// skip message notifications on join (the messages having timestamp - coming from the history)
const shouldShowNotification = userSelectedNotifications?.['notify.chatMessages']
&& !hasRead && !isReaction && !timestamp;
2019-10-07 12:35:04 +00:00
dispatch(addMessage({
displayName,
hasRead,
id,
2019-10-15 14:08:23 +00:00
messageType: participant.local ? MESSAGE_TYPE_LOCAL : MESSAGE_TYPE_REMOTE,
2019-10-07 12:35:04 +00:00
message,
privateMessage,
lobbyChat,
recipient: getParticipantDisplayName(state, localParticipant?.id ?? ''),
timestamp: millisecondsTimestamp,
isReaction
2019-10-07 12:35:04 +00:00
}));
if (shouldShowNotification) {
dispatch(showMessageNotification({
title: displayName,
description: message
}, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
}
2019-10-07 12:35:04 +00:00
if (typeof APP !== 'undefined') {
// Logic for web only:
APP.API.notifyReceivedChatMessage({
body: message,
id,
nick: displayName,
privateMessage,
2019-10-07 12:35:04 +00:00
ts: timestamp
});
if (!iAmRecorder) {
dispatch(showToolbox(4000));
}
2019-10-07 12:35:04 +00:00
}
}
/**
* Persists the sent private messages as if they were received over the muc.
*
* This is required as we rely on the fact that we receive all messages from the muc that we send
* (as they are sent to everybody), but we don't receive the private messages we send to another participant.
* But those messages should be in the store as well, otherwise they don't appear in the chat window.
*
* @param {Store} store - The Redux store.
* @param {string} recipientID - The ID of the recipient the private message was sent to.
* @param {string} message - The sent message.
* @param {boolean} isLobbyPrivateMessage - Is a lobby message.
2019-10-07 12:35:04 +00:00
* @returns {void}
*/
function _persistSentPrivateMessage({ dispatch, getState }: IStore, recipientID: string,
message: string, isLobbyPrivateMessage = false) {
const state = getState();
const localParticipant = getLocalParticipant(state);
if (!localParticipant?.id) {
return;
}
const displayName = getParticipantDisplayName(state, localParticipant.id);
const { lobbyMessageRecipient } = state['features/chat'];
2019-10-07 12:35:04 +00:00
dispatch(addMessage({
displayName,
hasRead: true,
id: localParticipant.id,
2019-10-15 14:08:23 +00:00
messageType: MESSAGE_TYPE_LOCAL,
2019-10-07 12:35:04 +00:00
message,
privateMessage: !isLobbyPrivateMessage,
lobbyChat: isLobbyPrivateMessage,
recipient: isLobbyPrivateMessage
? lobbyMessageRecipient?.name
: getParticipantDisplayName(getState, recipientID),
2019-10-07 12:35:04 +00:00
timestamp: Date.now()
}));
}
/**
* Returns the ID of the participant who we may have wanted to send the message
* that we're about to send.
*
* @param {Object} state - The Redux state.
* @param {Object} action - The action being dispatched now.
* @returns {string?}
*/
function _shouldSendPrivateMessageTo(state: IReduxState, action: AnyAction) {
2019-10-07 12:35:04 +00:00
if (action.ignorePrivacy) {
// Shortcut: this is only true, if we already displayed the notice, so no need to show it again.
return undefined;
}
const { messages, privateMessageRecipient } = state['features/chat'];
if (privateMessageRecipient) {
// We're already sending a private message, no need to warn about privacy.
return undefined;
}
if (!messages.length) {
// No messages yet, no need to warn for privacy.
return undefined;
}
// Platforms sort messages differently
const lastMessage = navigator.product === 'ReactNative'
? messages[0] : messages[messages.length - 1];
2019-10-15 14:08:23 +00:00
if (lastMessage.messageType === MESSAGE_TYPE_LOCAL) {
2019-10-07 12:35:04 +00:00
// The sender is probably aware of any private messages as already sent
// a message since then. Doesn't make sense to display the notice now.
return undefined;
}
if (lastMessage.privateMessage) {
// We show the notice if the last received message was private.
return lastMessage.id;
}
// But messages may come rapidly, we want to protect our users from mis-sending a message
// even when there was a reasonable recently received private message.
const now = Date.now();
const recentPrivateMessages = messages.filter(
message =>
2019-10-15 14:08:23 +00:00
message.messageType !== MESSAGE_TYPE_LOCAL
2019-10-07 12:35:04 +00:00
&& message.privateMessage
&& message.timestamp + PRIVACY_NOTICE_TIMEOUT > now);
const recentPrivateMessage = navigator.product === 'ReactNative'
? recentPrivateMessages[0] : recentPrivateMessages[recentPrivateMessages.length - 1];
if (recentPrivateMessage) {
return recentPrivateMessage.id;
}
return undefined;
}