Shared notes: client-side UI, get PDF from bbb-pads
This commit is contained in:
parent
6985004756
commit
4995ad5d82
@ -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>
|
||||
|
@ -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(() => {
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -270,4 +270,5 @@ export default {
|
||||
persistPresentationChanges,
|
||||
dispatchTogglePresentationDownloadable,
|
||||
setPresentation,
|
||||
requestPresentationUploadToken,
|
||||
};
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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": "用户活动检查",
|
||||
|
@ -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": "用戶活動檢查",
|
||||
|
Loading…
Reference in New Issue
Block a user