Shared notes: client-side UI, get PDF from bbb-pads

This commit is contained in:
Daniel Petri Rocha 2022-03-08 01:25:44 +01:00
parent 6985004756
commit 4995ad5d82
11 changed files with 155 additions and 2 deletions

View File

@ -17,6 +17,10 @@ const intlMessages = defineMessages({
id: 'app.notes.title',
description: 'Title for the shared notes',
},
convertAndUploadLabel: {
id: 'app.note.convertAndUpload',
description: 'Export shared notes as a PDF and upload to the main room',
},
});
const propTypes = {
@ -34,11 +38,50 @@ const Notes = ({
intl,
isRTL,
layoutContextDispatch,
amIModerator,
isResizing,
}) => {
useEffect(() => () => Service.setLastRev(), []);
const { isChrome } = browserInfo;
if (hasPermission && amIModerator) {
return (
<Styled.Notes data-test="notes" isChrome={isChrome}>
<Styled.Header>
<Styled.Title data-test="notesTitle">
<Styled.HideButton
onClick={() => {
layoutContextDispatch({
type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN,
value: false,
});
layoutContextDispatch({
type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL,
value: PANELS.NONE,
});
}}
data-test="hideNotesLabel"
aria-label={intl.formatMessage(intlMessages.hide)}
label={intl.formatMessage(intlMessages.title)}
icon={isRTL ? 'right_arrow' : 'left_arrow'}
/>
</Styled.Title>
<Styled.ConvertAndUpload
onClick={() => { Service.convertAndUpload(); }}
label={intl.formatMessage(intlMessages.convertAndUploadLabel)}
icon="upload"
/>
</Styled.Header>
<PadContainer
externalId={Service.ID}
hasPermission={hasPermission}
isResizing={isResizing}
isRTL={isRTL}
/>
</Styled.Notes>
);
}
return (
<Styled.Notes data-test="notes" isChrome={isChrome}>
<Styled.Header>

View File

@ -1,15 +1,24 @@
import React from 'react';
import React, { useContext } from 'react';
import { withTracker } from 'meteor/react-meteor-data';
import Notes from './component';
import Service from './service';
import { layoutSelectInput, layoutDispatch } from '../layout/context';
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
import Auth from '/imports/ui/services/auth';
const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator;
const Container = ({ ...props }) => {
const cameraDock = layoutSelectInput((i) => i.cameraDock);
const { isResizing } = cameraDock;
const layoutContextDispatch = layoutDispatch();
return <Notes {...{ layoutContextDispatch, isResizing, ...props }} />;
const usingUsersContext = useContext(UsersContext);
const { users } = usingUsersContext;
const currentUser = users[Auth.meetingID][Auth.userID];
const amIModerator = currentUser.role === ROLE_MODERATOR;
return <Notes {...{ amIModerator, layoutContextDispatch, isResizing, ...props }} />;
};
export default withTracker(() => {

View File

@ -74,6 +74,10 @@ const toggleNotesPanel = (sidebarContentPanel, layoutContextDispatch) => {
});
};
const convertAndUpload = () => {
return PadsService.convertAndUpload(NOTES_CONFIG.id);
}
export default {
ID: NOTES_CONFIG.id,
toggleNotesPanel,
@ -82,4 +86,5 @@ export default {
setLastRev,
getLastRev,
hasUnreadNotes,
convertAndUpload,
};

View File

@ -82,9 +82,38 @@ const HideButton = styled(Button)`
}
`;
const ConvertAndUpload = styled(Button)`
position: relative;
background-color: ${colorWhite};
display: block;
margin: ${borderSizeLarge};
margin-bottom: ${borderSize};
padding-left: 0;
padding-right: inherit;
[dir="rtl"] & {
padding-left: inherit;
padding-right: 0;
}
& > i {
color: ${colorGrayDark};
font-size: smaller;
[dir="rtl"] & {
-webkit-transform: scale(-1, 1);
-moz-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
transform: scale(-1, 1);
}
}
&:hover {
background-color: ${colorWhite};
}
`;
export default {
Notes,
Header,
Title,
HideButton,
ConvertAndUpload,
};

View File

@ -2,6 +2,8 @@ import Pads, { PadsUpdates } from '/imports/api/pads';
import { makeCall } from '/imports/ui/services/api';
import Auth from '/imports/ui/services/auth';
import Settings from '/imports/ui/services/settings';
import PresentationUploaderService from '/imports/ui/components/presentation/presentation-uploader/service';
import axios from 'axios';
const PADS_CONFIG = Meteor.settings.public.pads;
@ -85,6 +87,64 @@ const getPadContent = (externalId) => {
return '';
};
async function convertAndUpload(externalId) {
const padId = await makeCall('getPadId', externalId);
// Build export URL in the desired format
const params = getParams();
const exportUrl = Auth.authenticateURL(`${PADS_CONFIG.url}/p/${padId}/export/pdf?${params}`);
console.log(exportUrl);
let exportedSharedNotes = await axios({
method: 'get',
url: exportUrl,
responseType: 'json',
});
if (exportedSharedNotes.status != 200) {
return null;
}
let file = new File([exportedSharedNotes.data], "SharedNotes.pdf", { lastModified: Date.now, type: 'application/pdf' });
// PresentationUploaderService.uploadAndConvertPresentation(
// file,
// false,
// 'DEFAULT_PRESENTATION_POD',
// Auth.meetingID,
// PRESENTATION_CONFIG.uploadEndpoint,
// { done: false, error: false, progress: 0 },
// { done: false, error: false },
// { done: false, error: false, status: '' },
// );
let presentationUploadToken = await PresentationUploaderService.requestPresentationUploadToken('DEFAULT_PRESENTATION_POD', Auth.meetingID, 'SharedNotes.pdf');
let callbackUrl = `http://127.0.0.1:8090/bigbluebutton/presentation/${presentationUploadToken}/upload`;
let formData = new FormData();
formData.append('presentation_name', 'SharedNotes.pdf');
formData.append('Filename', 'SharedNotes.pdf');
formData.append('conference', Auth.meetingID);
formData.append('room', Auth.meetingID);
formData.append('pod_id', 'DEFAULT_PRESENTATION_POD');
formData.append('is_downloadable', false);
// formData.append('fileUpload', file);
let res = await axios({
method: "post",
url: callbackUrl,
fileUpload: file,
headers: { "Content-Type": "multipart/form-data" },
});
console.log(res.data);
return null;
}
export default {
getPadId,
createGroup,
@ -94,4 +154,5 @@ export default {
getRev,
getPadTail,
getPadContent,
convertAndUpload,
};

View File

@ -270,4 +270,5 @@ export default {
persistPresentationChanges,
dispatchTogglePresentationDownloadable,
setPresentation,
requestPresentationUploadToken,
};

View File

@ -57,6 +57,7 @@
"app.note.title": "Geteilte Notizen",
"app.note.label": "Notiz",
"app.note.hideNoteLabel": "Notiz verbergen",
"app.note.convertAndUpload": "Geteilte Notizen im Präsentations-Bereich laden",
"app.note.tipLabel": "Drücken Sie Esc, um die Editorwerkzeugliste auszuwählen",
"app.note.locked": "Gesperrt",
"app.user.activityCheck": "Teilnehmeraktivitätsprüfung",

View File

@ -58,6 +58,7 @@
"app.notes.title": "Shared Notes",
"app.notes.label": "Notes",
"app.notes.hide": "Hide notes",
"app.note.convertAndUpload": "Move notes to whiteboard",
"app.notes.locked": "Locked",
"app.pads.hint": "Press Esc to focus the pad's toolbar",
"app.user.activityCheck": "User activity check",

View File

@ -57,6 +57,7 @@
"app.note.title": "Notas compartilhadas",
"app.note.label": "Notas",
"app.note.hideNoteLabel": "Ocultar notas",
"app.note.convertAndUpload": "Adicionar notas compartilhadas como apresentação",
"app.note.tipLabel": "Pressione Esc para focar na barra de ferramentas do editor",
"app.note.locked": "Bloqueado",
"app.user.activityCheck": "Verificação de atividade do usuário",

View File

@ -54,6 +54,7 @@
"app.note.title": "分享笔记",
"app.note.label": "笔记",
"app.note.hideNoteLabel": "隐藏笔记面板",
"app.note.convertAndUpload": "上传共享笔记",
"app.note.tipLabel": "按Esc键定位到编辑器工具栏",
"app.note.locked": "已锁定",
"app.user.activityCheck": "用户活动检查",

View File

@ -57,6 +57,7 @@
"app.note.title": "共享筆記",
"app.note.label": "筆記",
"app.note.hideNoteLabel": "隱藏筆記",
"app.note.convertAndUpload": "上傳共享筆記",
"app.note.tipLabel": "按下 Esc 鍵以聚焦到編輯器工具列",
"app.note.locked": "已鎖定",
"app.user.activityCheck": "用戶活動檢查",