2023-11-23 04:01:18 +08:00
|
|
|
import React from 'react';
|
2023-03-10 19:30:46 +08:00
|
|
|
import PropTypes from 'prop-types';
|
2019-05-10 01:44:54 +08:00
|
|
|
import { notify } from '/imports/ui/services/notification';
|
2021-06-09 21:49:59 +08:00
|
|
|
import Presentation from '/imports/ui/components/presentation/component';
|
2019-07-18 08:30:28 +08:00
|
|
|
import PresentationToolbarService from './presentation-toolbar/service';
|
2020-05-12 20:58:14 +08:00
|
|
|
import Auth from '/imports/ui/services/auth';
|
|
|
|
import getFromUserSettings from '/imports/ui/services/users-settings';
|
2021-09-11 04:48:52 +08:00
|
|
|
import {
|
|
|
|
layoutSelect,
|
|
|
|
layoutSelectInput,
|
|
|
|
layoutSelectOutput,
|
|
|
|
layoutDispatch,
|
|
|
|
} from '../layout/context';
|
2021-03-05 06:26:25 +08:00
|
|
|
import WhiteboardService from '/imports/ui/components/whiteboard/service';
|
2021-08-04 19:42:38 +08:00
|
|
|
import { DEVICE_TYPE } from '../layout/enums';
|
2023-01-24 21:05:49 +08:00
|
|
|
import MediaService from '../media/service';
|
2023-09-29 22:58:16 +08:00
|
|
|
import { useSubscription } from '@apollo/client';
|
|
|
|
import {
|
|
|
|
CURRENT_PRESENTATION_PAGE_SUBSCRIPTION,
|
2023-10-03 03:16:46 +08:00
|
|
|
CURRENT_PAGE_WRITERS_SUBSCRIPTION,
|
2023-09-29 22:58:16 +08:00
|
|
|
} from '/imports/ui/components/whiteboard/queries';
|
2023-10-03 03:16:46 +08:00
|
|
|
import POLL_SUBSCRIPTION from '/imports/ui/core/graphql/queries/pollSubscription';
|
2023-10-03 21:24:38 +08:00
|
|
|
import useMeeting from '/imports/ui/core/hooks/useMeeting';
|
2023-11-23 04:01:18 +08:00
|
|
|
import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser';
|
2020-05-12 20:58:14 +08:00
|
|
|
|
2023-10-04 20:23:24 +08:00
|
|
|
const APP_CONFIG = Meteor.settings.public.app;
|
|
|
|
const PRELOAD_NEXT_SLIDE = APP_CONFIG.preloadNextSlides;
|
|
|
|
const fetchedpresentation = {};
|
|
|
|
|
|
|
|
const PresentationContainer = (props) => {
|
|
|
|
const { data: presentationPageData } = useSubscription(CURRENT_PRESENTATION_PAGE_SUBSCRIPTION);
|
|
|
|
const { pres_page_curr: presentationPageArray } = (presentationPageData || {});
|
|
|
|
const currentPresentationPage = presentationPageArray && presentationPageArray[0];
|
2023-10-18 00:49:23 +08:00
|
|
|
const slideSvgUrl = currentPresentationPage && currentPresentationPage.svgUrl;
|
2023-10-04 20:23:24 +08:00
|
|
|
|
|
|
|
const { data: whiteboardWritersData } = useSubscription(CURRENT_PAGE_WRITERS_SUBSCRIPTION);
|
|
|
|
const whiteboardWriters = whiteboardWritersData?.pres_page_writers || [];
|
|
|
|
|
|
|
|
const meeting = useMeeting((m) => ({
|
|
|
|
lockSettings: m?.lockSettings,
|
|
|
|
}));
|
|
|
|
|
2023-10-26 20:35:34 +08:00
|
|
|
const isViewersAnnotationsLocked = meeting ? meeting.lockSettings?.hideViewersAnnotation : true;
|
2023-10-04 21:49:59 +08:00
|
|
|
|
2023-10-04 20:23:24 +08:00
|
|
|
const multiUserData = {
|
|
|
|
active: whiteboardWriters?.length > 0,
|
|
|
|
size: whiteboardWriters?.length || 0,
|
|
|
|
hasAccess: whiteboardWriters?.some((writer) => writer.userId === Auth.userID),
|
|
|
|
};
|
|
|
|
|
|
|
|
const { data: pollData } = useSubscription(POLL_SUBSCRIPTION);
|
|
|
|
const poll = pollData?.poll[0] || {};
|
|
|
|
|
|
|
|
const currentSlide = currentPresentationPage ? {
|
|
|
|
content: currentPresentationPage.content,
|
|
|
|
current: currentPresentationPage.isCurrentPage,
|
|
|
|
height: currentPresentationPage.height,
|
|
|
|
width: currentPresentationPage.width,
|
|
|
|
id: currentPresentationPage.pageId,
|
2023-10-18 00:49:23 +08:00
|
|
|
imageUri: slideSvgUrl,
|
2023-10-04 20:23:24 +08:00
|
|
|
num: currentPresentationPage?.num,
|
|
|
|
presentationId: currentPresentationPage?.presentationId,
|
2023-10-18 00:49:23 +08:00
|
|
|
svgUri: slideSvgUrl,
|
2023-10-04 20:23:24 +08:00
|
|
|
} : null;
|
|
|
|
|
|
|
|
let slidePosition;
|
|
|
|
if (currentSlide) {
|
|
|
|
const { presentationId } = currentSlide;
|
|
|
|
|
|
|
|
slidePosition = {
|
|
|
|
height: currentPresentationPage.scaledHeight,
|
|
|
|
id: currentPresentationPage.pageId,
|
|
|
|
presentationId: currentPresentationPage.presentationId,
|
|
|
|
viewBoxHeight: currentPresentationPage.scaledViewBoxHeight,
|
|
|
|
viewBoxWidth: currentPresentationPage.scaledViewBoxWidth,
|
|
|
|
width: currentPresentationPage.scaledWidth,
|
|
|
|
x: currentPresentationPage.xOffset,
|
|
|
|
y: currentPresentationPage.yOffset,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (PRELOAD_NEXT_SLIDE && !fetchedpresentation[presentationId]) {
|
|
|
|
fetchedpresentation[presentationId] = {
|
|
|
|
canFetch: true,
|
|
|
|
fetchedSlide: {},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
const presentation = fetchedpresentation[presentationId];
|
|
|
|
|
|
|
|
if (PRELOAD_NEXT_SLIDE
|
|
|
|
&& !presentation.fetchedSlide[currentSlide.num + PRELOAD_NEXT_SLIDE]
|
|
|
|
&& presentation.canFetch) {
|
|
|
|
// TODO: preload next slides should be reimplemented in graphql
|
|
|
|
const slidesToFetch = [currentPresentationPage];
|
|
|
|
|
|
|
|
const promiseImageGet = slidesToFetch
|
|
|
|
.filter((s) => !fetchedpresentation[presentationId].fetchedSlide[s.num])
|
|
|
|
.map(async (slide) => {
|
|
|
|
if (presentation.canFetch) presentation.canFetch = false;
|
2023-10-18 00:49:23 +08:00
|
|
|
const image = await fetch(slide.svgUrl);
|
2023-10-04 20:23:24 +08:00
|
|
|
if (image.ok) {
|
|
|
|
presentation.fetchedSlide[slide.num] = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Promise.all(promiseImageGet).then(() => {
|
|
|
|
presentation.canFetch = true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const { presentationIsOpen } = props;
|
|
|
|
|
2021-09-11 04:48:52 +08:00
|
|
|
const cameraDock = layoutSelectInput((i) => i.cameraDock);
|
|
|
|
const presentation = layoutSelectOutput((i) => i.presentation);
|
|
|
|
const fullscreen = layoutSelect((i) => i.fullscreen);
|
|
|
|
const deviceType = layoutSelect((i) => i.deviceType);
|
|
|
|
const layoutContextDispatch = layoutDispatch();
|
2021-09-10 21:16:44 +08:00
|
|
|
|
2021-08-05 15:26:03 +08:00
|
|
|
const { numCameras } = cameraDock;
|
2021-07-13 03:47:06 +08:00
|
|
|
const { element } = fullscreen;
|
2021-09-10 21:16:44 +08:00
|
|
|
const fullscreenElementId = 'Presentation';
|
2021-07-06 19:28:17 +08:00
|
|
|
const fullscreenContext = (element === fullscreenElementId);
|
2021-09-10 21:16:44 +08:00
|
|
|
|
2021-08-28 02:32:56 +08:00
|
|
|
const isIphone = !!(navigator.userAgent.match(/iPhone/i));
|
2021-04-20 01:54:14 +08:00
|
|
|
|
2023-11-23 04:01:18 +08:00
|
|
|
const { data: currentUser } = useCurrentUser((user) => ({
|
|
|
|
presenter: user.presenter,
|
|
|
|
}));
|
|
|
|
const userIsPresenter = currentUser?.presenter;
|
2021-04-20 01:54:14 +08:00
|
|
|
|
2023-10-12 20:32:24 +08:00
|
|
|
const presentationAreaSize = {
|
|
|
|
presentationAreaWidth: presentation?.width,
|
|
|
|
presentationAreaHeight: presentation?.height,
|
|
|
|
};
|
|
|
|
|
2021-08-24 05:04:16 +08:00
|
|
|
return (
|
|
|
|
<Presentation
|
|
|
|
{
|
|
|
|
...{
|
|
|
|
layoutContextDispatch,
|
|
|
|
numCameras,
|
|
|
|
...props,
|
2022-02-10 03:45:43 +08:00
|
|
|
userIsPresenter,
|
2021-08-24 05:04:16 +08:00
|
|
|
presentationBounds: presentation,
|
|
|
|
fullscreenContext,
|
|
|
|
fullscreenElementId,
|
2021-08-28 02:37:19 +08:00
|
|
|
isMobile: deviceType === DEVICE_TYPE.MOBILE,
|
|
|
|
isIphone,
|
2023-09-29 22:58:16 +08:00
|
|
|
currentSlide,
|
2023-10-04 21:49:59 +08:00
|
|
|
slidePosition,
|
2023-11-06 21:35:55 +08:00
|
|
|
downloadPresentationUri: `${APP_CONFIG.bbbWebBase}/${currentPresentationPage?.downloadFileUri}`,
|
2023-10-04 21:49:59 +08:00
|
|
|
multiUser: (multiUserData.hasAccess || multiUserData.active) && presentationIsOpen,
|
|
|
|
presentationIsDownloadable: currentPresentationPage?.downloadable,
|
|
|
|
mountPresentation: !!currentSlide,
|
|
|
|
currentPresentationId: currentPresentationPage?.presentationId,
|
2023-10-20 21:15:47 +08:00
|
|
|
totalPages: currentPresentationPage?.totalPages || 0,
|
2023-10-04 21:49:59 +08:00
|
|
|
notify,
|
|
|
|
zoomSlide: PresentationToolbarService.zoomSlide,
|
|
|
|
publishedPoll: poll?.published || false,
|
|
|
|
restoreOnUpdate: getFromUserSettings(
|
|
|
|
'bbb_force_restore_presentation_on_new_events',
|
|
|
|
Meteor.settings.public.presentation.restoreOnUpdate,
|
|
|
|
),
|
|
|
|
addWhiteboardGlobalAccess: WhiteboardService.addGlobalAccess,
|
|
|
|
removeWhiteboardGlobalAccess: WhiteboardService.removeGlobalAccess,
|
|
|
|
multiUserSize: multiUserData.size,
|
|
|
|
isViewersAnnotationsLocked,
|
|
|
|
setPresentationIsOpen: MediaService.setPresentationIsOpen,
|
|
|
|
isDefaultPresentation: currentPresentationPage?.isDefaultPresentation,
|
|
|
|
presentationName: currentPresentationPage?.presentationName,
|
2023-10-12 20:32:24 +08:00
|
|
|
presentationAreaSize,
|
2021-08-24 05:04:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
);
|
2021-04-07 03:58:11 +08:00
|
|
|
};
|
2016-05-04 04:40:46 +08:00
|
|
|
|
2023-10-04 20:23:24 +08:00
|
|
|
export default PresentationContainer;
|
2023-03-10 19:30:46 +08:00
|
|
|
|
|
|
|
PresentationContainer.propTypes = {
|
|
|
|
presentationIsOpen: PropTypes.bool.isRequired,
|
|
|
|
};
|