Merge remote-tracking branch 'upstream/v2.5.x-release' into oct18
This commit is contained in:
commit
d3cfe305b0
@ -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')"
|
||||
|
||||
# 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 "# 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 which stunclient > /dev/null 2>&1; then
|
||||
if stunclient --mode full --localport 30000 $STUN_SERVER | grep -q "fail\|Unable\ to\ resolve"; then
|
||||
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 --mode full --localport 30000 $STUN_SERVER"
|
||||
echo "# stunclient $STUN_SERVER"
|
||||
echo "#"
|
||||
fi
|
||||
fi
|
||||
|
@ -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}
|
||||
|
@ -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);
|
||||
if (multiUser) {
|
||||
return removeWhiteboardGlobalAccess(whiteboardId);
|
||||
}
|
||||
|
||||
previousSlideHandler(event) {
|
||||
const {
|
||||
previousSlide,
|
||||
currentSlideNum,
|
||||
podId,
|
||||
} = this.props;
|
||||
|
||||
if (event) event.currentTarget.blur();
|
||||
previousSlide(currentSlideNum, podId);
|
||||
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,10 +284,8 @@ class PresentationToolbar extends PureComponent {
|
||||
}
|
||||
}>
|
||||
{this.renderAriaDescs()}
|
||||
{
|
||||
<div>
|
||||
{isPollingEnabled
|
||||
? (
|
||||
{isPollingEnabled ? (
|
||||
<Styled.QuickPollButton
|
||||
{...{
|
||||
currentSlidHasContent,
|
||||
@ -279,18 +296,18 @@ class PresentationToolbar extends PureComponent {
|
||||
currentSlide,
|
||||
}}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
) : null}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
<Styled.PresentationSlideControls>
|
||||
<Styled.PrevSlideButton
|
||||
role="button"
|
||||
aria-label={prevSlideAriaLabel}
|
||||
aria-describedby={startOfSlides ? 'noPrevSlideDesc' : 'prevSlideDesc'}
|
||||
aria-describedby={
|
||||
startOfSlides ? 'noPrevSlideDesc' : 'prevSlideDesc'
|
||||
}
|
||||
disabled={startOfSlides || !isMeteorConnected}
|
||||
color="default"
|
||||
color="light"
|
||||
circle
|
||||
icon="left_arrow"
|
||||
size="md"
|
||||
onClick={this.previousSlideHandler}
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
@ -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],
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user