diff --git a/public/config.json b/public/config.json new file mode 100644 index 00000000..5ec59c57 --- /dev/null +++ b/public/config.json @@ -0,0 +1,3 @@ +{ + "typeOfSharedNotes": "dynamic" +} diff --git a/src/components/notes/index.js b/src/components/notes/index.js index d996cb3b..dc844ff1 100644 --- a/src/components/notes/index.js +++ b/src/components/notes/index.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { defineMessages, useIntl, @@ -6,17 +6,45 @@ import { import { ID } from 'utils/constants'; import storage from 'utils/data/storage'; import './index.scss'; +import NotesDynamic from './notes_dynamic'; +import NotesStatic from './notes_static'; +import { getTypeOfSharedNotes } from 'utils/params'; +import { getConfigs } from 'config'; const intlMessages = defineMessages({ aria: { id: 'player.notes.wrapper.aria', description: 'Aria label for the notes wrapper', }, + noNotes: { + id: 'player.notes.message.noNotes' + } }); const Notes = () => { + let isThereNoteToDisplay = true; + let note; + let isDynamic = true; const intl = useIntl(); + const [typeOfSharedNotesConfig, setTypeOfSharedNotesConfig] = useState(""); + let typeOfSharedNotes = getTypeOfSharedNotes(); + if (!storage.notes_dynamic && !storage.notes_static) { + isThereNoteToDisplay = false; + note = `--- ${intl.formatMessage(intlMessages.noNotes)} ---`; + }else { + if ( typeOfSharedNotes === null) { + getConfigs(function (json) { + if (!!json) { + setTypeOfSharedNotesConfig(json.typeOfSharedNotes); + } + }); + typeOfSharedNotes = typeOfSharedNotesConfig + } + if ( typeOfSharedNotes === "static" ) { + isDynamic = false; + } + } return (
{ tabIndex="0" >
-
+ /> + : isDynamic ? : + }
); diff --git a/src/components/notes/notes_dynamic/index.js b/src/components/notes/notes_dynamic/index.js new file mode 100644 index 00000000..632e0556 --- /dev/null +++ b/src/components/notes/notes_dynamic/index.js @@ -0,0 +1,42 @@ +import React from 'react'; +import { + defineMessages, + useIntl, +} from 'react-intl'; +import { ID } from 'utils/constants'; +import storage from 'utils/data/storage'; +import '../index.scss'; +import { useCurrentIndex } from 'components/utils/hooks'; + +const intlMessages = defineMessages({ + notesToCome: { + id: 'player.notes.message.notesToCome' + } +}); + +const NotesDynamic = () => { + + const intl = useIntl(); + const currentIndex = useCurrentIndex(storage.notes_dynamic); + let note; + if ( !storage.notes_dynamic && storage.notes_static ) { + note = storage.notes_static; + } else if ( storage.notes_dynamic ){ + if (currentIndex === -1) { + note = `--- ${intl.formatMessage(intlMessages.notesToCome)} ---`; + } else { + note = storage.notes_dynamic[currentIndex].text; + } + } + return ( +
+ ); +}; + +// Avoid re-render +const areEqual = () => true; + +export default React.memo(NotesDynamic, areEqual); diff --git a/src/components/notes/notes_static/index.js b/src/components/notes/notes_static/index.js new file mode 100644 index 00000000..78927cb5 --- /dev/null +++ b/src/components/notes/notes_static/index.js @@ -0,0 +1,37 @@ +import React from 'react'; +import { + defineMessages, + useIntl, +} from 'react-intl'; +import { ID } from 'utils/constants'; +import storage from 'utils/data/storage'; +import '../index.scss'; + +const intlMessages = defineMessages({ + noNotes: { + id: 'player.notes.message.noNotes' + }, +}); + +const NotesStatic = () => { + const intl = useIntl(); + + let note; + if ( storage.notes_static ) { + note = storage.notes_static; + }else { + note = `--- ${intl.formatMessage(intlMessages.noNotes)} ---`; + } + + return ( +
+ ); +}; + +// Avoid re-render +const areEqual = () => true; + +export default React.memo(NotesStatic, areEqual); diff --git a/src/config.js b/src/config.js index 83383b6d..27fe3abf 100644 --- a/src/config.js +++ b/src/config.js @@ -11,6 +11,10 @@ const controls = { swap: true, theme: true, }; +const getConfigs = async (fn) => { + return await fetch("./config.json").then(response => response.json()) + .then(fn) +} const date = { enabled: true }; @@ -20,7 +24,8 @@ const files = { chat: 'slides_new.xml', cursor: 'cursor.xml', metadata: 'metadata.xml', - notes: 'notes.html', + notes_dynamic: 'notes_events.json', + notes_static: 'notes.html', panzooms: 'panzooms.xml', polls: 'polls.json', screenshare: 'deskshare.xml', @@ -77,6 +82,7 @@ const thumbnails = { }; export { + getConfigs, chat, controls, date, diff --git a/src/locales/messages/en.json b/src/locales/messages/en.json index ed46468b..0f9f6dfd 100644 --- a/src/locales/messages/en.json +++ b/src/locales/messages/en.json @@ -33,6 +33,8 @@ "player.chat.message.video.name": "External video", "player.chat.wrapper.aria": "Chat area", "player.notes.wrapper.aria": "Notes area", + "player.notes.message.noNotes": "Shared notes were not used", + "player.notes.message.notesToCome": "Nothing written yet", "player.presentation.wrapper.aria": "Presentation area", "player.screenshare.wrapper.aria": "Screenshare area", "player.search.modal.title": "Search", diff --git a/src/utils/builder.js b/src/utils/builder.js index 5ce63d77..8e4c31d9 100644 --- a/src/utils/builder.js +++ b/src/utils/builder.js @@ -133,6 +133,21 @@ const buildMetadata = result => { return data; }; +const buildNotesEvents = (result) => { + const { root } = result; + let data = []; + if (hasProperty(root, "events") ) { + const { events } = root + data = events.map(change => { + return { + timestamp: parseFloat(change.timestamp) / 1000, + text: change.text + } + }); + } + return data; +} + const buildNotes = result => { if (!result) return ''; @@ -497,6 +512,9 @@ const build = (filename, value) => { case config.tldraw: data = buildTldraw(value); break; + case config.notes_dynamic: + data = buildNotesEvents(value); + break; default: logger.debug('unhandled', 'json', filename); reject(filename); @@ -504,7 +522,7 @@ const build = (filename, value) => { resolve(data); } else if (fileType === 'html') { switch (filename) { - case config.notes: + case config.notes_static: data = buildNotes(value); break; default: diff --git a/src/utils/constants.js b/src/utils/constants.js index e87cbb32..7467083f 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -36,6 +36,8 @@ const ID = { MESSAGES: 'messages', METADATA: 'metadata', NOTES: 'notes', + NOTES_DYNAMIC: 'notes_dynamic', + NOTES_STATIC: 'notes_static', PANZOOMS: 'panzooms', PLAYER: 'player', POLLS: 'polls', @@ -59,7 +61,8 @@ const CONTENT = [ ID.CHAT, ID.POLLS, ID.VIDEOS, - ID.NOTES, + ID.NOTES_DYNAMIC, + ID.NOTES_STATIC, ID.SCREENSHARE, ID.CAPTIONS, ]; diff --git a/src/utils/data/storage.js b/src/utils/data/storage.js index 15151f2c..1cdaa14b 100644 --- a/src/utils/data/storage.js +++ b/src/utils/data/storage.js @@ -160,7 +160,7 @@ const storage = { return { captions: hasProperty(DATA, ID.CAPTIONS), chat: hasProperty(DATA, ID.CHAT), - notes: hasProperty(DATA, ID.NOTES), + notes_dynamic: hasProperty(DATA, ID.NOTES_DYNAMIC), polls: hasProperty(DATA, ID.POLLS), videos: hasProperty(DATA, ID.VIDEOS), presentation: hasProperty(DATA, ID.SHAPES), @@ -171,7 +171,7 @@ const storage = { return { captions: !isEmpty(this.captions), chat: !isEmpty(this.chat), - notes: !isEmpty(this.notes), + notes_dynamic: !isEmpty(this.notes_dynamic), polls: !isEmpty(this.polls), videos: !isEmpty(this.videos), presentation: hasPresentation(this.slides), @@ -213,8 +213,11 @@ const storage = { get metadata() { return DATA[ID.METADATA]; }, - get notes() { - return DATA[ID.NOTES]; + get notes_static() { + return DATA[ID.NOTES_STATIC]; + }, + get notes_dynamic() { + return DATA[ID.NOTES_DYNAMIC]; }, get panzooms() { return DATA[ID.PANZOOMS]; diff --git a/src/utils/params.js b/src/utils/params.js index 34fe7f63..e1f135ba 100644 --- a/src/utils/params.js +++ b/src/utils/params.js @@ -27,6 +27,14 @@ const getMediaPath = () => { return mediaPath; }; +const getTypeOfSharedNotes = () => { + const param = getSearchParam('typeOfSharedNotes'); + + if (param) return param; + + return null; +}; + const getSearchParam = (name) => { const params = new URLSearchParams(window.location.search); @@ -125,6 +133,7 @@ const parseTimeToSeconds = time => { }; export { + getTypeOfSharedNotes, getFrequency, getLayout, getMediaPath,