Commit a52a5789 authored by Matthieu Le Corre's avatar Matthieu Le Corre

integrate literralyCanvas

Signed-off-by: Matthieu Le Corre's avatarMatthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
parent 54b4b139
nodes_modules
node_modules
.vscode/
\ No newline at end of file
<?php
/**
* @author 2020 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
return [
'routes' => [
[ 'name' => 'file#save', 'url' => '/file/save', 'verb' => 'POST' ],
[ 'name' => 'file#load', 'url' => '/file/load', 'verb' => 'GET' ]
]
];
.literally .button-style-1{border:2px solid transparent;border-radius:3px}.literally .button-style-1{text-decoration:none;cursor:pointer}.literally .button-style-1.selected:not(.disabled){background-color:#a1d9fe}.literally .button-style-1:hover:not(.disabled){border-color:#a1d9fe}.literally .button-style-1.disabled{cursor:default;opacity:0.3}.literally.toolbar-at-top .lc-drawing{bottom:0;top:31px}.literally.toolbar-at-top .lc-options{top:0;border-bottom:1px solid #555}.literally.toolbar-at-bottom .lc-drawing{bottom:31px;top:0}.literally.toolbar-at-bottom .lc-options{bottom:0;border-top:1px solid #555}.literally.toolbar-hidden .lc-drawing{left:0;right:0;bottom:0;top:0}.literally.toolbar-hidden .lc-options,.literally.toolbar-hidden .lc-picker{display:none}.literally{position:relative;background-color:#ddd;min-height:400px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;-ms-touch-action:none;user-select:none}.literally,.literally *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.literally>*{position:absolute}.literally .lc-picker{top:0;left:0;bottom:0;width:61px;background-color:#e6e6e6}.literally .lc-drawing{right:0;left:0;bottom:0;left:0}.literally .lc-drawing>*{position:absolute;top:0;right:0;bottom:0;left:0}.literally .lc-drawing.with-gui{right:0;left:61px;cursor:default}.literally .lc-drawing.with-gui .polygon-toolbar{top:auto;height:31px}.literally .lc-drawing.with-gui .polygon-toolbar .polygon-toolbar-button{float:left}.literally .lc-drawing.with-gui .text-tool-input:focus{outline:none}.literally .lc-picker{z-index:1001;border-right:1px solid #555}.literally .lc-picker .toolbar-button{width:26px;height:26px;line-height:26px;margin:2px;padding:0;cursor:pointer;text-align:center;border:2px solid transparent;border-radius:3px}.literally .lc-picker .toolbar-button{text-decoration:none;cursor:pointer}.literally .lc-picker .toolbar-button.selected:not(.disabled){background-color:#a1d9fe}.literally .lc-picker .toolbar-button:hover:not(.disabled){border-color:#a1d9fe}.literally .lc-picker .toolbar-button.disabled{cursor:default;opacity:0.3}.literally .lc-picker .thin-button{cursor:pointer;float:left;position:relative}.literally .lc-picker .fat-button{clear:both;width:56px}.literally .lc-picker .lc-pick-tool,.literally .lc-picker .lc-undo,.literally .lc-picker .lc-redo,.literally .lc-picker .lc-zoom-in,.literally .lc-picker .lc-zoom-out{background-size:100% auto;background-repeat:no-repeat;background-position:center center}.literally .color-well{font-size:10px;float:left;width:60px}.literally .color-well.open{background-color:#a1d9fe}.literally .color-well-color-container{border:2px solid transparent;border-radius:3px;border:1px solid #aaa;position:relative;width:28px;height:28px;margin:1px auto;overflow:visible}.literally .color-well-color-container{text-decoration:none;cursor:pointer}.literally .color-well-color-container.selected:not(.disabled){background-color:#a1d9fe}.literally .color-well-color-container:hover:not(.disabled){border-color:#a1d9fe}.literally .color-well-color-container.disabled{cursor:default;opacity:0.3}.literally .color-well-color-container .color-well-checker{position:absolute;width:50%;height:50%;background-color:black}.literally .color-well-color-container .color-well-checker-top-left{border-top-left-radius:3px}.literally .color-well-color-container .color-well-checker-bottom-right{border-bottom-right-radius:3px}.literally .color-well-color-container .color-well-color{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:3px}.literally .color-picker-popup{position:absolute;z-index:1;background-color:white;border:1px solid #555;left:60px;bottom:31px}.literally .color-picker-popup .color-row{clear:both}.literally .color-picker-popup .color-row .color-cell{cursor:pointer;width:20px;height:20px;line-height:20px;float:left}.literally .color-picker-popup .color-row .color-cell:hover,.literally .color-picker-popup .color-row .color-cell.selected{border:1px solid #555;line-height:18px}.literally .color-picker-popup .color-row .color-cell.transparent-cell{width:100%}.literally .horz-toolbar{height:31px;background-color:#e6e6e6}.literally .horz-toolbar .label{line-height:30px;margin:0 0.25em 0 0.25em;font-size:12px}.literally .horz-toolbar span{line-height:30px;margin:0 0.25em 0 0.25em;font-size:12px;float:left}.literally .horz-toolbar .square-toolbar-button{border:2px solid transparent;border-radius:3px;margin:1px;border:1px solid #aaa;width:28px;height:28px;float:left;position:relative}.literally .horz-toolbar .square-toolbar-button{text-decoration:none;cursor:pointer}.literally .horz-toolbar .square-toolbar-button.selected:not(.disabled){background-color:#a1d9fe}.literally .horz-toolbar .square-toolbar-button:hover:not(.disabled){border-color:#a1d9fe}.literally .horz-toolbar .square-toolbar-button.disabled{cursor:default;opacity:0.3}.literally .horz-toolbar .square-toolbar-button img{max-width:100%;max-height:100%}.literally .horz-toolbar .square-toolbar-button label{position:absolute;top:0;right:0;bottom:0;left:0;line-height:26px;margin:auto;float:none;text-align:center}.literally .polygon-toolbar{position:absolute;border-top:1px solid #555;border-bottom:1px solid #555;width:100%}.literally.toolbar-at-bottom .polygon-toolbar{top:-100%}.literally.toolbar-at-top .polygon-toolbar{top:100%}.literally .lc-options{z-index:1;right:0;left:61px}.literally .lc-options .lc-font-settings{height:30px;line-height:31px;padding-left:4px;background-color:#f5f5f5}.literally .lc-options .lc-font-settings input{margin:0 0.5em 0 0}.literally .lc-options .lc-font-settings input[type=checkbox]{margin:0 0.5em 0 0.5em}
#whiteboard-container {
position: absolute;
top: 0 ;
bottom: 0;
left:0 ;
right: 0 ;
background-color: white;
z-index: 1000;
margin-top: 50px ;
overflow: hidden;
}
#closebtn {
position: absolute;
top:0 ;
right: 0 ;
width: 30px ;
height: 30Px ;
z-index: inherit;
}
#closebtn:hover {
border: 1px solid silver ;
border-radius: 2px ;
}
.icon-whiteboard {
background-image: url("../img/whiteboard.svg");
}
.literally {
background-color: white !important;
position: initial !important ;
}
.lc-options.horz-toolbar {
background-color: white !important;
border-bottom: 1px solid silver !important;
}
.lc-picker {
background-color: white !important;
border-right: 1px solid silver !important;
}
.square-toolbar-button {
border: 0px solid silver ! important;
}
.square-toolbar-button svg circle{
fill: var(--color-primary) ;
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
/******/ (function(modules) { // webpackBootstrap
/******/ // install a JSONP callback for chunk loading
/******/ function webpackJsonpCallback(data) {
/******/ var chunkIds = data[0];
/******/ var moreModules = data[1];
/******/
/******/
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0, resolves = [];
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ resolves.push(installedChunks[chunkId][0]);
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ for(moduleId in moreModules) {
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
/******/ modules[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
/******/
/******/ while(resolves.length) {
/******/ resolves.shift()();
/******/ }
/******/
/******/ };
/******/
/******/
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // Promise = chunk loading, 0 = chunk loaded
/******/ var installedChunks = {
/******/ 0: 0
/******/ };
/******/
/******/
/******/
/******/ // script path function
/******/ function jsonpScriptSrc(chunkId) {
/******/ return __webpack_require__.p + "" + ({"1":"vendors~literallycanvas"}[chunkId]||chunkId) + ".js"
/******/ }
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
......@@ -26,6 +70,67 @@
/******/ return module.exports;
/******/ }
/******/
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = function requireEnsure(chunkId) {
/******/ var promises = [];
/******/
/******/
/******/ // JSONP chunk loading for javascript
/******/
/******/ var installedChunkData = installedChunks[chunkId];
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
/******/
/******/ // a Promise means "currently loading".
/******/ if(installedChunkData) {
/******/ promises.push(installedChunkData[2]);
/******/ } else {
/******/ // setup Promise in chunk cache
/******/ var promise = new Promise(function(resolve, reject) {
/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject];
/******/ });
/******/ promises.push(installedChunkData[2] = promise);
/******/
/******/ // start chunk loading
/******/ var script = document.createElement('script');
/******/ var onScriptComplete;
/******/
/******/ script.charset = 'utf-8';
/******/ script.timeout = 120;
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = jsonpScriptSrc(chunkId);
/******/
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ onScriptComplete = function (event) {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
/******/ clearTimeout(timeout);
/******/ var chunk = installedChunks[chunkId];
/******/ if(chunk !== 0) {
/******/ if(chunk) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ chunk[1](error);
/******/ }
/******/ installedChunks[chunkId] = undefined;
/******/ }
/******/ };
/******/ var timeout = setTimeout(function(){
/******/ onScriptComplete({ type: 'timeout', target: script });
/******/ }, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ document.head.appendChild(script);
/******/ }
/******/ }
/******/ return Promise.all(promises);
/******/ };
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
......@@ -79,6 +184,16 @@
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // on error function for async loading
/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };
/******/
/******/ var jsonpArray = window["webpackJsonpFileWhiteboard"] = window["webpackJsonpFileWhiteboard"] || [];
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
/******/ jsonpArray.push = webpackJsonpCallback;
/******/ jsonpArray = jsonpArray.slice();
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
/******/ var parentJsonpFunction = oldJsonpFunction;
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
......@@ -86,7 +201,7 @@
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
/***/ (function(module, exports, __webpack_require__) {
/**
* @author Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
......@@ -114,10 +229,21 @@
*/
whiteboardApp = {
// App init
initialise: function() {
this.registerFileActions() ;
var contenair = "<div id=whiteboard-container></div>" ;
this.registerFileActions() ;
},
setupContainer: function() {
$('#content')
.add(this.contenair)
.addClass("viewer-mode")
.addClass("no-sidebar") ;
},
......@@ -129,11 +255,11 @@ whiteboardApp = {
OCA.Files.fileActions.registerAction({
name: 'Edit',
mime: "application/wbr",
actionHandler: self.editAction,
permissions: OC.PERMISSION_READ,
icon: function () {
return OC.imagePath('core', 'actions/edit');
}
},
actionHandler: self.editAction
}) ;
OCA.Files.fileActions.setDefault("application/wbr", 'Edit');
......@@ -143,13 +269,69 @@ whiteboardApp = {
//edit
editAction: function(filename,context) {
dir = context.dir ;
//self.setupContainer() ;
var closebtn ="<div id=closebtn class=icon-close><div>" ;
var ncClient = OC.Files.getClient();
var contenair = "<div id=whiteboard-container></div>" ;
$('#content')
.append(contenair)
.addClass("viewer-mode")
.addClass("no-sidebar") ;
fo = ncClient.getFileInfo(dir + "/" + filename) ;
console.log( fo) ;
__webpack_require__.e(/* import() | literallycanvas */ 1).then(__webpack_require__.t.bind(null, 1, 7)).then(LC => {
var WB= LC.init(
document.getElementById('whiteboard-container'),
{
imageURLPrefix: '/stable18/apps/whiteboard/img/lc_assets' ,
toolbarPosition: 'top'
}
);
// create close button
$('#whiteboard-container') .append(closebtn) ;
$("#closebtn").click(function(){
WB.teardown() ;
$('#whiteboard-container').remove() ;
$('#content').removeClass("viewer-mode").removeClass("no-sidebard") ;
}) ;
//load whiteboard
var url = OC.generateUrl('apps/whiteboard/file/load');
$.ajax({
type: 'GET',
url: url,
data: {path: context.dir + "/" + filename }
}).done(function(content){
console.log("loading done") ;
WB.loadSnapshot(JSON.parse(content)) ;
})
// set save callback
WB.on('drawingChange', function() {
console.log("Save WB ...") ;
var url = OC.generateUrl('apps/whiteboard/file/save');
console.log(url) ;
var putObject = {
content: JSON.stringify(WB.getSnapshot()),
path: context.dir + "/" + filename
};
$.ajax({
type: 'POST',
url: url,
data: putObject
})
}) ;
}) ;
}
} ;
......@@ -195,6 +377,9 @@ $(document).ready(function () {
});
__webpack_require__.nc = btoa(OC.requestToken)
__webpack_require__.p = OC.linkTo('whiteboard', 'js/');
/***/ })
/******/ ]);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -45,7 +45,7 @@
function() {
\OCP\Util::addscript('whiteboard', 'main');
\OCP\Util::addStyle('whiteboard','style') ;
\OCP\Util::addStyle('whiteboard','literallycanvas') ;
});
}
......
<?php
/**
* @author 2020 Matthieu Le Corre <matthieu.lecorre@univ-nantes.fr>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\whiteboard\Controller ;
use OCP\AppFramework\Controller ;
use OCP\IRequest;
use OCP\Files\File;
use OCP\Files\Folder;
class FileController extends Controller {
public function __construct($AppName, IRequest $request, Folder $userFolder) {
parent::__construct($AppName, $request);
//$this->request = $request ;
$this->userFolder = $userFolder;
}
/**
* @NoAdminRequired
*/
public function save($path,$content) {
/** @var File $file */
$file = $this->userFolder->get($path);
$file->putContent($content);
}
/**
* @NoAdminRequired
*/
public function load($path) {
/** @var File $file */
$file = $this->userFolder->get($path);
return $file->getContent($content);
}
}
This diff is collapsed.
......@@ -13,5 +13,12 @@
},
"devDependencies": {
"webpack": "^4.42.0"
},
"dependencies": {
"create-react-class": "^15.6.3",
"literallycanvas": "^0.5.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-dom-factories": "^1.0.2"
}
}
......@@ -24,10 +24,21 @@
*/
whiteboardApp = {
// App init
initialise: function() {
this.registerFileActions() ;
var contenair = "<div id=whiteboard-container></div>" ;
this.registerFileActions() ;
},
setupContainer: function() {
$('#content')
.add(this.contenair)
.addClass("viewer-mode")
.addClass("no-sidebar") ;
},
......@@ -39,11 +50,11 @@ whiteboardApp = {
OCA.Files.fileActions.registerAction({
name: 'Edit',
mime: "application/wbr",
actionHandler: self.editAction,
permissions: OC.PERMISSION_READ,
icon: function () {
return OC.imagePath('core', 'actions/edit');
}
},
actionHandler: self.editAction
}) ;
OCA.Files.fileActions.setDefault("application/wbr", 'Edit');
......@@ -53,13 +64,69 @@ whiteboardApp = {
//edit
editAction: function(filename,context) {
dir = context.dir ;
var ncClient = OC.Files.getClient();
//self.setupContainer() ;
var closebtn ="<div id=closebtn class=icon-close><div>" ;
var contenair = "<div id=whiteboard-container></div>" ;
$('#content')
.append(contenair)
.addClass("viewer-mode")
.addClass("no-sidebar") ;
import(/* webpackChunkName: "literallycanvas" */ "literallycanvas").then(LC => {
var WB= LC.init(
document.getElementById('whiteboard-container'),
{
imageURLPrefix: '/stable18/apps/whiteboard/img/lc_assets' ,
toolbarPosition: 'top'
}
);
// create close button
$('#whiteboard-container') .append(closebtn) ;
$("#closebtn").click(function(){
WB.teardown() ;
$('#whiteboard-container').remove() ;
$('#content').removeClass("viewer-mode").removeClass("no-sidebard") ;
}) ;
//load whiteboard
var url = OC.generateUrl('apps/whiteboard/file/load');
$.ajax({
type: 'GET',
url: url,
data: {path: context.dir + "/" + filename }
}).done(function(content){
console.log("loading done") ;
WB.loadSnapshot(JSON.parse(content)) ;
})
// set save callback
WB.on('drawingChange', function() {
console.log("Save WB ...") ;
var url = OC.generateUrl('apps/whiteboard/file/save');
console.log(url) ;
var putObject = {
content: JSON.stringify(WB.getSnapshot()),
path: context.dir + "/" + filename
};
$.ajax({
type: 'POST',
url: url,
data: putObject
})
}) ;
}) ;
fo = ncClient.getFileInfo(dir + "/" + filename) ;
console.log( fo) ;
}
} ;
......@@ -104,3 +171,6 @@ $(document).ready(function () {
});
__webpack_nonce__ = btoa(OC.requestToken)
__webpack_public_path__ = OC.linkTo('whiteboard', 'js/');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment