Merge remote-tracking branch 'upstream/v2.5.x-release' into oct18

This commit is contained in:
Ramón Souza 2022-10-18 17:13:33 -03:00
commit d3cfe305b0
4 changed files with 169 additions and 114 deletions

View File

@ -1291,19 +1291,34 @@ check_state() {
if [ ! -z "$STUN" ]; then
for i in $STUN; do
STUN_SERVER="$(xmlstarlet sel -N x="http://www.springframework.org/schema/beans" -t -m "_:beans/_:bean[@id=\"$i\"]/_:constructor-arg[@index=\"0\"]" -v @value $TURN | sed 's/stun://g')"
if echo $STUN_SERVER | grep -q ':'; then
STUN_SERVER="$(echo $STUN_SERVER | sed 's/:.*//g') $(echo $STUN_SERVER | sed 's/.*://g')"
else
STUN_SERVER="$STUN_SERVER 3478"
fi
if which stunclient > /dev/null 2>&1; then
if stunclient --mode full --localport 30000 $STUN_SERVER | grep -q "fail\|Unable\ to\ resolve"; then
# stun is from the stun-client package, which is available on both bionic and focal
# stunclient is from the stuntman-client package, which is available on bionic but was removed from focal
if which stun > /dev/null 2>&1; then
# stun return codes, from its client.cxx
# low nibble: open (0), various STUN combinations (2-9), firewall (a), blocked (c), unknown (e), error (f)
# high nibble: hairpin (1)
stun $STUN_SERVER > /dev/null
if (( ($? & 0xf) > 9 )); then
echo
echo "#"
echo "# Warning: Failed to verify STUN server at $STUN_SERVER with command"
echo "#"
echo "# stunclient --mode full --localport 30000 $STUN_SERVER"
echo "# stun $STUN_SERVER"
echo "#"
fi
elif which stunclient > /dev/null 2>&1; then
if echo $STUN_SERVER | grep -q ':'; then
STUN_SERVER="$(echo $STUN_SERVER | sed 's/:.*//g') $(echo $STUN_SERVER | sed 's/.*://g')"
else
STUN_SERVER="$STUN_SERVER 3478"
fi
if stunclient $STUN_SERVER | grep -q "fail\|Unable\ to\ resolve"; then
echo
echo "#"
echo "# Warning: Failed to verify STUN server at $STUN_SERVER with command"
echo "#"
echo "# stunclient $STUN_SERVER"
echo "#"
fi
fi

View File

@ -61,6 +61,18 @@ const QuickPollDropdown = (props) => {
pollTypes,
} = props;
const parsedSlide = parseCurrentSlideContent(
intl.formatMessage(intlMessages.yesOptionLabel),
intl.formatMessage(intlMessages.noOptionLabel),
intl.formatMessage(intlMessages.abstentionOptionLabel),
intl.formatMessage(intlMessages.trueOptionLabel),
intl.formatMessage(intlMessages.falseOptionLabel),
);
const {
slideId, quickPollOptions, optionsWithLabels, pollQuestion,
} = parsedSlide;
const handleClickQuickPoll = (lCDispatch) => {
lCDispatch({
type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN,
@ -131,7 +143,7 @@ const QuickPollDropdown = (props) => {
key={_.uniqueId('quick-poll-item')}
onClick={() => {
handleClickQuickPoll(_layoutContextDispatch);
funcStartPoll(type, slideId, letterAnswers, '', pollData?.multiResp);
funcStartPoll(type, slideId, letterAnswers, pollQuestion, pollData?.multiResp);
}}
answers={letterAnswers}
multiResp={pollData?.multiResp}
@ -148,15 +160,6 @@ const QuickPollDropdown = (props) => {
});
};
const parsedSlide = parseCurrentSlideContent(
intl.formatMessage(intlMessages.yesOptionLabel),
intl.formatMessage(intlMessages.noOptionLabel),
intl.formatMessage(intlMessages.abstentionOptionLabel),
intl.formatMessage(intlMessages.trueOptionLabel),
intl.formatMessage(intlMessages.falseOptionLabel),
);
const { slideId, quickPollOptions } = parsedSlide;
const quickPolls = getAvailableQuickPolls(
slideId, quickPollOptions, startPoll, pollTypes, layoutContextDispatch,
);
@ -189,7 +192,17 @@ const QuickPollDropdown = (props) => {
tooltipLabel={intl.formatMessage(intlMessages.quickPollLabel)}
onClick={() => {
handleClickQuickPoll(layoutContextDispatch);
startPoll(singlePollType, currentSlide.id, answers, question, multiResponse);
if (singlePollType === 'R-' || singlePollType === 'TF') {
startPoll(singlePollType, currentSlide.id, answers, pollQuestion, multiResponse);
} else {
startPoll(
pollTypes.Custom,
currentSlide.id,
optionsWithLabels,
pollQuestion,
multiResponse,
);
}
}}
size="lg"
disabled={!!activePoll}

View File

@ -70,6 +70,18 @@ const intlMessages = defineMessages({
id: 'app.presentationUploder.title',
description: 'presentation area element label',
},
toolbarMultiUserOn: {
id: 'app.whiteboard.toolbar.multiUserOn',
description: 'Whiteboard toolbar turn multi-user on menu',
},
toolbarMultiUserOff: {
id: 'app.whiteboard.toolbar.multiUserOff',
description: 'Whiteboard toolbar turn multi-user off menu',
},
pan: {
id: 'app.whiteboard.toolbar.tools.hand',
description: 'presentation toolbar pan label',
},
});
class PresentationToolbar extends PureComponent {
@ -79,10 +91,11 @@ class PresentationToolbar extends PureComponent {
this.handleSkipToSlideChange = this.handleSkipToSlideChange.bind(this);
this.change = this.change.bind(this);
this.renderAriaDescs = this.renderAriaDescs.bind(this);
this.switchSlide = this.switchSlide.bind(this);
this.nextSlideHandler = this.nextSlideHandler.bind(this);
this.previousSlideHandler = this.previousSlideHandler.bind(this);
this.fullscreenToggleHandler = this.fullscreenToggleHandler.bind(this);
this.switchSlide = this.switchSlide.bind(this);
this.handleSwitchWhiteboardMode = this.handleSwitchWhiteboardMode.bind(this);
}
componentDidMount() {
@ -93,28 +106,6 @@ class PresentationToolbar extends PureComponent {
document.removeEventListener('keydown', this.switchSlide);
}
switchSlide(event) {
const { target, which } = event;
const isBody = target.nodeName === 'BODY';
if (isBody) {
switch (which) {
case KEY_CODES.ARROW_LEFT:
case KEY_CODES.PAGE_UP:
this.previousSlideHandler();
break;
case KEY_CODES.ARROW_RIGHT:
case KEY_CODES.PAGE_DOWN:
this.nextSlideHandler();
break;
case KEY_CODES.ENTER:
this.fullscreenToggleHandler();
break;
default:
}
}
}
handleSkipToSlideChange(event) {
const {
skipToSlide,
@ -126,27 +117,17 @@ class PresentationToolbar extends PureComponent {
skipToSlide(requestedSlideNum, podId);
}
nextSlideHandler(event) {
handleSwitchWhiteboardMode() {
const {
nextSlide,
currentSlideNum,
numberOfSlides,
podId,
multiUser,
whiteboardId,
removeWhiteboardGlobalAccess,
addWhiteboardGlobalAccess,
} = this.props;
if (event) event.currentTarget.blur();
nextSlide(currentSlideNum, numberOfSlides, podId);
}
previousSlideHandler(event) {
const {
previousSlide,
currentSlideNum,
podId,
} = this.props;
if (event) event.currentTarget.blur();
previousSlide(currentSlideNum, podId);
if (multiUser) {
return removeWhiteboardGlobalAccess(whiteboardId);
}
return addWhiteboardGlobalAccess(whiteboardId);
}
fullscreenToggleHandler() {
@ -171,6 +152,44 @@ class PresentationToolbar extends PureComponent {
});
}
nextSlideHandler(event) {
const {
nextSlide, currentSlideNum, numberOfSlides, podId,
} = this.props;
if (event) event.currentTarget.blur();
nextSlide(currentSlideNum, numberOfSlides, podId);
}
previousSlideHandler(event) {
const { previousSlide, currentSlideNum, podId } = this.props;
if (event) event.currentTarget.blur();
previousSlide(currentSlideNum, podId);
}
switchSlide(event) {
const { target, which } = event;
const isBody = target.nodeName === 'BODY';
if (isBody) {
switch (which) {
case KEY_CODES.ARROW_LEFT:
case KEY_CODES.PAGE_UP:
this.previousSlideHandler();
break;
case KEY_CODES.ARROW_RIGHT:
case KEY_CODES.PAGE_DOWN:
this.nextSlideHandler();
break;
case KEY_CODES.ENTER:
this.fullscreenToggleHandler();
break;
default:
}
}
}
change(value) {
const { zoomChanger } = this.props;
zoomChanger(value);
@ -211,15 +230,11 @@ class PresentationToolbar extends PureComponent {
const { intl } = this.props;
const optionList = [];
for (let i = 1; i <= numberOfSlides; i += 1) {
optionList.push((
<option
value={i}
key={i}
>
{
intl.formatMessage(intlMessages.goToSlide, { 0: i })
}
</option>));
optionList.push(
<option value={i} key={i}>
{intl.formatMessage(intlMessages.goToSlide, { 0: i })}
</option>
);
}
return optionList;
@ -250,11 +265,15 @@ class PresentationToolbar extends PureComponent {
const prevSlideAriaLabel = startOfSlides
? intl.formatMessage(intlMessages.previousSlideLabel)
: `${intl.formatMessage(intlMessages.previousSlideLabel)} (${currentSlideNum <= 1 ? '' : (currentSlideNum - 1)})`;
: `${intl.formatMessage(intlMessages.previousSlideLabel)} (${
currentSlideNum <= 1 ? '' : currentSlideNum - 1
})`;
const nextSlideAriaLabel = endOfSlides
? intl.formatMessage(intlMessages.nextSlideLabel)
: `${intl.formatMessage(intlMessages.nextSlideLabel)} (${currentSlideNum >= 1 ? (currentSlideNum + 1) : ''})`;
: `${intl.formatMessage(intlMessages.nextSlideLabel)} (${
currentSlideNum >= 1 ? currentSlideNum + 1 : ''
})`;
return (
<Styled.PresentationToolbarWrapper
@ -265,39 +284,37 @@ class PresentationToolbar extends PureComponent {
}
}>
{this.renderAriaDescs()}
{
<div>
{isPollingEnabled
? (
<Styled.QuickPollButton
{...{
currentSlidHasContent,
intl,
amIPresenter,
parseCurrentSlideContent,
startPoll,
currentSlide,
}}
/>
) : null
}
</div>
}
{
<Styled.PresentationSlideControls>
<Styled.PrevSlideButton
role="button"
aria-label={prevSlideAriaLabel}
aria-describedby={startOfSlides ? 'noPrevSlideDesc' : 'prevSlideDesc'}
disabled={startOfSlides || !isMeteorConnected}
color="default"
icon="left_arrow"
size="md"
onClick={this.previousSlideHandler}
label={intl.formatMessage(intlMessages.previousSlideLabel)}
hideLabel
data-test="prevSlide"
<div>
{isPollingEnabled ? (
<Styled.QuickPollButton
{...{
currentSlidHasContent,
intl,
amIPresenter,
parseCurrentSlideContent,
startPoll,
currentSlide,
}}
/>
) : null}
</div>
<Styled.PresentationSlideControls>
<Styled.PrevSlideButton
role="button"
aria-label={prevSlideAriaLabel}
aria-describedby={
startOfSlides ? 'noPrevSlideDesc' : 'prevSlideDesc'
}
disabled={startOfSlides || !isMeteorConnected}
color="light"
circle
icon="left_arrow"
size="md"
onClick={this.previousSlideHandler}
label={intl.formatMessage(intlMessages.previousSlideLabel)}
hideLabel
data-test="prevSlide"
/>
<TooltipContainer title={intl.formatMessage(intlMessages.selectLabel)}>
<Styled.SkipSlideSelect
@ -328,8 +345,6 @@ class PresentationToolbar extends PureComponent {
data-test="nextSlide"
/>
</Styled.PresentationSlideControls>
}
{
<Styled.PresentationZoomControls>
{
!isMobile
@ -368,7 +383,6 @@ class PresentationToolbar extends PureComponent {
hideLabel
/>
</Styled.PresentationZoomControls>
}
</Styled.PresentationToolbarWrapper>
);
}

View File

@ -85,14 +85,22 @@ const parseCurrentSlideContent = (yesValue, noValue, abstentionValue, trueValue,
} = currentSlide;
const questionRegex = /.*?\?$/gm;
let question = safeMatch(questionRegex, content, '');
const question = safeMatch(questionRegex, content, '');
const doubleQuestionRegex = /\?{2}/gm;
let doubleQuestion = safeMatch(doubleQuestionRegex, content, null);
const doubleQuestion = safeMatch(doubleQuestionRegex, content, false);
const pollRegex = /[1-9A-Ia-i][.)].*/g;
let optionsPoll = safeMatch(pollRegex, content, []);
if (optionsPoll) optionsPoll = optionsPoll.map((opt) => `\r${opt[0]}.`);
const optionsWithLabels = [];
if (optionsPoll) {
optionsPoll = optionsPoll.map((opt) => {
const MAX_CHAR_LIMIT = 30;
const formattedOpt = opt.substring(0, MAX_CHAR_LIMIT);
optionsWithLabels.push(formattedOpt);
return `\r${opt[0]}.`;
});
}
optionsPoll.reduce((acc, currentValue) => {
const lastElement = acc[acc.length - 1];
@ -129,7 +137,8 @@ const parseCurrentSlideContent = (yesValue, noValue, abstentionValue, trueValue,
return acc;
}, []).filter(({
options,
}) => options.length > 1 && options.length < 10).forEach((poll) => {
}) => options.length > 1 && options.length < 10).forEach((p) => {
const poll = p;
if (doubleQuestion) poll.multiResp = true;
if (poll.options.length <= 5 || MAX_CUSTOM_FIELDS <= 5) {
const maxAnswer = poll.options.length > MAX_CUSTOM_FIELDS
@ -149,10 +158,10 @@ const parseCurrentSlideContent = (yesValue, noValue, abstentionValue, trueValue,
if (question.length > 0 && optionsPoll.length === 0 && !doubleQuestion) {
quickPollOptions.push({
type: `R-`,
type: 'R-',
poll: {
question: question[0],
}
question: question[0],
},
});
}
@ -179,9 +188,13 @@ const parseCurrentSlideContent = (yesValue, noValue, abstentionValue, trueValue,
poll,
}));
const pollQuestion = (question?.length > 0 && question[0]?.replace(/ *\([^)]*\) */g, '')) || '';
return {
slideId: currentSlide.id,
quickPollOptions,
optionsWithLabels,
pollQuestion,
};
};