From 38d54348ca28981a545bac1e3c846bdfc82e0894 Mon Sep 17 00:00:00 2001 From: Daria Voytova Date: Wed, 9 Nov 2016 15:11:05 +0300 Subject: [PATCH 01/18] Add button for uploading cover photo --- branding/client/branding.html | 1 + 1 file changed, 1 insertion(+) diff --git a/branding/client/branding.html b/branding/client/branding.html index ee90fbfc80..619d700ff0 100644 --- a/branding/client/branding.html +++ b/branding/client/branding.html @@ -14,6 +14,7 @@

{{# if branding }} {{> viewProjectLogo branding=branding }} {{> uploadProjectLogo branding=branding }} + {{> uploadCoverPhoto branding=branding }} {{# autoForm id="brandingEdit" type="update" From 21391fee72e9cdd091fc069597aaee9813c86518 Mon Sep 17 00:00:00 2001 From: Daria Voytova Date: Wed, 9 Nov 2016 15:12:09 +0300 Subject: [PATCH 02/18] Add field in branding collection for saving cover photo ID --- branding/collection/schema.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/branding/collection/schema.js b/branding/collection/schema.js index d9d90e337e..cd1a0d279b 100644 --- a/branding/collection/schema.js +++ b/branding/collection/schema.js @@ -6,6 +6,10 @@ Branding.schema = new SimpleSchema({ type: String, optional: true, }, + coverPhotoFileId: { + type: String, + optional: true, + }, colors: { type: Object, optional: true, From 56daa3138eee56bf847332309d427d5026e23d7c Mon Sep 17 00:00:00 2001 From: Daria Voytova Date: Wed, 9 Nov 2016 15:14:24 +0300 Subject: [PATCH 03/18] Cover photo collection, permissions, publication --- branding/cover_photo/collection/index.js | 19 +++++++++++++++++++ .../collection/server/permissions.js | 19 +++++++++++++++++++ branding/cover_photo/server/publications.js | 12 ++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 branding/cover_photo/collection/index.js create mode 100644 branding/cover_photo/collection/server/permissions.js create mode 100644 branding/cover_photo/server/publications.js diff --git a/branding/cover_photo/collection/index.js b/branding/cover_photo/collection/index.js new file mode 100644 index 0000000000..0acf21bb78 --- /dev/null +++ b/branding/cover_photo/collection/index.js @@ -0,0 +1,19 @@ +// Import Meteor packages +import { FileCollection } from 'meteor/vsivsi:file-collection'; + +const CoverPhoto = new FileCollection('CoverPhoto', { + resumable: true, // Enable built-in resumable.js upload support + http: [ + { method: 'get', + // this will be at route "/gridfs/CoverPhoto/md5/:md5" + path: '/md5/:md5', + // uses express style url params + // a query mapping url to CoverPhoto + lookup: function (params) { + return { md5: params.md5 }; + }, + }, + ], +}); + +export default CoverPhoto; diff --git a/branding/cover_photo/collection/server/permissions.js b/branding/cover_photo/collection/server/permissions.js new file mode 100644 index 0000000000..ecc7a929ce --- /dev/null +++ b/branding/cover_photo/collection/server/permissions.js @@ -0,0 +1,19 @@ +// Import meteor package +import { Roles } from 'meteor/alanning:roles'; +// Import apinf collection +import CoverPhoto from '/branding/cover_photo/collection'; + +CoverPhoto.allow({ + insert: function (userId) { + return Roles.userIsInRole(userId, ['admin']); + }, + remove: function (userId) { + return Roles.userIsInRole(userId, ['admin']); + }, + read: function () { + return true; + }, + write: function () { + return true; + }, +}); diff --git a/branding/cover_photo/server/publications.js b/branding/cover_photo/server/publications.js new file mode 100644 index 0000000000..19839d40a4 --- /dev/null +++ b/branding/cover_photo/server/publications.js @@ -0,0 +1,12 @@ +// Import Meteor package +import { Meteor } from 'meteor/meteor'; +// Import apinf collection +import CoverPhoto from '/branding/cover_photo/collection'; + +Meteor.publish('coverPhoto', () => { + return CoverPhoto.find({ + 'metadata._Resumable': { + $exists: false, + }, + }); +}); From 0533ad89d26bb5b8dbb534f8bb5e9f253c40b426 Mon Sep 17 00:00:00 2001 From: Daria Voytova Date: Wed, 9 Nov 2016 15:17:48 +0300 Subject: [PATCH 04/18] Show button for uploading or deletion button, handlers for them, css --- branding/cover_photo/client/upload/upload.css | 3 + .../cover_photo/client/upload/upload.html | 22 ++++++ branding/cover_photo/client/upload/upload.js | 69 +++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 branding/cover_photo/client/upload/upload.css create mode 100644 branding/cover_photo/client/upload/upload.html create mode 100644 branding/cover_photo/client/upload/upload.js diff --git a/branding/cover_photo/client/upload/upload.css b/branding/cover_photo/client/upload/upload.css new file mode 100644 index 0000000000..d9248804f5 --- /dev/null +++ b/branding/cover_photo/client/upload/upload.css @@ -0,0 +1,3 @@ +.cover-photo-file { + margin-bottom: 1em; +} diff --git a/branding/cover_photo/client/upload/upload.html b/branding/cover_photo/client/upload/upload.html new file mode 100644 index 0000000000..8b287a3a8b --- /dev/null +++ b/branding/cover_photo/client/upload/upload.html @@ -0,0 +1,22 @@ + diff --git a/branding/cover_photo/client/upload/upload.js b/branding/cover_photo/client/upload/upload.js new file mode 100644 index 0000000000..4ab094a3fe --- /dev/null +++ b/branding/cover_photo/client/upload/upload.js @@ -0,0 +1,69 @@ +// Import meteor packages +import { Template } from 'meteor/templating'; +import { Mongo } from 'meteor/mongo'; +import { ReactiveVar } from 'meteor/reactive-var'; +import { TAPi18n } from 'meteor/tap:i18n'; +import { sAlert } from 'meteor/juliancwirko:s-alert'; +// Import apinf collections +import { Branding } from '/branding/collection'; +import CoverPhoto from '/branding/cover_photo/collection'; + +const uploadingSpinner = new ReactiveVar(false); + +Template.uploadCoverPhoto.onCreated(function () { + const instance = this; + + // Subscribe to Branding collection + instance.subscribe('branding'); + // Subscribe to Cover Photo collection + instance.subscribe('coverPhoto'); + // Turn off spinner if it was on + uploadingSpinner.set(false); +}); + +Template.uploadCoverPhoto.helpers({ + uploadedCoverPhotoFile () { + // Get cover photo ID + const currentCoverPhotoFileId = this.branding.coverPhotoFileId; + + // Convert to Mongo ObjectID + const objectId = new Mongo.Collection.ObjectID(currentCoverPhotoFileId); + + // Check if cover photo file is available + return CoverPhoto.findOne(objectId); + }, + spinnerEnabled () { + // Get value of spinner + return uploadingSpinner.get(); + }, +}); + +Template.uploadCoverPhoto.events({ + 'click .delete-cover-photo': function () { + // Show confirmation dialog to user + const confirmation = confirm(TAPi18n.__('uploadCoverPhoto_confirm_delete')); + + // Check if user clicked "OK" + if (confirmation) { + // Get cover photo file id from branding + const coverPhotoFileId = this.branding.coverPhotoFileId; + + // Convert to Mongo ObjectID + const objectId = new Mongo.Collection.ObjectID(coverPhotoFileId); + + // Remove the cover photo object + CoverPhoto.remove(objectId); + + // Remove the cover photo file id field + Branding.update(this.branding._id, { $unset: { coverPhotoFileId: '' } }); + + // Get deletion success message translation + const message = TAPi18n.__('uploadCoverPhoto_successfully_deleted'); + + // Alert user of successful delete + sAlert.success(message); + } + }, +}); + +export default uploadingSpinner; From 59c91629381a2f0353a676aba656aed3b5775bac Mon Sep 17 00:00:00 2001 From: Daria Voytova Date: Wed, 9 Nov 2016 15:18:25 +0300 Subject: [PATCH 05/18] Upload button, handlers for it --- .../client/upload/uploadButton/uploadButton.html | 5 +++++ .../client/upload/uploadButton/uploadButton.js | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 branding/cover_photo/client/upload/uploadButton/uploadButton.html create mode 100644 branding/cover_photo/client/upload/uploadButton/uploadButton.js diff --git a/branding/cover_photo/client/upload/uploadButton/uploadButton.html b/branding/cover_photo/client/upload/uploadButton/uploadButton.html new file mode 100644 index 0000000000..9630b913d0 --- /dev/null +++ b/branding/cover_photo/client/upload/uploadButton/uploadButton.html @@ -0,0 +1,5 @@ + diff --git a/branding/cover_photo/client/upload/uploadButton/uploadButton.js b/branding/cover_photo/client/upload/uploadButton/uploadButton.js new file mode 100644 index 0000000000..ee49f6d31a --- /dev/null +++ b/branding/cover_photo/client/upload/uploadButton/uploadButton.js @@ -0,0 +1,9 @@ +// Import meteor packages +import { Template } from 'meteor/templating'; +// Import apinf collections +import CoverPhoto from '/branding/cover_photo/collection'; + +Template.uploadCoverPhotoButton.onRendered(function() { + // Assign resumable browse to element + CoverPhoto.resumable.assignBrowse($('#cover-photo-browse')); +}); From b27a63f66174eefe21d613e0dfe93a8ae91ce27e Mon Sep 17 00:00:00 2001 From: Daria Voytova Date: Wed, 9 Nov 2016 15:18:53 +0300 Subject: [PATCH 06/18] Handler for upload process --- .../cover_photo/client/upload/resumable.js | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 branding/cover_photo/client/upload/resumable.js diff --git a/branding/cover_photo/client/upload/resumable.js b/branding/cover_photo/client/upload/resumable.js new file mode 100644 index 0000000000..a2c000633e --- /dev/null +++ b/branding/cover_photo/client/upload/resumable.js @@ -0,0 +1,61 @@ +// Import meteor packages +import { Meteor } from 'meteor/meteor'; +import { sAlert } from 'meteor/juliancwirko:s-alert'; +import { TAPi18n } from 'meteor/tap:i18n'; + +// Import apinf collections +import { Branding } from '/branding/collection'; +import CoverPhoto from '/branding/cover_photo/collection'; +import { fileNameEndsWith } from '/core/helper_functions/file_name_ends_with'; +import uploadingSpinner from './upload'; + +Meteor.startup(function () { + // Set cover photo id to branding collection on Success + CoverPhoto.resumable.on('fileSuccess', function (file) { + // Turn off spinner + uploadingSpinner.set(false); + + // Get the id from project logo file object + const coverPhotoFileId = file.uniqueIdentifier; + + // Get branding + const branding = Branding.findOne(); + + // Update logo id field + Branding.update(branding._id, { $set: { coverPhotoFileId } }); + + // Get upload success message translation + const message = TAPi18n.__('uploadCoverPhoto_successfully_uploaded'); + + // Alert user of successful upload + sAlert.success(message); + }); + + CoverPhoto.resumable.on('fileAdded', function (file) { + return CoverPhoto.insert({ + _id: file.uniqueIdentifier, + filename: file.fileName, + contentType: file.file.type, + }, function (err) { + if (err) { + console.warn('File creation failed!', err); + return; + } + + const acceptedExtensions = ['jpg', 'jpeg', 'png', 'gif']; + + if (fileNameEndsWith(file.file.name, acceptedExtensions)) { + // Turn on spinner + uploadingSpinner.set(true); + // Upload the cover photo + return CoverPhoto.resumable.upload(); + } + + // Get extension error message + const message = TAPi18n.__('uploadCoverPhoto_acceptedExtensions'); + + // Alert user of extension error + sAlert.error(message); + }); + }); +}); From 674f068b88b0d78b8e572002e5def9945f655daa Mon Sep 17 00:00:00 2001 From: Daria Voytova Date: Wed, 9 Nov 2016 15:24:45 +0300 Subject: [PATCH 07/18] Display cover photo, handler --- home/client/body/homeBody.html | 2 +- home/client/body/homeBody.js | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/home/client/body/homeBody.html b/home/client/body/homeBody.html index 72e6c2183c..28d533fc39 100755 --- a/home/client/body/homeBody.html +++ b/home/client/body/homeBody.html @@ -1,5 +1,5 @@