From 1ad09b704634b9ffababf064b8d93a4291273a0a Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Tue, 28 Jul 2020 12:55:21 +0000 Subject: [PATCH 1/2] fix poll chat message grouping / unread counter not updating for polls --- .../message-list-item/component.jsx | 89 ++++++------------- .../message-list-item/container.jsx | 16 ---- .../message-list-item/message/component.jsx | 57 +++++++++++- .../message-list-item/styles.scss | 37 +------- .../imports/ui/components/chat/service.js | 12 ++- .../imports/ui/components/poll/service.js | 9 +- 6 files changed, 98 insertions(+), 122 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/component.jsx index 4e9ebea3bf..cade8f4c4b 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/component.jsx @@ -4,6 +4,7 @@ import { FormattedTime, defineMessages, injectIntl } from 'react-intl'; import _ from 'lodash'; import Icon from '/imports/ui/components/icon/component'; import UserAvatar from '/imports/ui/components/user-avatar/component'; +import cx from 'classnames'; import Message from './message/component'; import { styles } from './styles'; @@ -42,10 +43,6 @@ const intlMessages = defineMessages({ id: 'app.chat.pollResult', description: 'used in place of user name who published poll to chat', }, - legendTitle: { - id: 'app.polling.pollingTitle', - description: 'heading for chat poll legend', - }, }); class MessageListItem extends Component { @@ -111,13 +108,14 @@ class MessageListItem extends Component { handleReadMessage, scrollArea, intl, - chats, + messages, } = this.props; - if (chats.length < 1) return null; + if (messages && messages[0].text.includes('bbb-published-poll-
')) { + return this.renderPollItem(); + } const dateTime = new Date(time); - const regEx = /]+>/i; return ( @@ -149,7 +147,7 @@ class MessageListItem extends Component {
- {chats.map(message => ( + {messages.map(message => ( - {intl.formatMessage(intlMessages.legendTitle)} -
), - ]; - - let isDefault = true; - polls.forEach((poll) => { - isDefault = isDefaultPoll(poll.text); - pollText = poll.text.split('
'); - pollElement.push(pollText.map((p, index) => { - if (!isDefault) { - legendElements.push( -
- {`${index + 1}: `} - {p.split(':')[0]} -
, - ); - } - - return ( -
- {!isDefault ? p.replace(p.split(':')[0], index + 1) : p} -
- ); - })); - }); - - if (!isDefault) { - pollElement.push(
); - pollElement.push(legendElements); - } - - return polls ? ( + return messages ? (
{ this.item = ref; }}>
@@ -240,15 +202,19 @@ class MessageListItem extends Component {
-
- {polls[0] ? ( -
- { - pollElement - } -
- ) : null} -
+ ', ''))} + />
@@ -266,10 +232,7 @@ class MessageListItem extends Component { return (
- {[ - this.renderPollItem(), - this.renderMessageItem(), - ]} + {this.renderMessageItem()}
); } diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/container.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/container.jsx index 5c7d7e0a47..31b407d453 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/container.jsx @@ -15,26 +15,10 @@ export default withTracker(({ message }) => { const mappedMessage = ChatService.mapGroupMessage(message); const messages = mappedMessage.content; - const chats = []; - const polls = []; - - if (messages.length > 0) { - messages.forEach((m) => { - if (m.text.includes('bbb-published-poll-
')) { - m.text = m.text.replace(/^bbb-published-poll-/g, ''); - polls.push(m); - } else { - chats.push(m); - } - }); - } - return { messages, user: mappedMessage.sender, time: mappedMessage.time, - chats, - polls, isDefaultPoll: (pollText) => { const pollValue = pollText.replace(/|[ :|%\n\d+]/g, ''); switch (pollValue) { diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/message/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/message/component.jsx index e015975f84..d7d7ade04f 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/message/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/message/component.jsx @@ -2,6 +2,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import _ from 'lodash'; import fastdom from 'fastdom'; +import { defineMessages, injectIntl } from 'react-intl'; const propTypes = { text: PropTypes.string.isRequired, @@ -34,13 +35,22 @@ const isElementInViewport = (el) => { ); }; -export default class MessageListItem extends PureComponent { +const intlMessages = defineMessages({ + legendTitle: { + id: 'app.polling.pollingTitle', + description: 'heading for chat poll legend', + }, +}); + +class MessageListItem extends PureComponent { constructor(props) { super(props); this.ticking = false; this.handleMessageInViewport = _.debounce(this.handleMessageInViewport.bind(this), 50); + + this.renderPollListItem = this.renderPollListItem.bind(this); } componentDidMount() { @@ -145,17 +155,56 @@ export default class MessageListItem extends PureComponent { }); } - render() { + renderPollListItem() { const { + intl, text, className, + color, + isDefaultPoll, } = this.props; + const formatBoldBlack = s => s.bold().fontcolor('black'); + + let _text = text.replace('bbb-published-poll-
', ''); + + if (!isDefaultPoll) { + const entries = _text.split('
'); + const options = []; + entries.map((e) => { options.push([e.slice(0, e.indexOf(':'))]); return e; }); + options.map((o, idx) => { + _text = formatBoldBlack(_text.replace(o, idx + 1)); + return _text; + }); + _text += formatBoldBlack(`

${intl.formatMessage(intlMessages.legendTitle)}`); + options.map((o, idx) => { _text += `
${idx + 1}: ${o}`; return _text; }); + } + return (

{ this.text = ref; }} + dangerouslySetInnerHTML={{ __html: isDefaultPoll ? formatBoldBlack(_text) : _text }} + data-test="chatMessageText" + /> + ); + } + + render() { + const { + text, + type, + className, + } = this.props; + + if (type === 'poll') return this.renderPollListItem(); + + return ( +

{ this.text = ref; }} dangerouslySetInnerHTML={{ __html: text }} - className={className} data-test="chatMessageText" /> ); @@ -164,3 +213,5 @@ export default class MessageListItem extends PureComponent { MessageListItem.propTypes = propTypes; MessageListItem.defaultProps = defaultProps; + +export default injectIntl(MessageListItem); diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/styles.scss b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/styles.scss index 5b8817b1c6..b4447341f5 100755 --- a/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/chat/message-list/message-list-item/styles.scss @@ -4,7 +4,7 @@ --systemMessage-background-color: #F9FBFC; --systemMessage-border-color: #C5CDD4; --systemMessage-font-color: var(--color-dark-grey); - --chat-poll-margin-sm: .25rem; + --chat-poll-margin-sm: .5rem; } .item { @@ -159,42 +159,11 @@ bottom: var(--border-size-large); } -.pollLine { - overflow-wrap: break-word; - font-size: var(--font-size-large); - font-weight: 600; -} - .pollWrapper { + background: var(--systemMessage-background-color); border: solid 1px var(--color-gray-lighter); border-radius: var(--border-radius); padding: var(--chat-poll-margin-sm); padding-left: 1rem; - margin-top: .5rem; - background: var(--systemMessage-background-color); -} - -.pollLegend { - display: flex; - flex-direction: row; - margin-top: var(--chat-poll-margin-sm); -} - -.pollOption { - word-break: break-word; - margin-left: var(--md-padding-y); -} - -.optionsTitle { - font-weight: bold; - margin-top: var(--md-padding-y); -} - -.divider { - position: relative; - height: 1px; - width: 95%; - margin-right: auto; - margin-top: var(--md-padding-y); - border-bottom: solid 1px var(--color-gray-lightest); + margin-top: var(--chat-poll-margin-sm) !important; } diff --git a/bigbluebutton-html5/imports/ui/components/chat/service.js b/bigbluebutton-html5/imports/ui/components/chat/service.js index 5579ad7ce4..ce745e1966 100755 --- a/bigbluebutton-html5/imports/ui/components/chat/service.js +++ b/bigbluebutton-html5/imports/ui/components/chat/service.js @@ -31,6 +31,8 @@ const UnsentMessagesCollection = new Mongo.Collection(null); // session for closed chat list const CLOSED_CHAT_LIST_KEY = 'closedChatList'; +const POLL_MESSAGE_PREFIX = 'bbb-published-poll-
'; + const getUser = userId => Users.findOne({ userId }); const getWelcomeProp = () => Meetings.findOne({ meetingId: Auth.meetingID }, @@ -83,11 +85,15 @@ const reduceGroupMessages = (previous, current) => { return previous.concat(currentMessage); } // Check if the last message is from the same user and time discrepancy - // between the two messages exceeds window and then group current message - // with the last one + // between the two messages exceeds window and then group current + // message with the last one const timeOfLastMessage = lastMessage.content[lastMessage.content.length - 1].time; + const isOrWasPoll = currentMessage.message.includes(POLL_MESSAGE_PREFIX) + || lastMessage.message.includes(POLL_MESSAGE_PREFIX); + const groupingWindow = isOrWasPoll ? 0 : GROUPING_MESSAGES_WINDOW; + if (lastMessage.sender === currentMessage.sender - && (currentMessage.timestamp - timeOfLastMessage) <= GROUPING_MESSAGES_WINDOW) { + && (currentMessage.timestamp - timeOfLastMessage) <= groupingWindow) { lastMessage.content.push(currentMessage.content.pop()); return previous; } diff --git a/bigbluebutton-html5/imports/ui/components/poll/service.js b/bigbluebutton-html5/imports/ui/components/poll/service.js index bd85398252..5e31719c7c 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/service.js +++ b/bigbluebutton-html5/imports/ui/components/poll/service.js @@ -59,7 +59,7 @@ const sendGroupMessage = (message) => { color: '0', correlationId: `${PUBLIC_CHAT_SYSTEM_ID}-${Date.now()}`, sender: { - id: PUBLIC_CHAT_SYSTEM_ID, + id: Auth.userID, name: '', }, message, @@ -69,9 +69,12 @@ const sendGroupMessage = (message) => { }; export default { - amIPresenter: () => Users.findOne({ userId: Auth.userID }, { fields: { presenter: 1 } }).presenter, + amIPresenter: () => Users.findOne( + { userId: Auth.userID }, + { fields: { presenter: 1 } }, + ).presenter, pollTypes, - stopPoll: () => makeCall('stopPoll', Auth.userId), + stopPoll: () => makeCall('stopPoll', Auth.userID), currentPoll: () => Polls.findOne({ meetingId: Auth.meetingID }), pollAnswerIds, sendGroupMessage, From 6872a07d04a1507b5ef762f04c457d17cd1b3d67 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Tue, 28 Jul 2020 19:22:05 +0000 Subject: [PATCH 2/2] fix chat poll result calculation to match whiteboard --- .../ui/components/poll/live-result/component.jsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/poll/live-result/component.jsx b/bigbluebutton-html5/imports/ui/components/poll/live-result/component.jsx index 1070f02870..0aa6f2ace9 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/live-result/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/poll/live-result/component.jsx @@ -194,12 +194,15 @@ class LiveResult extends PureComponent { Session.set('pollInitiated', false); Service.publishPoll(); const { answers, numRespondents } = currentPoll; - + let responded = 0; let resultString = 'bbb-published-poll-\n'; - answers.forEach((item) => { - const pct = Math.round(item.numVotes / numRespondents * 100); + answers.map((item) => { + responded += item.numVotes; + return item; + }).map((item) => { + const numResponded = responded === numRespondents ? numRespondents : responded; + const pct = Math.round(item.numVotes / numResponded * 100); const pctFotmatted = `${Number.isNaN(pct) ? 0 : pct}%`; - resultString += `${item.key}: ${item.numVotes || 0} | ${pctFotmatted}\n`; });