From 4e08d8342e8582e8001df31ff6e56f40d20ccc40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?=
 <skjnldsv@protonmail.com>
Date: Sat, 14 Jul 2018 11:45:04 +0200
Subject: [PATCH] UI set share note!
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
---
 apps/files_sharing/css/sharetabview.scss |  21 ++++
 core/js/core.json                        |   1 +
 core/js/merged-share-backend.json        |   1 +
 core/js/sharedialognoteview.js           | 149 +++++++++++++++++++++++
 core/js/sharedialogshareelistview.js     |  21 ++++
 core/js/sharedialogview.js               |   9 ++
 6 files changed, 202 insertions(+)
 create mode 100644 core/js/sharedialognoteview.js

diff --git a/apps/files_sharing/css/sharetabview.scss b/apps/files_sharing/css/sharetabview.scss
index b4b64daff2b..28cae27d405 100644
--- a/apps/files_sharing/css/sharetabview.scss
+++ b/apps/files_sharing/css/sharetabview.scss
@@ -131,6 +131,7 @@
 	display: none !important;
 }
 
+form#newNoteForm,
 .linkShareView {
 	margin-top: 16px;
 }
@@ -142,3 +143,23 @@
 .shareTabView .icon {
 	background-size: 16px 16px;
 }
+
+
+/* NOTE */
+form#newNoteForm {
+	display: flex;
+	flex-wrap: wrap;
+	.message {
+		flex: 1 1;
+		min-height: 76px;
+		margin-right: 0;
+		border-bottom-right-radius: 0;
+		border-top-right-radius: 0;
+	}
+	input {
+		width: 44px;
+		border-bottom-left-radius: 0;
+		border-top-left-radius: 0;
+		margin-left: -1px;
+	}
+}
\ No newline at end of file
diff --git a/core/js/core.json b/core/js/core.json
index 502e3a57976..6a6249c294b 100644
--- a/core/js/core.json
+++ b/core/js/core.json
@@ -38,6 +38,7 @@
 		"shareitemmodel.js",
 		"sharedialogview.js",
 		"sharedialogexpirationview.js",
+		"sharedialognoteview.js",
 		"sharedialoglinkshareview.js",
 		"sharedialogresharerinfoview.js",
 		"sharedialogshareelistview.js",
diff --git a/core/js/merged-share-backend.json b/core/js/merged-share-backend.json
index d39945b8f79..48ad5d5340c 100644
--- a/core/js/merged-share-backend.json
+++ b/core/js/merged-share-backend.json
@@ -5,6 +5,7 @@
   "sharedialogresharerinfoview.js",
   "sharedialoglinkshareview.js",
   "sharedialogexpirationview.js",
+  "sharedialognoteview.js",
   "sharedialogshareelistview.js",
   "sharedialogview.js",
   "share.js"
diff --git a/core/js/sharedialognoteview.js b/core/js/sharedialognoteview.js
new file mode 100644
index 00000000000..429d9cd942b
--- /dev/null
+++ b/core/js/sharedialognoteview.js
@@ -0,0 +1,149 @@
+/*
+ * @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @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/>.
+ *
+ */
+
+/* global moment, Handlebars */
+
+(function() {
+	if (!OC.Share) {
+		OC.Share = {};
+	}
+
+	var TEMPLATE =
+		'	<form id="newNoteForm" data-shareId="{{shareId}}">' +
+		'		<textarea class="message" placeholder="{{placeholder}}">{{note}}</textarea>' +
+		'		<input class="submit icon-confirm has-tooltip" type="submit" value="" title="{{submitText}}"/>' +
+		'	</form>' +
+		'	<div class="error hidden">{{error}}</div>'
+	;
+
+	/**
+	 * @class OCA.Share.ShareDialogNoteView
+	 * @member {OC.Share.ShareItemModel} model
+	 * @member {jQuery} $el
+	 * @memberof OCA.Sharing
+	 * @classdesc
+	 *
+	 * Represents the expiration part in the GUI of the share dialogue
+	 *
+	 */
+	var ShareDialogNoteView = OC.Backbone.View.extend({
+
+		id: 'shareNote',
+
+		className: 'hidden',
+
+		shareId: undefined,
+
+		events: {
+			'submit #newNoteForm': '_onSubmitComment'
+		},
+
+		_onSubmitComment: function(e) {
+			var self = this;
+			var $form = $(e.target);
+			var $submit = $form.find('.submit');
+			var $commentField = $form.find('.message');
+			var $error = $form.siblings('.error');
+			var message = $commentField.val().trim();
+			e.preventDefault();
+
+			if (message.length < 1) {
+				return;
+			}
+
+			$submit.prop('disabled', true);
+			$form.addClass('icon-loading').prop('disabled', true);
+
+			// send data
+			$.ajax({
+				method: 'PUT',
+				url: OC.generateUrl('/ocs/v2.php/apps/files_sharing/api/v1/shares/' + self.shareId),
+				data: { note: message },
+				complete : function() {
+					$submit.prop('disabled', false);
+					$form.removeClass('icon-loading').prop('disabled', false);
+				},
+				error: function() {
+					$error.show();
+					setTimeout(function() {
+						$error.hide();
+					}, 3000);
+				}
+			});
+
+			// update local js object
+			var shares = this.model.get('shares');
+			var share = shares.filter(function (share) {
+				return share.id === self.shareId;
+			});
+			share[0].note = message;
+
+			return message;
+		},
+
+		render: function(shareId) {
+			this.shareId = shareId;
+			var shares = this.model.get('shares');
+			if (!shares) {
+				return;
+			}
+			var share = shares.filter(function (share) {
+				return share.id === shareId;
+			});
+			if (share.length !== 1) {
+				// should not happend
+				return;
+			}
+			this.$el.show();
+			this.$el.html(this.template({
+				note: share[0].note,
+				submitText: t('core', 'Submit the note'),
+				placeholder: t('core', 'Add a note…'),
+				error: t('core', 'An error has occured. Unable to save the note.'),
+				shareId: shareId
+			}));
+
+			this.delegateEvents();
+
+			return this;
+		},
+
+		hide() {
+			this.$el.hide();
+		},
+
+		/**
+		 * @returns {Function} from Handlebars
+		 * @private
+		 */
+		template: function (data) {
+			if (!this._template) {
+				this._template = Handlebars.compile(TEMPLATE);
+			}
+			return this._template(data);
+		}
+
+	});
+
+	OC.Share.ShareDialogNoteView = ShareDialogNoteView;
+
+})();
diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js
index 53a65fcdf7a..af4abce17b6 100644
--- a/core/js/sharedialogshareelistview.js
+++ b/core/js/sharedialogshareelistview.js
@@ -120,6 +120,9 @@
 						'</div>' +
 					'</span>' +
 				'</li>' +
+				'<li>' +
+					'<a href="#" class="addnote"><span class="icon-loading-small hidden"></span><span class="icon icon-edit"></span><span>{{addNoteLabel}}</span></a>' +
+				'</li>' +
 				'<li>' +
 					'<a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span>{{unshareLabel}}</span></a>' +
 				'</li>' +
@@ -154,8 +157,11 @@
 		/** @type {boolean|number} **/
 		_renderPermissionChange: false,
 
+		_noteView: undefined,
+
 		events: {
 			'click .unshare': 'onUnshare',
+			'click .addnote': 'showNoteForm',
 			'click .icon-more': 'onToggleMenu',
 			'click .permissions': 'onPermissionChange',
 			'click .expireDate' : 'onExpireDateChange',
@@ -178,6 +184,8 @@
 			this.model.on('change:shares', function() {
 				view.render();
 			});
+
+			this._noteView = options.parent.noteView;
 		},
 
 		/**
@@ -269,6 +277,7 @@
 		getShareProperties: function() {
 			return {
 				unshareLabel: t('core', 'Unshare'),
+				addNoteLabel: t('core', 'Set share note'),
 				canShareLabel: t('core', 'Can reshare'),
 				canEditLabel: t('core', 'Can edit'),
 				createPermissionLabel: t('core', 'Can create'),
@@ -470,6 +479,16 @@
 			return this._popoverMenuTemplate(data);
 		},
 
+		showNoteForm(event) {
+			event.preventDefault();
+			event.stopPropagation();
+			var self = this;
+			var $element = $(event.target);
+			var $li = $element.closest('li[data-share-id]');
+			var shareId = $li.data('share-id');
+			this._noteView.render(shareId);
+		},
+
 		onUnshare: function(event) {
 			event.preventDefault();
 			event.stopPropagation();
@@ -493,6 +512,8 @@
 			self.model.removeShare(shareId)
 				.done(function() {
 					$li.remove();
+					// remove note field on sucess
+					self._noteView.hide();
 				})
 				.fail(function() {
 					$loading.addClass('hidden');
diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js
index d886e45856f..4b5dc80e945 100644
--- a/core/js/sharedialogview.js
+++ b/core/js/sharedialogview.js
@@ -28,6 +28,7 @@
 		'<div class="shareeListView subView"></div>' +
 		'<div class="linkShareView subView"></div>' +
 		'<div class="expirationView subView"></div>' +
+		'<div class="noteView subView"></div>' +
 		'<div class="loading hidden" style="height: 50px"></div>';
 
 	/**
@@ -62,6 +63,9 @@
 		/** @type {object} **/
 		expirationView: undefined,
 
+		/** @type {object} **/
+		noteView: undefined,
+
 		/** @type {object} **/
 		shareeListView: undefined,
 
@@ -105,6 +109,7 @@
 
 			var subViewOptions = {
 				model: this.model,
+				parent: this,
 				configModel: this.configModel
 			};
 
@@ -112,6 +117,7 @@
 				resharerInfoView: 'ShareDialogResharerInfoView',
 				linkShareView: 'ShareDialogLinkShareView',
 				expirationView: 'ShareDialogExpirationView',
+				noteView: 'ShareDialogNoteView',
 				shareeListView: 'ShareDialogShareeListView'
 			};
 
@@ -674,6 +680,9 @@
 			this.expirationView.$el = this.$el.find('.expirationView');
 			this.expirationView.render();
 
+			this.noteView.$el = this.$el.find('.noteView');
+			this.noteView.render();
+
 			this.shareeListView.$el = this.$el.find('.shareeListView');
 			this.shareeListView.render();
 
-- 
GitLab