summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2015-07-15 16:09:00 +0200
committerArthur Schiwon <blizzz@owncloud.com>2015-08-07 01:22:42 +0200
commit12e5f310ddb784c0ed1248020b770d93040918da (patch)
tree6bfc053ff77ba25f238fef59fe3eb0c358269dc8 /apps
parent9854e71d2c83bd5f74a4798be1547e75112d5a41 (diff)
downloadnextcloud-server-12e5f310ddb784c0ed1248020b770d93040918da.tar.gz
nextcloud-server-12e5f310ddb784c0ed1248020b770d93040918da.zip
Improved right sidebar
Added owner info. Added animation, but causes scrollbal. Default file action now when clicking on name directly. Fixed icon. Added empty share tab.
Diffstat (limited to 'apps')
-rw-r--r--apps/files/css/detailsView.css30
-rw-r--r--apps/files/index.php2
-rw-r--r--apps/files/js/detailsview.js45
-rw-r--r--apps/files/js/detailtabview.js25
-rw-r--r--apps/files/js/filelist.js118
-rw-r--r--apps/files/js/mainfileinfodetailview.js48
-rw-r--r--apps/files_sharing/js/share.js7
-rw-r--r--apps/files_sharing/js/sharedetailview.js63
-rw-r--r--apps/files_sharing/js/sharetabview.js64
9 files changed, 328 insertions, 74 deletions
diff --git a/apps/files/css/detailsView.css b/apps/files/css/detailsView.css
index 783a8c9b0c3..0bbdfe94903 100644
--- a/apps/files/css/detailsView.css
+++ b/apps/files/css/detailsView.css
@@ -1,19 +1,45 @@
+#app-content-files .detailsView.disappear {
+ margin-right: -300px;
+}
+
#app-content-files .detailsView {
position: absolute;
width: 300px;
top: 44px;
bottom: 0;
right: 0;
+ left: auto;
background-color: white;
border: 1px solid black;
+ -webkit-transition: margin-right 300ms;
+ -moz-transition: margin-right 300ms;
+ -o-transition: margin-right 300ms;
+ transition: margin-right 300ms;
+}
+
+#app-content-files .detailsView .detailFileInfoContainer {
+ min-height: 200px;
+ padding: 10px;
+}
+
+#app-content-files .detailsView .detailFileInfoContainer > div{
+ clear: both;
+ margin-left: 5px;
}
#app-content-files .detailsView .thumbnail {
- width: 32px;
- height: 32px;
+ width: 50px;
+ height: 50px;
float: left;
+ margin: 5px;
+ background-size: 50px;
+}
+
+#app-content-files .detailsView .fileName {
+ font-weight: bold;
+ font-size: 17px;
}
#app-content-files .detailsView .detailList {
diff --git a/apps/files/index.php b/apps/files/index.php
index 1cb7c16ce6b..dca3e5ae74d 100644
--- a/apps/files/index.php
+++ b/apps/files/index.php
@@ -52,8 +52,8 @@ OCP\Util::addscript('files', 'search');
\OCP\Util::addScript('files', 'detailfileinfoview');
\OCP\Util::addScript('files', 'detailtabview');
-\OCP\Util::addScript('files', 'detailsview');
\OCP\Util::addScript('files', 'mainfileinfodetailview');
+\OCP\Util::addScript('files', 'detailsview');
\OCP\Util::addStyle('files', 'detailsView');
\OC_Util::addVendorScript('core', 'handlebars/handlebars');
diff --git a/apps/files/js/detailsview.js b/apps/files/js/detailsview.js
index a8abac5c68f..719299485a6 100644
--- a/apps/files/js/detailsview.js
+++ b/apps/files/js/detailsview.js
@@ -14,14 +14,14 @@
'<div>' +
' <div class="detailFileInfoContainer">' +
' </div>' +
- ' <div class="tabHeadsContainer">' +
- ' </div>' +
- ' <div class="tabContentsContainer">' +
+ ' <div class="tabsContainer">' +
+ ' <ul class="tabHeadsContainer">' +
+ ' </ul>' +
' </div>' +
'</div>';
var TEMPLATE_TAB_HEADER =
- '<div class="tabHeaders">{{label}}</div>';
+ '<li class="tabHeaders"><a href="#{{tabId}}">{{label}}</a></li>';
/**
* @class OCA.Files.DetailsView
@@ -33,6 +33,7 @@
var DetailsView = function() {
this.initialize();
};
+
/**
* @memberof OCA.Files
*/
@@ -90,6 +91,7 @@
* Renders this details view
*/
render: function() {
+ var self = this;
this.$el.empty();
if (!this._template) {
@@ -101,30 +103,37 @@
}
var $el = $(this._template());
+ var $tabsContainer = $el.find('.tabsContainer');
var $tabHeadsContainer = $el.find('.tabHeadsContainer');
- var $tabsContainer = $el.find('.tabContentsContainer');
var $detailsContainer = $el.find('.detailFileInfoContainer');
- // render tabs
- _.each(this._tabs, function(tabView) {
- tabView.render();
- // hidden by default
- tabView.$el.addClass('hidden');
- $tabsContainer.append(tabView.$el);
-
- $tabHeadsContainer.append(this._templateTabHeader({label: tabView.getLabel()}));
- });
-
// render details
_.each(this._detailFileInfoViews, function(detailView) {
detailView.render();
$detailsContainer.append(detailView.$el);
});
- // select first tab
- $el.find('.tabContentsContainer:first').removeClass('hidden');
+ if (this._tabViews.length > 0) {
+ // render tabs
+ _.each(this._tabViews, function(tabView) {
+ tabView.render();
+ // hidden by default
+ $tabsContainer.append(tabView.$el);
+
+ $tabHeadsContainer.append(self._templateTabHeader({
+ tabId: tabView.getId(),
+ label: tabView.getLabel()
+ }));
+ });
+ }
+
+ // TODO: select current tab
this.$el.append($el);
+
+ if (this._tabViews.length > 0) {
+ $tabsContainer.tabs({});
+ }
},
/**
@@ -136,7 +145,7 @@
this._fileInfo = fileInfo;
// notify all panels
- _.each(this._tabs, function(tabView) {
+ _.each(this._tabViews, function(tabView) {
tabView.setFileInfo(fileInfo);
});
_.each(this._detailFileInfoViews, function(detailView) {
diff --git a/apps/files/js/detailtabview.js b/apps/files/js/detailtabview.js
index f630099111d..767ece2297c 100644
--- a/apps/files/js/detailtabview.js
+++ b/apps/files/js/detailtabview.js
@@ -17,8 +17,8 @@
* Base class for tab views to display file information.
*
*/
- var DetailTabView = function() {
- this.initialize();
+ var DetailTabView = function(id) {
+ this.initialize(id);
};
/**
@@ -51,9 +51,16 @@
/**
* Initialize the details view
+ *
+ * @param {string} id tab id
*/
- initialize: function() {
+ initialize: function(id) {
+ if (!id) {
+ throw 'Argument "id" is required';
+ }
+ this._id = id;
this.$el = $('<div class="detailTabView"></div>');
+ this.$el.attr('id', id);
},
/**
@@ -66,6 +73,15 @@
},
/**
+ * Returns the tab element id
+ *
+ * @return {string} tab id
+ */
+ getId: function() {
+ return this._id;
+ },
+
+ /**
* Returns the tab label
*
* @return {String} label
@@ -81,6 +97,9 @@
*/
render: function() {
// to be implemented in subclass
+ // FIXME: code is only for testing
+ this.$el.empty();
+ this.$el.append('<div>Hello ' + this._id + '</div>');
},
/**
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index cbf946974eb..355c76f9c64 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -221,6 +221,13 @@
this.updateSearch();
+ this.$el.on('click', function(event) {
+ var $target = $(event.target);
+ // click outside file row ?
+ if (!$target.closest('tbody').length) {
+ self._updateDetailsView(null);
+ }
+ });
this.$fileList.on('click','td.filename>a.name', _.bind(this._onClickFile, this));
this.$fileList.on('change', 'td.filename>.selectCheckBox', _.bind(this._onClickFileCheckbox, this));
this.$el.on('urlChanged', _.bind(this._onUrlChanged, this));
@@ -273,17 +280,35 @@
* @param {OCA.Files.FileInfo} fileInfo file info to display
*/
_updateDetailsView: function(fileInfo) {
+ var self = this;
+ if (!fileInfo) {
+ if (this._detailsView) {
+ // hide it
+ this._detailsView.$el.addClass('disappear');
+ this._detailsView.setFileInfo(null);
+ }
+ return;
+ }
+
if (!this._detailsView) {
this._detailsView = new OCA.Files.DetailsView();
- this.$el.append(this._detailsView.$el);
-
this._detailsView.addDetailView(new OCA.Files.MainFileInfoDetailView());
-
+ _.each(this._detailFileInfoViews, function(view) {
+ self._detailsView.addDetailView(view);
+ });
+ _.each(this._tabViews, function(view) {
+ self._detailsView.addTabView(view);
+ });
+ this.$el.append(this._detailsView.$el);
+ this._detailsView.$el.addClass('disappear');
this._detailsView.render();
}
this._detailsView.setFileInfo(_.extend({
path: this.getCurrentDirectory()
}, fileInfo));
+ _.defer(function() {
+ self._detailsView.$el.removeClass('disappear');
+ });
},
/**
@@ -374,36 +399,34 @@
this._selectFileEl($tr, !$checkbox.prop('checked'));
this.updateSelectionSummary();
} else {
- var currentIndex = $tr.index();
- var fileInfo = this.files[currentIndex];
-
- this._updateDetailsView(fileInfo);
- event.preventDefault();
- return;
-
- // FIXME: disabled for testing details view
-
- var filename = $tr.attr('data-file');
- var renaming = $tr.data('renaming');
- if (!renaming) {
- this.fileActions.currentFile = $tr.find('td');
- var mime = this.fileActions.getCurrentMimeType();
- var type = this.fileActions.getCurrentType();
- var permissions = this.fileActions.getCurrentPermissions();
- var action = this.fileActions.getDefault(mime,type, permissions);
- if (action) {
- event.preventDefault();
- // also set on global object for legacy apps
- window.FileActions.currentFile = this.fileActions.currentFile;
- action(filename, {
- $file: $tr,
- fileList: this,
- fileActions: this.fileActions,
- dir: $tr.attr('data-path') || this.getCurrentDirectory()
- });
+ // clicked directly on the name
+ if ($(event.target).is('.nametext') || $(event.target).closest('.nametext').length) {
+ var filename = $tr.attr('data-file');
+ var renaming = $tr.data('renaming');
+ if (!renaming) {
+ this.fileActions.currentFile = $tr.find('td');
+ var mime = this.fileActions.getCurrentMimeType();
+ var type = this.fileActions.getCurrentType();
+ var permissions = this.fileActions.getCurrentPermissions();
+ var action = this.fileActions.getDefault(mime,type, permissions);
+ if (action) {
+ event.preventDefault();
+ // also set on global object for legacy apps
+ window.FileActions.currentFile = this.fileActions.currentFile;
+ action(filename, {
+ $file: $tr,
+ fileList: this,
+ fileActions: this.fileActions,
+ dir: $tr.attr('data-path') || this.getCurrentDirectory()
+ });
+ }
+ // deselect row
+ $(event.target).closest('a').blur();
}
- // deselect row
- $(event.target).closest('a').blur();
+ } else {
+ var fileInfo = this.files[$tr.index()];
+ this._updateDetailsView(fileInfo);
+ event.preventDefault();
}
}
},
@@ -858,7 +881,7 @@
var formatted;
var text;
if (mtime > 0) {
- formatted = formatDate(mtime);
+ formatted = OC.Util.formatDate(mtime);
text = OC.Util.relativeModifiedDate(mtime);
} else {
formatted = t('files', 'Unable to determine date');
@@ -1554,6 +1577,7 @@
tr.remove();
tr = self.add(fileInfo, {updateSummary: false, silent: true});
self.$fileList.trigger($.Event('fileActionsReady', {fileList: self, $files: $(tr)}));
+ self._updateDetailsView(fileInfo);
}
});
} else {
@@ -2261,6 +2285,34 @@
};
/**
+ * Globally registered tab views
+ *
+ * @type OCA.Files.DetailTabView
+ */
+ FileList.prototype._tabViews = [];
+
+ /**
+ * Globally registered detail views
+ *
+ * @type OCA.Files.DetailFileInfoView
+ */
+ FileList.prototype._detailFileInfoViews = [];
+
+ /**
+ * Register a tab view to be added to all views
+ */
+ FileList.prototype.registerTabView = function(tabView) {
+ this._tabViews.push(tabView);
+ };
+
+ /**
+ * Register a detail view to be added to all views
+ */
+ FileList.prototype.registerDetailView = function(detailView) {
+ this._detailFileInfoViews.push(detailView);
+ };
+
+ /**
* File info attributes.
*
* @todo make this a real class in the future
diff --git a/apps/files/js/mainfileinfodetailview.js b/apps/files/js/mainfileinfodetailview.js
index 3f3705c2586..5eb74145f12 100644
--- a/apps/files/js/mainfileinfodetailview.js
+++ b/apps/files/js/mainfileinfodetailview.js
@@ -10,11 +10,8 @@
(function() {
var TEMPLATE =
- '<div class="thumbnail"></div>' +
- '<ul class="detailList">' +
- ' <li>Name: {{name}}</li>' +
- ' <li>Path: {{path}}</li>' +
- '</ul>';
+ '<div class="thumbnail"></div><div class="fileName">{{name}}</div>' +
+ '<div><span title="{{altSize}}">{{size}}</span>, <span title="{{altDate}}">{{date}}</span></div>';
/**
* @class OCA.Files.MainFileInfoDetailView
@@ -42,8 +39,6 @@
/**
* Renders this details view
- *
- * @abstract
*/
render: function() {
this.$el.empty();
@@ -53,17 +48,36 @@
}
if (this._fileInfo) {
- this.$el.append(this._template(this._fileInfo));
+ this.$el.append(this._template({
+ nameLabel: t('files', 'Name'),
+ name: this._fileInfo.name,
+ pathLabel: t('files', 'Path'),
+ path: this._fileInfo.path,
+ sizeLabel: t('files', 'Size'),
+ // TODO: refactor and use size formatter
+ size: OC.Util.humanFileSize(this._fileInfo.size, true),
+ altSize: this._fileInfo.size,
+ dateLabel: t('files', 'Modified'),
+ altDate: OC.Util.formatDate(this._fileInfo.mtime),
+ date: OC.Util.relativeModifiedDate(this._fileInfo.mtime)
+ }));
+
var $iconDiv = this.$el.find('.thumbnail');
- // FIXME: use proper way, this is only for demo purposes
- FileList.lazyLoadPreview({
- path: this._fileInfo.path + '/' + this._fileInfo.name,
- mime: this._fileInfo.mimetype,
- etag: this._fileInfo.etag,
- callback: function(url) {
- $iconDiv.css('background-image', 'url("' + url + '")');
- }
- });
+ // TODO: we really need OC.Previews
+ if (this._fileInfo.mimetype !== 'httpd/unix-directory') {
+ // FIXME: use proper way, this is only for demo purposes
+ var previewUrl = FileList.generatePreviewUrl({
+ file: this._fileInfo.path + '/' + this._fileInfo.name,
+ c: this._fileInfo.etag,
+ x: 50,
+ y: 50
+ });
+ previewUrl = previewUrl.replace('(', '%28').replace(')', '%29');
+ $iconDiv.css('background-image', 'url("' + previewUrl + '")');
+ } else {
+ // TODO: special icons / shared / external
+ $iconDiv.css('background-image', 'url("' + OC.MimeType.getIconUrl('dir') + '")');
+ }
} else {
// TODO: render placeholder text?
}
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index e7823454c53..227eec79578 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -140,6 +140,13 @@
}
});
}, t('files_sharing', 'Share'));
+
+ OC.addScript('files_sharing', 'sharetabview').done(function() {
+ fileList.registerTabView(new OCA.Sharing.ShareTabView('shareTabView'));
+ });
+ OC.addScript('files_sharing', 'sharedetailview').done(function() {
+ fileList.registerDetailView(new OCA.Sharing.ShareDetailView());
+ });
},
/**
diff --git a/apps/files_sharing/js/sharedetailview.js b/apps/files_sharing/js/sharedetailview.js
new file mode 100644
index 00000000000..a18a6d19d15
--- /dev/null
+++ b/apps/files_sharing/js/sharedetailview.js
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+
+(function() {
+ var TEMPLATE =
+ '<ul class="shareDetailList">' +
+ ' <li>Owner: {{owner}}</li>' +
+ '</ul>';
+
+ /**
+ * @class OCA.Files.MainFileInfoDetailView
+ * @classdesc
+ *
+ * Displays main details about a file
+ *
+ */
+ var ShareDetailView = function() {
+ this.initialize();
+ };
+ /**
+ * @memberof OCA.Sharing
+ */
+ ShareDetailView.prototype = _.extend({}, OCA.Files.DetailFileInfoView.prototype,
+ /** @lends OCA.Sharing.ShareDetailView.prototype */ {
+ _template: null,
+
+ /**
+ * Initialize the details view
+ */
+ initialize: function() {
+ this.$el = $('<div class="shareDetailView"></div>');
+ },
+
+ /**
+ * Renders this details view
+ */
+ render: function() {
+ this.$el.empty();
+
+ if (!this._template) {
+ this._template = Handlebars.compile(TEMPLATE);
+ }
+
+ if (this._fileInfo) {
+ this.$el.append(this._template({
+ owner: this._fileInfo.shareOwner || OC.currentUser
+ }));
+ } else {
+ // TODO: render placeholder text?
+ }
+ }
+ });
+
+ OCA.Sharing.ShareDetailView = ShareDetailView;
+})();
+
diff --git a/apps/files_sharing/js/sharetabview.js b/apps/files_sharing/js/sharetabview.js
new file mode 100644
index 00000000000..48dfcae16d8
--- /dev/null
+++ b/apps/files_sharing/js/sharetabview.js
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+
+(function() {
+ var TEMPLATE =
+ '<div>TODO: here comes the share dialog</div>';
+
+ /**
+ * @class OCA.Sharing.ShareTabView
+ * @classdesc
+ *
+ * Displays sharing information
+ *
+ */
+ var ShareTabView = function(id) {
+ this.initialize(id);
+ };
+ /**
+ * @memberof OCA.Sharing
+ */
+ ShareTabView.prototype = _.extend({}, OCA.Files.DetailTabView.prototype,
+ /** @lends OCA.Sharing.ShareTabView.prototype */ {
+ _template: null,
+
+ /**
+ * Initialize the details view
+ */
+ initialize: function() {
+ OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
+ this.$el.addClass('shareTabView');
+ },
+
+ getLabel: function() {
+ return t('files_sharing', 'Sharing');
+ },
+
+ /**
+ * Renders this details view
+ */
+ render: function() {
+ this.$el.empty();
+
+ if (!this._template) {
+ this._template = Handlebars.compile(TEMPLATE);
+ }
+
+ if (this._fileInfo) {
+ this.$el.append(this._template());
+ } else {
+ // TODO: render placeholder text?
+ }
+ }
+ });
+
+ OCA.Sharing.ShareTabView = ShareTabView;
+})();
+