record notify modal
This commit is contained in:
parent
cc54f167f7
commit
35ae2a9e77
@ -56,6 +56,7 @@ export default function addMeeting(meeting) {
|
|||||||
learningDashboardEnabled: Boolean,
|
learningDashboardEnabled: Boolean,
|
||||||
name: String,
|
name: String,
|
||||||
disabledFeatures: Array,
|
disabledFeatures: Array,
|
||||||
|
remindRecordingIsOn: Boolean,
|
||||||
},
|
},
|
||||||
usersProp: {
|
usersProp: {
|
||||||
webcamsOnlyForModerator: Boolean,
|
webcamsOnlyForModerator: Boolean,
|
||||||
|
@ -45,7 +45,6 @@ import Settings from '/imports/ui/services/settings';
|
|||||||
import LayoutService from '/imports/ui/components/layout/service';
|
import LayoutService from '/imports/ui/components/layout/service';
|
||||||
import { registerTitleView } from '/imports/utils/dom-utils';
|
import { registerTitleView } from '/imports/utils/dom-utils';
|
||||||
import GlobalStyles from '/imports/ui/stylesheets/styled-components/globalStyles';
|
import GlobalStyles from '/imports/ui/stylesheets/styled-components/globalStyles';
|
||||||
import ModalConsentContainer from '../modal-consent/container';
|
|
||||||
|
|
||||||
const MOBILE_MEDIA = 'only screen and (max-width: 40em)';
|
const MOBILE_MEDIA = 'only screen and (max-width: 40em)';
|
||||||
const APP_CONFIG = Meteor.settings.public.app;
|
const APP_CONFIG = Meteor.settings.public.app;
|
||||||
@ -467,7 +466,6 @@ class App extends Component {
|
|||||||
height: '100%',
|
height: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ModalConsentContainer/>
|
|
||||||
{this.renderActivityCheck()}
|
{this.renderActivityCheck()}
|
||||||
{this.renderUserInformation()}
|
{this.renderUserInformation()}
|
||||||
<BannerBarContainer />
|
<BannerBarContainer />
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
|
||||||
import style from './style.scss';
|
|
||||||
import { makeCall } from '/imports/ui/services/api';
|
|
||||||
import getValueFromKeyObj from './utils/getValueFromKeyObj';
|
|
||||||
|
|
||||||
const intlMessages = defineMessages({
|
|
||||||
title: {
|
|
||||||
id: 'app.consent.title',
|
|
||||||
description: 'Title Modal Con sent',
|
|
||||||
},
|
|
||||||
desc: {
|
|
||||||
id: 'app.consent.desc',
|
|
||||||
description: 'Question for accept or not meeting be recorded',
|
|
||||||
},
|
|
||||||
buttonyes: {
|
|
||||||
id: 'app.consent.buttonyes',
|
|
||||||
description: 'Button accept',
|
|
||||||
|
|
||||||
},
|
|
||||||
buttonreject: {
|
|
||||||
id: 'app.consent.buttonreject',
|
|
||||||
description: 'Button accept',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const ModalConsent = ({ recMeetingsCollection, intl, meetingsCollection }) => {
|
|
||||||
const [continueModal, setContinueModal] = React.useState(false);
|
|
||||||
|
|
||||||
const allowRecord = getValueFromKeyObj(
|
|
||||||
'record',
|
|
||||||
recMeetingsCollection[0],
|
|
||||||
);
|
|
||||||
|
|
||||||
const { isBreakout } = getValueFromKeyObj(
|
|
||||||
'meetingProp',
|
|
||||||
meetingsCollection[0],
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
|
||||||
!allowRecord// if meeting is not able to record
|
|
||||||
|| !Meteor.settings.public.app.requireAdditionalRecordingConsentOnJoin
|
|
||||||
|| continueModal // if clicked in continue
|
|
||||||
|| isBreakout // if is breackout (because user already accept before)
|
|
||||||
) return null;
|
|
||||||
|
|
||||||
const LOGOUT_CODE = '680';
|
|
||||||
function skipButtonHandle() {
|
|
||||||
makeCall('userLeftMeeting');
|
|
||||||
Session.set('codeError', LOGOUT_CODE);
|
|
||||||
setContinueModal(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className={style.overlay}>
|
|
||||||
<div className={style.modal}>
|
|
||||||
|
|
||||||
<h1>{intl.formatMessage(intlMessages.title)}</h1>
|
|
||||||
<p>{intl.formatMessage(intlMessages.desc)}</p>
|
|
||||||
<div className={style.divButtons}>
|
|
||||||
|
|
||||||
<button type="button" onClick={() => setContinueModal(true)} className={style.continue}>
|
|
||||||
{intl.formatMessage(intlMessages.buttonyes)}
|
|
||||||
</button>
|
|
||||||
<button type="button" onClick={skipButtonHandle} className={style.skip}>
|
|
||||||
{intl.formatMessage(intlMessages.buttonreject)}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default injectIntl(ModalConsent);
|
|
@ -1,13 +0,0 @@
|
|||||||
import { withTracker } from 'meteor/react-meteor-data';
|
|
||||||
import ModalConsent from './component';
|
|
||||||
import { RecordMeetings } from '/imports/api/meetings';
|
|
||||||
import Meetings from '../../../api/meetings/index';
|
|
||||||
|
|
||||||
export default withTracker(() => {
|
|
||||||
const recMeetingsCollection = RecordMeetings.find().fetch();
|
|
||||||
const meetingsCollection = Meetings.find().fetch();
|
|
||||||
return {
|
|
||||||
recMeetingsCollection,
|
|
||||||
meetingsCollection,
|
|
||||||
};
|
|
||||||
})(ModalConsent);
|
|
@ -1,108 +0,0 @@
|
|||||||
.overlay{
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
background-color: rgba(0, 0, 0, 0.322);
|
|
||||||
z-index: 10000;
|
|
||||||
overflow: visible;
|
|
||||||
position: fixed;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
}
|
|
||||||
@keyframes up_modal {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-10px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal {
|
|
||||||
padding: 0.625em 3.125em 0.625em 3.125em;
|
|
||||||
width: 60%;
|
|
||||||
height: 18.75em;
|
|
||||||
background-color: rgb(250, 252, 255);
|
|
||||||
background-color: var( --color-off-white);
|
|
||||||
border-radius: 0.3125em;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
animation: up_modal 0.3s ease
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal p{
|
|
||||||
padding: 0em;
|
|
||||||
margin: 0em;
|
|
||||||
margin-bottom: 1.25em;
|
|
||||||
font-size: 1.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.continue{
|
|
||||||
padding: 0.625em 1.875em 0.625em 1.875em;
|
|
||||||
background-color: var(--color-primary);
|
|
||||||
border: none;
|
|
||||||
border-radius: 0.3125em;
|
|
||||||
color: white;
|
|
||||||
font-size: 1.1em;
|
|
||||||
margin-right: 0.7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skip{
|
|
||||||
padding: 0.625em 1.875em 0.625em 1.875em;
|
|
||||||
background-color: var(--color-blue-lightest);
|
|
||||||
border: none;
|
|
||||||
border-radius: 0.3125em;
|
|
||||||
color: var(--color-gray);
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.divButtons{
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divButtons button{
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divButtons button:hover{
|
|
||||||
transform: scale3d(1.05, 1.05, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 940px)
|
|
||||||
{
|
|
||||||
.modal h1
|
|
||||||
{
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divButtons{
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divButtons button{
|
|
||||||
width: 100%;
|
|
||||||
margin: 0.3125em;
|
|
||||||
padding: 0.625em 1.875em 0.625em 1.875em;
|
|
||||||
}
|
|
||||||
.modal{
|
|
||||||
width: 70%;
|
|
||||||
height: 90vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.continue{
|
|
||||||
margin-right: 03em;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
export default function getValueFromKeyObj(chaveObj, obj){
|
|
||||||
let existKey = Object.keys(obj).filter(function(key){
|
|
||||||
return key === chaveObj
|
|
||||||
})
|
|
||||||
|
|
||||||
if(existKey){
|
|
||||||
return obj[existKey]
|
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { withModalMounter } from '/imports/ui/components/common/modal/service';
|
import { withModalMounter, getModal } from '/imports/ui/components/common/modal/service';
|
||||||
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
|
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import Styled from './styles';
|
import Styled from './styles';
|
||||||
@ -235,6 +235,7 @@ class NavBar extends Component {
|
|||||||
</Styled.PresentationTitle>
|
</Styled.PresentationTitle>
|
||||||
<RecordingIndicator
|
<RecordingIndicator
|
||||||
mountModal={mountModal}
|
mountModal={mountModal}
|
||||||
|
getModal={getModal}
|
||||||
amIModerator={amIModerator}
|
amIModerator={amIModerator}
|
||||||
/>
|
/>
|
||||||
</Styled.Center>
|
</Styled.Center>
|
||||||
|
@ -5,6 +5,7 @@ import Tooltip from '/imports/ui/components/common/tooltip/component';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import Styled from './styles';
|
import Styled from './styles';
|
||||||
|
import RecordingNotifyContainer from './notify/container';
|
||||||
|
|
||||||
const intlMessages = defineMessages({
|
const intlMessages = defineMessages({
|
||||||
notificationRecordingStart: {
|
notificationRecordingStart: {
|
||||||
@ -67,19 +68,47 @@ class RecordingIndicator extends PureComponent {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
time: (props.time ? props.time : 0),
|
time: (props.time ? props.time : 0),
|
||||||
|
shouldNotify: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.incrementTime = this.incrementTime.bind(this);
|
this.incrementTime = this.incrementTime.bind(this);
|
||||||
|
this.toggleShouldNotify = this.toggleShouldNotify.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
toggleShouldNotify() {
|
||||||
|
const { shouldNotify } = this.state;
|
||||||
|
this.setState({shouldNotify: !shouldNotify});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
const { recording } = this.props;
|
const { recording } = this.props;
|
||||||
|
|
||||||
|
if (recording) {
|
||||||
|
this.toggleShouldNotify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
const { recording, mountModal, getModal } = this.props;
|
||||||
|
const { shouldNotify } = this.state;
|
||||||
|
|
||||||
if (!recording) {
|
if (!recording) {
|
||||||
clearInterval(this.interval);
|
clearInterval(this.interval);
|
||||||
this.interval = null;
|
this.interval = null;
|
||||||
} else if (this.interval === null) {
|
} else if (this.interval === null) {
|
||||||
this.interval = setInterval(this.incrementTime, 1000);
|
this.interval = setInterval(this.incrementTime, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!prevProps.recording && recording && !shouldNotify) {
|
||||||
|
return this.setState({shouldNotify: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
const isModalOpen = !!getModal();
|
||||||
|
|
||||||
|
// should only display notification modal when other modals are closed
|
||||||
|
if (shouldNotify && !isModalOpen) {
|
||||||
|
mountModal(<RecordingNotifyContainer toggleShouldNotify={this.toggleShouldNotify} />);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
incrementTime() {
|
incrementTime() {
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
import { makeCall } from '/imports/ui/services/api';
|
||||||
|
import Styled from './styles';
|
||||||
|
|
||||||
|
const intlMessages = defineMessages({
|
||||||
|
title: {
|
||||||
|
id: 'app.recording.notify.title',
|
||||||
|
description: 'Title Modal Con sent',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
id: 'app.recording.notify.description',
|
||||||
|
description: 'Question for accept or not meeting be recorded',
|
||||||
|
},
|
||||||
|
continue: {
|
||||||
|
id: 'app.recording.notify.continue',
|
||||||
|
description: 'Button accept',
|
||||||
|
|
||||||
|
},
|
||||||
|
leave: {
|
||||||
|
id: 'app.recording.notify.leave',
|
||||||
|
description: 'Button accept',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const LOGOUT_CODE = '680';
|
||||||
|
|
||||||
|
const RecordingNotifyModal = ({ intl, closeModal, toggleShouldNotify }) => {
|
||||||
|
function skipButtonHandle() {
|
||||||
|
makeCall('userLeftMeeting');
|
||||||
|
Session.set('codeError', LOGOUT_CODE);
|
||||||
|
toggleShouldNotify();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Styled.RecordingNotifyModal
|
||||||
|
hideBorder
|
||||||
|
contentLabel={intl.formatMessage(intlMessages.title)}
|
||||||
|
shouldShowCloseButton={false}
|
||||||
|
>
|
||||||
|
<Styled.Container>
|
||||||
|
<Styled.Header>
|
||||||
|
<Styled.Title>
|
||||||
|
{intl.formatMessage(intlMessages.title)}
|
||||||
|
</Styled.Title>
|
||||||
|
</Styled.Header>
|
||||||
|
<Styled.Description>
|
||||||
|
{intl.formatMessage(intlMessages.description)}
|
||||||
|
</Styled.Description>
|
||||||
|
<Styled.Footer>
|
||||||
|
<Styled.NotifyButton
|
||||||
|
color="primary"
|
||||||
|
label={intl.formatMessage(intlMessages.continue)}
|
||||||
|
onClick={closeModal}
|
||||||
|
/>
|
||||||
|
<Styled.NotifyButton
|
||||||
|
label={intl.formatMessage(intlMessages.leave)}
|
||||||
|
onClick={skipButtonHandle}
|
||||||
|
/>
|
||||||
|
</Styled.Footer>
|
||||||
|
</Styled.Container>
|
||||||
|
</Styled.RecordingNotifyModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(RecordingNotifyModal);
|
@ -0,0 +1,12 @@
|
|||||||
|
import { withTracker } from 'meteor/react-meteor-data';
|
||||||
|
import { withModalMounter } from '/imports/ui/components/common/modal/service';
|
||||||
|
import RecordingNotifyModal from './component';
|
||||||
|
|
||||||
|
export default withModalMounter(withTracker(({ mountModal, toggleShouldNotify}) => {
|
||||||
|
return {
|
||||||
|
closeModal: () => {
|
||||||
|
toggleShouldNotify();
|
||||||
|
mountModal(null);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})(RecordingNotifyModal));
|
@ -0,0 +1,29 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import Modal from '/imports/ui/components/common/modal/simple/component';
|
||||||
|
import RecordingModalStyles from '/imports/ui/components/recording/styles';
|
||||||
|
|
||||||
|
const RecordingNotifyModal = styled(Modal)``;
|
||||||
|
|
||||||
|
const Container = styled(RecordingModalStyles.Container)`
|
||||||
|
padding: 3.625em 0 3.625em 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Header = styled(RecordingModalStyles.Header)``;
|
||||||
|
|
||||||
|
const Title = styled(RecordingModalStyles.Title)``;
|
||||||
|
|
||||||
|
const Description = styled(RecordingModalStyles.Description)``;
|
||||||
|
|
||||||
|
const Footer = styled(RecordingModalStyles.Footer)``;
|
||||||
|
|
||||||
|
const NotifyButton = styled(RecordingModalStyles.RecordingButton)``;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
RecordingNotifyModal,
|
||||||
|
Container,
|
||||||
|
Header,
|
||||||
|
Title,
|
||||||
|
Description,
|
||||||
|
Footer,
|
||||||
|
NotifyButton,
|
||||||
|
};
|
@ -726,6 +726,10 @@
|
|||||||
"app.recording.resumeTitle": "Resume recording",
|
"app.recording.resumeTitle": "Resume recording",
|
||||||
"app.recording.startDescription": "You can select the record button again later to pause the recording.",
|
"app.recording.startDescription": "You can select the record button again later to pause the recording.",
|
||||||
"app.recording.stopDescription": "Are you sure you want to pause the recording? You can resume by selecting the record button again.",
|
"app.recording.stopDescription": "Are you sure you want to pause the recording? You can resume by selecting the record button again.",
|
||||||
|
"app.recording.notify.title": "Recording has started",
|
||||||
|
"app.recording.notify.description": "A recording will be available based on the remainder of this session",
|
||||||
|
"app.recording.notify.continue": "Continue",
|
||||||
|
"app.recording.notify.leave": "Leave session",
|
||||||
"app.videoPreview.cameraLabel": "Camera",
|
"app.videoPreview.cameraLabel": "Camera",
|
||||||
"app.videoPreview.profileLabel": "Quality",
|
"app.videoPreview.profileLabel": "Quality",
|
||||||
"app.videoPreview.quality.low": "Low",
|
"app.videoPreview.quality.low": "Low",
|
||||||
|
Loading…
Reference in New Issue
Block a user