diff --git a/css/style.scss b/css/style.scss index fc36e81c6..ed959e35f 100644 --- a/css/style.scss +++ b/css/style.scss @@ -653,6 +653,31 @@ input.input-inline { } } +.drop-indicator { + display: none; +} +.file-drop .drop-indicator { + display: block; + position: absolute; + width: 100%; + height: calc(100% - 40px); + background-color: #fff; + z-index: 100; + opacity: 0.9; + text-align: center; + margin-top: 40px; + + p { + width: calc(100% - 20px); + height: calc(100% - 20px); + position: absolute; + padding: 20px; + border: 1px dashed #AAA; + margin: 10px; + border-radius: 5px; + } +} + #card-meta { // TODO: use .card-block instead? height: 100%; display: flex; @@ -750,6 +775,54 @@ input.input-inline { } } + .card-attachments { + ul { + li.attachment { + display: flex; + + .fileicon { + display: inline-block; + min-width: 32px; + width: 32px; + height: 32px; + background-size: contain; + } + .details { + flex-grow: 1; + flex-shrink: 1; + min-width: 0; + flex-basis: 50%; + line-height: 110%; + padding: 2px; + } + .filename { + width: 70%; + display: flex; + .basename { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .extension { + opacity: 0.7; + } + } + .filesize, .filedate { + font-size: 90%; + color: $color-darkgrey; + } + .app-popover-menu-utils { + position: relative; + button { + height: 32px; + width: 40px; + } + } + } + } + + } + .card-description { &.section-header { .save-indicator { diff --git a/js/controller/CardController.js b/js/controller/CardController.js index f35a38817..171bb641d 100644 --- a/js/controller/CardController.js +++ b/js/controller/CardController.js @@ -23,7 +23,7 @@ /* global app moment */ import app from '../app/App.js'; -app.controller('CardController', function ($scope, $rootScope, $sce, $location, $stateParams, $interval, $timeout, $filter, BoardService, CardService, StackService, StatusService, markdownItConverter) { +app.controller('CardController', function ($scope, $rootScope, $sce, $location, $stateParams, $interval, $timeout, $filter, BoardService, CardService, StackService, StatusService, markdownItConverter, FileUploader) { $scope.sidebar = $rootScope.sidebar; $scope.status = { lastEdit: 0, @@ -36,6 +36,59 @@ app.controller('CardController', function ($scope, $rootScope, $sce, $location, $scope.statusservice = StatusService.getInstance(); $scope.boardservice = BoardService; + $scope.uploader = new FileUploader(); + + $scope.runUpload = function(fileItem) { + fileItem.url = OC.generateUrl('/apps/deck/cards/' + $scope.cardId + '/attachment'); + fileItem.formData = [ + { + requesttoken: oc_requesttoken, + type: 'deck_file', + + } + ]; + $scope.uploader.uploadItem(fileItem); + }; + $scope.uploader.onAfterAddingFile = function(fileItem) { + console.log(fileItem); + let existingFile = $scope.cardservice.getCurrent().attachments.find((attachment) => { + return attachment.data === fileItem.file.name; + }); + console.log(existingFile); + if (typeof existingFile !== 'undefined') { + OC.dialogs.confirm( + `A file with the name ${fileItem.file.name} already exists. Do you want to overwrite it?`, + 'File already exists', + function(result) { + if (result) { + $scope.runUpload(fileItem) + } else { + // TODO: check for proper number and append it before the file extension + fileItem.file.name = fileItem.file.name + '.1'; + } + } + ); + } else { + $scope.runUpload(fileItem) + } + }; + $scope.uploader.onSuccessItem = function(item, response) { + $scope.cardservice.getCurrent().attachments.push(response); + }; + + $scope.mimetypeForAttachment = function(attachment) { + let url = OC.MimeType.getIconUrl(attachment.extendedData.mimetype); + let style = { + 'background-image': `url("${url}")`, + }; + return style; + }; + $scope.attachmentUrl = function(attachment) { + let cardId = $scope.cardservice.getCurrent().id; + let attachmentId = attachment.id; + return OC.generateUrl(`/apps/deck/cards/${cardId}/attachment/${attachmentId}`); + }; + $scope.statusservice.retainWaiting(); $scope.description = function() { diff --git a/js/filters/bytesFilter.js b/js/filters/bytesFilter.js new file mode 100644 index 000000000..ee81e16f7 --- /dev/null +++ b/js/filters/bytesFilter.js @@ -0,0 +1,37 @@ +/* + * @copyright Copyright (c) 2018 Julius Härtl + * + * @author Julius Härtl + * + * @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 . + * + */ + +import app from '../app/App.js'; + +app.filter('bytes', function () { + return function (bytes, precision) { + if (isNaN(parseFloat(bytes, 10)) || !isFinite(bytes)) { + return '-'; + } + if (precision === undefined) { + precision = 2; + } + var units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'], + number = Math.floor(Math.log(bytes) / Math.log(1024)); + return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number]; + }; +}); \ No newline at end of file diff --git a/js/service/CardService.js b/js/service/CardService.js index fc33e8e06..7e4f6c393 100644 --- a/js/service/CardService.js +++ b/js/service/CardService.js @@ -133,6 +133,20 @@ app.factory('CardService', function (ApiService, $http, $q) { return deferred.promise; }; + CardService.prototype.attachmentRemove = function (attachment) { + var deferred = $q.defer(); + var self = this; + $http.delete(this.baseUrl + '/' + this.getCurrent().id + '/attachment/' + attachment.id, {}).then(function (response) { + self.getCurrent().attachments = self.getCurrent().attachments.filter(function (obj) { + return obj.id !== attachment.id; + }); + deferred.resolve(response.data); + }, function (error) { + deferred.reject('Error when removing the attachment'); + }); + return deferred.promise; + }; + var service = new CardService($http, 'cards', $q); return service; }); \ No newline at end of file diff --git a/templates/part.card.php b/templates/part.card.php index a0684b638..90b8e6cf6 100644 --- a/templates/part.card.php +++ b/templates/part.card.php @@ -1,4 +1,8 @@ -
+
+
+

t('Drop your files here to upload it to the card')); ?>

+
+
t('Status')); ?>

{{ statusservice.title }}

@@ -83,6 +87,43 @@
+
+

t('Attachments')); ?>

+ + +
+ + +