2024-01-16 03:49:09 +08:00
|
|
|
import React, { useState } from 'react';
|
|
|
|
import { defineMessages, useIntl } from 'react-intl';
|
2024-06-04 21:40:54 +08:00
|
|
|
import { useQuery } from '@apollo/client';
|
2024-01-16 03:49:09 +08:00
|
|
|
import BBBMenu from '/imports/ui/components/common/menu/component';
|
|
|
|
import Trigger from '/imports/ui/components/common/control-header/right/component';
|
|
|
|
import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser';
|
|
|
|
import { uniqueId } from '/imports/utils/string-utils';
|
|
|
|
import { layoutSelect } from '/imports/ui/components/layout/context';
|
|
|
|
import { PROCESSED_PRESENTATIONS_SUBSCRIPTION } from '/imports/ui/components/whiteboard/queries';
|
|
|
|
import Service from './service';
|
2024-02-14 03:39:45 +08:00
|
|
|
import { GET_PAD_ID, GetPadIdQueryResponse } from './queries';
|
2024-06-04 21:40:54 +08:00
|
|
|
import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription';
|
2024-01-16 03:49:09 +08:00
|
|
|
|
|
|
|
const DEBOUNCE_TIMEOUT = 15000;
|
|
|
|
|
|
|
|
const intlMessages = defineMessages({
|
|
|
|
convertAndUploadLabel: {
|
|
|
|
id: 'app.notes.notesDropdown.covertAndUpload',
|
|
|
|
description: 'Export shared notes as a PDF and upload to the main room',
|
|
|
|
},
|
|
|
|
pinNotes: {
|
|
|
|
id: 'app.notes.notesDropdown.pinNotes',
|
|
|
|
description: 'Label for pin shared notes button',
|
|
|
|
},
|
|
|
|
options: {
|
|
|
|
id: 'app.notes.notesDropdown.notesOptions',
|
|
|
|
description: 'Label for shared notes options',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
interface NotesDropdownContainerGraphqlProps {
|
|
|
|
handlePinSharedNotes: (pinned: boolean) => void
|
|
|
|
}
|
|
|
|
|
|
|
|
interface NotesDropdownGraphqlProps extends NotesDropdownContainerGraphqlProps {
|
|
|
|
amIPresenter: boolean;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
presentations: any;
|
|
|
|
isRTL: boolean;
|
2024-02-14 03:39:45 +08:00
|
|
|
padId: string;
|
2024-01-16 03:49:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const NotesDropdownGraphql: React.FC<NotesDropdownGraphqlProps> = (props) => {
|
|
|
|
const {
|
2024-02-14 03:39:45 +08:00
|
|
|
amIPresenter, presentations, handlePinSharedNotes, isRTL, padId,
|
2024-01-16 03:49:09 +08:00
|
|
|
} = props;
|
|
|
|
const [converterButtonDisabled, setConverterButtonDisabled] = useState(false);
|
|
|
|
const intl = useIntl();
|
2024-05-29 21:26:11 +08:00
|
|
|
const NOTES_IS_PINNABLE = window.meetingClientSettings.public.notes.pinnable;
|
2024-01-16 03:49:09 +08:00
|
|
|
|
|
|
|
const getAvailableActions = () => {
|
|
|
|
const uploadIcon = 'upload';
|
|
|
|
const pinIcon = 'presentation';
|
|
|
|
|
|
|
|
const menuItems = [];
|
|
|
|
|
|
|
|
if (amIPresenter) {
|
|
|
|
menuItems.push(
|
|
|
|
{
|
|
|
|
key: uniqueId('notes-option-'),
|
|
|
|
icon: uploadIcon,
|
|
|
|
dataTest: 'moveNotesToWhiteboard',
|
|
|
|
label: intl.formatMessage(intlMessages.convertAndUploadLabel),
|
|
|
|
disabled: converterButtonDisabled,
|
|
|
|
onClick: () => {
|
|
|
|
setConverterButtonDisabled(true);
|
|
|
|
setTimeout(() => setConverterButtonDisabled(false), DEBOUNCE_TIMEOUT);
|
2024-02-14 03:39:45 +08:00
|
|
|
return Service.convertAndUpload(presentations, padId);
|
2024-01-16 03:49:09 +08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (amIPresenter && NOTES_IS_PINNABLE) {
|
|
|
|
menuItems.push(
|
|
|
|
{
|
|
|
|
key: uniqueId('notes-option-'),
|
|
|
|
icon: pinIcon,
|
|
|
|
dataTest: 'pinNotes',
|
|
|
|
label: intl.formatMessage(intlMessages.pinNotes),
|
|
|
|
onClick: () => {
|
|
|
|
handlePinSharedNotes(true);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return menuItems;
|
|
|
|
};
|
|
|
|
|
|
|
|
const actions = getAvailableActions();
|
|
|
|
|
|
|
|
if (actions.length === 0) return null;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<BBBMenu
|
|
|
|
trigger={(
|
|
|
|
<Trigger
|
|
|
|
data-test="notesOptionsMenu"
|
|
|
|
icon="more"
|
|
|
|
label={intl.formatMessage(intlMessages.options)}
|
|
|
|
aria-label={intl.formatMessage(intlMessages.options)}
|
|
|
|
onClick={() => null}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
opts={{
|
|
|
|
id: 'notes-options-dropdown',
|
|
|
|
keepMounted: true,
|
|
|
|
transitionDuration: 0,
|
|
|
|
elevation: 3,
|
|
|
|
getcontentanchorel: null,
|
|
|
|
fullwidth: 'true',
|
|
|
|
anchorOrigin: { vertical: 'bottom', horizontal: isRTL ? 'right' : 'left' },
|
|
|
|
transformOrigin: { vertical: 'top', horizontal: isRTL ? 'right' : 'left' },
|
|
|
|
}}
|
|
|
|
actions={actions}
|
|
|
|
/>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const NotesDropdownContainerGraphql: React.FC<NotesDropdownContainerGraphqlProps> = (props) => {
|
|
|
|
const { handlePinSharedNotes } = props;
|
|
|
|
const { data: currentUserData } = useCurrentUser((user) => ({
|
|
|
|
presenter: user.presenter,
|
|
|
|
}));
|
|
|
|
const amIPresenter = !!currentUserData?.presenter;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
const isRTL = layoutSelect((i: any) => i.isRTL);
|
|
|
|
|
2024-06-04 21:40:54 +08:00
|
|
|
const { data: presentationData } = useDeduplicatedSubscription(PROCESSED_PRESENTATIONS_SUBSCRIPTION);
|
2024-01-16 03:49:09 +08:00
|
|
|
const presentations = presentationData?.pres_presentation || [];
|
|
|
|
|
2024-05-29 21:26:11 +08:00
|
|
|
const NOTES_CONFIG = window.meetingClientSettings.public.notes;
|
|
|
|
|
2024-02-14 03:39:45 +08:00
|
|
|
const { data: padIdData } = useQuery<GetPadIdQueryResponse>(
|
|
|
|
GET_PAD_ID,
|
2024-05-29 21:26:11 +08:00
|
|
|
{ variables: { externalId: NOTES_CONFIG.id } },
|
2024-02-14 03:39:45 +08:00
|
|
|
);
|
|
|
|
const padId = padIdData?.sharedNotes?.[0]?.padId;
|
|
|
|
|
|
|
|
if (!padId) return null;
|
|
|
|
|
2024-01-16 03:49:09 +08:00
|
|
|
return (
|
|
|
|
<NotesDropdownGraphql
|
|
|
|
amIPresenter={amIPresenter}
|
|
|
|
isRTL={isRTL}
|
|
|
|
presentations={presentations}
|
|
|
|
handlePinSharedNotes={handlePinSharedNotes}
|
2024-02-14 03:39:45 +08:00
|
|
|
padId={padId}
|
2024-01-16 03:49:09 +08:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default NotesDropdownContainerGraphql;
|