diff --git a/components/Application.js b/components/Application.js
index 2735c88bc..fb0ecb5d1 100644
--- a/components/Application.js
+++ b/components/Application.js
@@ -30,19 +30,19 @@ class Application extends React.Component {
let cookieBanner = '';
let Handler = this.props.currentRoute.handler;
let header = null , footer = null, content = null;
- const noHF_pages = ['presentation', 'neo4jguide', 'webrtc'];//NOTE add the route name to the following array if you don't want header and footer rendered on the page
+ const noHF_pages = ['presentation', 'neo4jguide', 'webrtc', 'print', 'presentationIE'];//NOTE add the route name to the following array if you don't want header and footer rendered on the page
if(!noHF_pages.includes(this.props.currentRoute.name)){
header = ; footer = ;
+ //does not show banner on the above pages
+ if (!this.state.user_cookies) {
+ cookieBanner =
+ {(message) =>
+ {}}/>}
+ ;
+ }
}
content = (this.props.ErrorStore.error) ? : ;
- if (!this.state.user_cookies) {
- cookieBanner =
- {(message) =>
- {}}/>}
- ;
- }
-
return (
{cookieBanner}
diff --git a/components/Deck/ContentModulesPanel/CollectionsPanel/CollectionsList.js b/components/Deck/ContentModulesPanel/CollectionsPanel/CollectionsList.js
new file mode 100644
index 000000000..8b36a34ca
--- /dev/null
+++ b/components/Deck/ContentModulesPanel/CollectionsPanel/CollectionsList.js
@@ -0,0 +1,50 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import CollectionsListItem from './CollectionsListItem';
+import { defineMessages } from 'react-intl';
+
+class CollectionsList extends React.Component {
+ constructor(props) {
+ super(props);
+ this.messages = this.getIntlMessages();
+ }
+ getIntlMessages() {
+ return defineMessages({
+ partOfPlaylists: {
+ id: 'CollectionsList.partOfPlaylists',
+ defaultMessage: 'This deck is part of the following playlists'
+ },
+ });
+ }
+ render() {
+
+ const selector = this.props.selector;
+ const collections = this.props.collections;
+ const collectionsList = collections.map( (node, index) => );
+
+ return (
+
');
} else {
console.log(nextProps.MediaStore.file);
// The following trick using date is to force refresh of the img, otherwise the browser will use the cached one.
let d = new Date();
let time = d.getTime();
if (nextProps.MediaStore.file.url){
- $('.pptx2html').append('
');
+ $('.pptx2html').append('
');
}
}
this.refreshCKeditor();
@@ -2015,13 +2140,20 @@ class SlideContentEditor extends React.Component {
}
}
editImage(context, event, idContext){
+ this.idContext = idContext;
let contains_img = $('#' + idContext).find('img').length;
if (contains_img) {
let src = $('#' + idContext).find('img')[0].src;
this.context.executeAction(editImageWithSrc, src);
} else {
let src = $('#' + idContext).attr('svg-source');
- this.context.executeAction(editImageWithSrc, src);
+ if (src) {
+ this.context.executeAction(editImageWithSrc, src);
+ } else {
+ let svg = '';
+ this.context.executeAction(editSVGwithSVG, svg);
+ }
}
@@ -2208,8 +2340,8 @@ class SlideContentEditor extends React.Component {
this.refs.inlineContent.style.height = contentHeight + padding + 'px';
this.refs.inlineContent.style.width = contentWidth + padding + 'px';
} else {
- this.refs.inlineContent.style.overflowY = 'scroll';
- this.refs.inlineContent.style.height = '100%';
+ this.refs.inlineContent.style.overflowY = 'auto';
+ this.refs.slideEditPanel.style.height = '720px'; // fix problem with editing: SWIK-2499
}
}
@@ -2230,21 +2362,6 @@ class SlideContentEditor extends React.Component {
//context.hasChanges = true;
}
- zoomIn(){
- this.scaleRatio += 0.25;
- this.resize();
- }
-
- resetZoom(){
- this.scaleRatio = 1;
- this.resize();
- }
-
- zoomOut(){
- this.scaleRatio -= 0.25;
- this.resize();
- }
-
render() {
//TODO: offer option to switch between inline-editor (alloy) and permanent/full editor (CKeditor)
//TODO - remove use of id - Only use 'ref=' for React. Find CKeditor create function(s) that do not require id.
@@ -2431,33 +2548,6 @@ class SlideContentEditor extends React.Component {
}
- {
- this.props.hideSpeakerNotes ? null :
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
);
diff --git a/components/Deck/ContentPanel/SlideModes/SlideEditPanel/SlideEditPanel.js b/components/Deck/ContentPanel/SlideModes/SlideEditPanel/SlideEditPanel.js
index e1d8f7c64..8c0d281f3 100644
--- a/components/Deck/ContentPanel/SlideModes/SlideEditPanel/SlideEditPanel.js
+++ b/components/Deck/ContentPanel/SlideModes/SlideEditPanel/SlideEditPanel.js
@@ -7,8 +7,6 @@ import SlideContentEditor from './SlideContentEditor';
import MarkdownEditor from './MarkdownEditor';
import restoreDeckPageLayout from '../../../../../actions/deckpagelayout/restoreDeckPageLayout';
-
-
class SlideEditPanel extends React.Component {
constructor(props) {
super(props);
diff --git a/components/Deck/ContentPanel/SlideModes/SlideViewPanel/SlideContentView.js b/components/Deck/ContentPanel/SlideModes/SlideViewPanel/SlideContentView.js
index 05a0b26bc..43b967e95 100644
--- a/components/Deck/ContentPanel/SlideModes/SlideViewPanel/SlideContentView.js
+++ b/components/Deck/ContentPanel/SlideModes/SlideViewPanel/SlideContentView.js
@@ -2,6 +2,8 @@ import PropTypes from 'prop-types';
import React from 'react';
import {findDOMNode} from 'react-dom';
import ChartRender from '../../util/ChartRender';
+import {connectToStores} from 'fluxible-addons-react';
+import SlideViewStore from '../../../../../stores/SlideViewStore';
const ReactDOM = require('react-dom');
class SlideContentView extends React.Component {
@@ -13,10 +15,13 @@ class SlideContentView extends React.Component {
this.resize = this.resize.bind(this);
}
componentWillReceiveProps(nextProps){
- if (this.currentContent !== this.props.content)
- {
+ if (this.currentContent !== this.props.content) {
this.currentContent = this.props.content;
- this.scaleRatio = null;
+ }
+
+ if (nextProps.SlideViewStore.scaleRatio && nextProps.SlideViewStore.scaleRatio !== this.scaleRatio) {
+ this.scaleRatio = nextProps.SlideViewStore.scaleRatio;
+ this.resize();
}
}
componentWillUnmount(){
@@ -71,25 +76,14 @@ class SlideContentView extends React.Component {
this.refs.inlineContent.style.overflowX = 'hidden';
/* Some extra padding is added to ensure that the borderline is visible. */
- this.refs.inlineContent.style.height = contentHeight + padding + 'px';
- this.refs.inlineContent.style.width = contentWidth + padding + 'px';
+ this.refs.inlineContent.style.height = contentHeight + 'px';
+ this.refs.inlineContent.style.width = contentWidth + 'px';
} else {
this.refs.inlineContent.style.overflowY = 'scroll';
this.refs.inlineContent.style.height = '100%';
}
}
- zoomIn(){
- this.scaleRatio += 0.25;
- this.resize();
- }
- resetZoom(){
- this.scaleRatio = 1;
- this.resize();
- }
- zoomOut(){
- this.scaleRatio -= 0.25;
- this.resize();
- }
+
render() {
//styles should match slideContentEditor for consistency
const compHeaderStyle = {
@@ -136,7 +130,11 @@ class SlideContentView extends React.Component {
styleName = 'white';
}
let style = require('../../../../../custom_modules/reveal.js/css/theme/' + styleName + '.css');
-
+ //to handle non-canvas display of slides
+ let slideHTMLContent = this.props.content;
+ if(slideHTMLContent.indexOf('class="pptx2html"') === -1){
+ slideHTMLContent = '
' + slideHTMLContent + '
';
+ }
return (
@@ -144,7 +142,7 @@ class SlideContentView extends React.Component {
diff --git a/components/DeckCollection/CollectionPanel/CollectionPanel.js b/components/DeckCollection/CollectionPanel/CollectionPanel.js
index 9e57a4b80..134739a78 100644
--- a/components/DeckCollection/CollectionPanel/CollectionPanel.js
+++ b/components/DeckCollection/CollectionPanel/CollectionPanel.js
@@ -3,20 +3,25 @@ import React from 'react';
import {NavLink, navigateAction} from 'fluxible-router';
import DeckCollectionStore from '../../../stores/DeckCollectionStore';
import UserProfileStore from '../../../stores/UserProfileStore';
+import UserFollowingsStore from '../../../stores/UserFollowingsStore';
import { connectToStores } from 'fluxible-addons-react';
import CustomDate from '../../Deck/util/CustomDate';
import CollectionDecks from './CollectionDecks';
import CollectionDecksReorder from './CollectionDecksReorder';
import {Button, Icon} from 'semantic-ui-react';
import updateCollectionDeckOrder from '../../../actions/collections/updateCollectionDeckOrder';
+import createFollowing from '../../../actions/following/createFollowing';
+import deleteFollowing from '../../../actions/following/deleteFollowing';
import {FormattedMessage, defineMessages} from 'react-intl';
+import AddDecksModal from '../Modals/AddDecksModal/AddDecksModal';
+import nl2br from 'react-nl2br';
class CollectionPanel extends React.Component {
constructor(props){
super(props);
this.state = {
editMode: false,
- decksOrder: this.props.DeckCollectionStore.collectionDetails.decks.slice() || []
+ decksOrder: this.props.DeckCollectionStore.collectionDetails.decks.slice() || [],
};
this.messages = this.getIntlMessages();
@@ -70,6 +75,29 @@ class CollectionPanel extends React.Component {
newState.decksOrder[index + 1] = tmp;
this.setState(newState);
}
+ handleFollowCollection() {
+ if (this.props.UserFollowingsStore.selectedFollowingId !== null) {
+ this.context.executeAction(deleteFollowing, {
+ id: this.props.UserFollowingsStore.selectedFollowingId
+ });
+ } else {
+ this.context.executeAction(createFollowing, {
+ playlistId: this.props.DeckCollectionStore.collectionDetails._id,
+ userId: this.props.UserProfileStore.userid,
+ followed_type: 'playlist'
+ });
+ }
+ }
+ handleRemove(index){
+ let newState = Object.assign({}, this.state);
+ newState.decksOrder.splice(index, 1);
+ this.setState(newState);
+ }
+ handleAdd(newDecks){
+ let newState = Object.assign({}, this.state);
+ newState.decksOrder = newDecks;
+ this.setState(newState);
+ }
showErrorPopup(text){
swal({
title: 'Error',
@@ -105,17 +133,21 @@ class CollectionPanel extends React.Component {
id: 'CollectionPanel.decks.title',
defaultMessage: 'Decks in Playlist'
},
- reorderDecks: {
- id: 'CollectionPanel.decks.reorder',
- defaultMessage: 'Reorder Decks'
+ editPlaylist: {
+ id: 'CollectionPanel.decks.edit',
+ defaultMessage: 'Edit'
},
+ editPlaylistHeader: {
+ id: 'CollectionPanel.decks.edit.header',
+ defaultMessage: 'Edit Playlist'
+ },
saveReorder: {
id: 'CollectionPanel.save.reorder',
defaultMessage: 'Save'
},
cancelReorder: {
id: 'CollectionPanel.cancel.reorder',
- defaultMessage: 'Close'
+ defaultMessage: 'Cancel'
},
sortDefault: {
id: 'CollectionPanel.sort.default',
@@ -132,7 +164,15 @@ class CollectionPanel extends React.Component {
sortTitle: {
id: 'CollectionPanel.sort.title',
defaultMessage: 'Title'
- }
+ },
+ collectionSubscribe: {
+ id: 'UserCollections.collections.subscribe',
+ defaultMessage: 'Subscribe to this playlist'
+ },
+ collectionUnsubscribe: {
+ id: 'UserCollections.collections.unsubscribe',
+ defaultMessage: 'You are subscribed to this playlist, click to unsubscribe'
+ },
});
}
getSelectedSort(sortBy){
@@ -156,10 +196,9 @@ class CollectionPanel extends React.Component {
}
let data = this.props.DeckCollectionStore.collectionDetails;
- let content = (!this.state.editMode)
- ?
- : ;
+ let loadingDiv = (this.props.DeckCollectionStore.deckOrderLoading) ?
Loading
: '';
+
// the user has edit rights in collection if he is the owner of the collection, or one of his user groups are assigned to the collection
let hasEditRights = (this.props.UserProfileStore.userid && this.props.UserProfileStore.userid === data.user.id
|| this.props.UserProfileStore.user.groups && this.props.UserProfileStore.user.groups.map((group) => group._id).includes(data.userGroup));
@@ -173,28 +212,36 @@ class CollectionPanel extends React.Component {
diff --git a/components/Home/Terms.js b/components/Home/Terms.js
index e7082458f..e39627584 100644
--- a/components/Home/Terms.js
+++ b/components/Home/Terms.js
@@ -129,7 +129,7 @@ class terms extends React.Component {
values={{
noProfessionalAdvice:
}}
- defaultMessage="{noProfessionalAdvice} – the content of presentations and other projects is for informational purposes only and does not constitute professional advice."
+ defaultMessage="{noProfessionalAdvice} – the content of presentations and other projects is for informational/educational purposes only and does not constitute professional advice or commercial advertisement. However, you can contact the SlideWiki foundation to support you in creating your own installation of SlideWiki on a website or webserver for commercial, educational, hybrid, or other purposes."
/>
@@ -176,7 +176,7 @@ class terms extends React.Component {
-
+
diff --git a/components/Login/LoginModal.js b/components/Login/LoginModal.js
index 3533c2a17..f1311e63e 100644
--- a/components/Login/LoginModal.js
+++ b/components/Login/LoginModal.js
@@ -344,7 +344,7 @@ class LoginModal extends React.Component {
diff --git a/components/Login/UserMenuDropdown.js b/components/Login/UserMenuDropdown.js
index 4342bf38f..53b8b1db0 100644
--- a/components/Login/UserMenuDropdown.js
+++ b/components/Login/UserMenuDropdown.js
@@ -71,6 +71,15 @@ class UserMenuDropdown extends React.Component {
Decks
+
+
+ Playlists
+ {
for (let i = 0; i < objects.length; i++){
this.canvas.add(objects[i]);
}
+ // Black Magic to render correctly imported SVGs from a Slide... please don't remove, unless
+ // you find a better solution (real solution)
+ let dummy = new fabric.Rect({ width: 20, height: 20, left: 30, top:0 });
+ this.canvas.add(dummy);
+ this.undo();
+ // Black Magic ends here.
this.canvas.renderAll();
});
- } else if ( ext === 'png' || ext === 'jpg' || ext === 'jpeg' ) {
+ } else if (nextProps.PaintModalStore.toEdit) {
this.handleOpen();
fabric.Image.fromURL(nextProps.PaintModalStore.url, (oImg) => {
this.canvas.add(oImg);
@@ -803,6 +807,15 @@ class PaintModal extends React.Component {
}
}
+ handleKeyPress = (event, param) => {
+ if(event.key === 'Enter'){
+ // console.log('enter key');
+ if(param === 'handlePaintOpen') {
+ this.handleOpen();
+ }
+ }
+ }
+
render() {
this.context.getUser().username;
let submitButtonText = this.context.intl.formatMessage(this.messages.addToSlide);
@@ -912,7 +925,7 @@ class PaintModal extends React.Component {
this.handleKeyPress(evt, 'handleOpen')}>
+ this.handleKeyPress(evt, 'handlePaintOpen')}>
{this.context.intl.formatMessage(this.messages.paintButton)}
}
diff --git a/components/PresentationPrintHTMLLayout.js b/components/PresentationPrintHTMLLayout.js
new file mode 100644
index 000000000..3939eb8d0
--- /dev/null
+++ b/components/PresentationPrintHTMLLayout.js
@@ -0,0 +1,59 @@
+import React from 'react';
+import ApplicationStore from '../stores/ApplicationStore';
+//import ga from '../plugins/googleAnalytics/ga';
+
+let hook = require('css-modules-require-hook');
+
+hook({
+ generateScopedName: '[hash:base64:5]',
+});
+
+class PresentationPrintHTMLLayout extends React.Component {
+ render() {
+ return (
+
+
+
+ {this.props.context.getStore(ApplicationStore).getPageTitle()}
+
+
+ {/*NOTE needed, otherwise a horizontal scrollbar appears. TODO get rid of this*/}
+
+
+ {/**/}
+ {/* we add this config option for mathjax so we can better control when the typesetting will occur */}
+
+
+ {/* Vendors css bundle */
+ this.props.addAssets ? :
+ }
+
+
+
+ {/* Following are added only to support IE browser */}
+
+
+
+
+
+ {/* Above are added only to support IE browser */}
+
+
+
+ {/* All external vendors bundle*/
+ this.props.addAssets ? : ''
+ }
+ {/* Adding for dependency loading with reveal.js*/}
+
+ {/* Run-time settings */}
+
+ {/* Main app bundle */}
+
+ {/* */}
+
+
+ );
+ }
+}
+
+export default PresentationPrintHTMLLayout;
diff --git a/components/PresentationRoomsHTMLLayout.js b/components/PresentationRoomsHTMLLayout.js
index 275be76ab..90194785e 100644
--- a/components/PresentationRoomsHTMLLayout.js
+++ b/components/PresentationRoomsHTMLLayout.js
@@ -43,7 +43,9 @@ class PresentationRoomsHTMLLayout extends React.Component {
{/* Main app bundle */}
-
+ {/**/}
+
+ {/* */}
{/* */}