+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 library. If not, see .
+*
+*/
+
+describe('OCA.Files.MainFileInfoDetailView tests', function() {
+ var view, tooltipStub, previewStub, fncLazyLoadPreview, fileListMock;
+
+ beforeEach(function() {
+ tooltipStub = sinon.stub($.fn, 'tooltip');
+ fileListMock = sinon.mock(OCA.Files.FileList.prototype);
+ view = new OCA.Files.MainFileInfoDetailView();
+ });
+ afterEach(function() {
+ view.destroy();
+ view = undefined;
+ tooltipStub.restore();
+ fileListMock.restore();
+
+ });
+ describe('rendering', function() {
+ var testFileInfo;
+ beforeEach(function() {
+ view = new OCA.Files.MainFileInfoDetailView();
+ testFileInfo = {
+ id: 5,
+ name: 'One.txt',
+ path: '/subdir',
+ size: 123456789,
+ mtime: Date.UTC(2015, 6, 17, 1, 2, 0, 0)
+ };
+ });
+ it('displays basic info', function() {
+ var clock = sinon.useFakeTimers(Date.UTC(2015, 6, 17, 1, 2, 0, 3));
+ var dateExpected = OC.Util.formatDate(Date(Date.UTC(2015, 6, 17, 1, 2, 0, 0)));
+ view.setFileInfo(testFileInfo);
+ expect(view.$el.find('.fileName').text()).toEqual('One.txt');
+ expect(view.$el.find('.fileName').attr('title')).toEqual('One.txt');
+ expect(view.$el.find('.size').text()).toEqual('117.7 MB');
+ expect(view.$el.find('.size').attr('title')).toEqual('123456789 bytes');
+ expect(view.$el.find('.date').text()).toEqual('a few seconds ago');
+ expect(view.$el.find('.date').attr('title')).toEqual(dateExpected);
+ clock.restore();
+ });
+ it('displays favorite icon', function() {
+ view.setFileInfo(_.extend(testFileInfo, {
+ tags: [OC.TAG_FAVORITE]
+ }));
+ expect(view.$el.find('.favorite img').attr('src'))
+ .toEqual(OC.imagePath('core', 'actions/starred'));
+
+ view.setFileInfo(_.extend(testFileInfo, {
+ tags: []
+ }));
+ expect(view.$el.find('.favorite img').attr('src'))
+ .toEqual(OC.imagePath('core', 'actions/star'));
+ });
+ it('displays mime icon', function() {
+ // File
+ view.setFileInfo(_.extend(testFileInfo, {
+ mimetype: 'text/calendar'
+ }));
+
+ expect(view.$el.find('.thumbnail').css('background-image'))
+ .toContain('filetypes/text-calendar.svg');
+
+ // Folder
+ view.setFileInfo(_.extend(testFileInfo, {
+ mimetype: 'httpd/unix-directory'
+ }));
+
+ expect(view.$el.find('.thumbnail').css('background-image'))
+ .toContain('filetypes/folder.svg');
+ });
+ it('displays thumbnail', function() {
+ view.setFileInfo(_.extend(testFileInfo, {
+ mimetype: 'text/plain'
+ }));
+
+ var expectation = fileListMock.expects('lazyLoadPreview');
+ expectation.once();
+
+ view.setFileInfo(testFileInfo);
+
+ fileListMock.verify();
+ });
+ });
+});
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index f72f5024622..9000fafd8dd 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -56,6 +56,7 @@ $application->setupPropagation();
\OCP\Util::addScript('files_sharing', 'share');
\OCP\Util::addScript('files_sharing', 'external');
+\OCP\Util::addStyle('files_sharing', 'sharetabview');
// FIXME: registering a job here will cause additional useless SQL queries
// when the route is not cron.php, needs a better way
diff --git a/apps/files_sharing/css/sharetabview.css b/apps/files_sharing/css/sharetabview.css
new file mode 100644
index 00000000000..42c9bee7173
--- /dev/null
+++ b/apps/files_sharing/css/sharetabview.css
@@ -0,0 +1,3 @@
+.app-files .shareTabView {
+ min-height: 100px;
+}
diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js
index 5923e426f05..1993efe7d73 100644
--- a/apps/files_sharing/js/public.js
+++ b/apps/files_sharing/js/public.js
@@ -57,7 +57,8 @@ OCA.Sharing.PublicApp = {
scrollContainer: $(window),
dragOptions: dragOptions,
folderDropOptions: folderDropOptions,
- fileActions: fileActions
+ fileActions: fileActions,
+ detailsViewEnabled: false
}
);
this.files = OCA.Files.Files;
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index e7823454c53..12bec0e8c9a 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -140,6 +140,10 @@
}
});
}, t('files_sharing', 'Share'));
+
+ OC.addScript('files_sharing', 'sharetabview').done(function() {
+ fileList.registerTabView(new OCA.Sharing.ShareTabView('shareTabView'));
+ });
},
/**
diff --git a/apps/files_sharing/js/sharetabview.js b/apps/files_sharing/js/sharetabview.js
new file mode 100644
index 00000000000..e02de923751
--- /dev/null
+++ b/apps/files_sharing/js/sharetabview.js
@@ -0,0 +1,67 @@
+/*
+ * 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 =
+ 'Owner: {{owner}}';
+
+ /**
+ * @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({
+ owner: this._fileInfo.shareOwner || OC.currentUser
+ }));
+
+ } else {
+ // TODO: render placeholder text?
+ }
+ }
+ });
+
+ OCA.Sharing.ShareTabView = ShareTabView;
+})();
+
diff --git a/apps/files_sharing/tests/js/appSpec.js b/apps/files_sharing/tests/js/appSpec.js
index 49bca568001..133bd44f750 100644
--- a/apps/files_sharing/tests/js/appSpec.js
+++ b/apps/files_sharing/tests/js/appSpec.js
@@ -132,7 +132,7 @@ describe('OCA.Sharing.App tests', function() {
shareOwner: 'user2'
}]);
- fileListIn.findFileEl('testdir').find('td a.name').click();
+ fileListIn.findFileEl('testdir').find('td .nametext').click();
expect(OCA.Files.App.fileList.getCurrentDirectory()).toEqual('/somewhere/inside/subdir/testdir');
diff --git a/core/css/apps.css b/core/css/apps.css
index 57133729f15..5769120c5ed 100644
--- a/core/css/apps.css
+++ b/core/css/apps.css
@@ -417,7 +417,39 @@
min-height: 100%;
}
+/* APP-SIDEBAR ----------------------------------------------------------------*/
+/*
+ Sidebar: a sidebar to be used within #app-content
+ have it as first element within app-content in order to shrink other
+ sibling containers properly. Compare Files app for example.
+*/
+#app-sidebar {
+ position: fixed;
+ top: 45px;
+ right: 0;
+ left: auto;
+ bottom: 0;
+ width: 27%;
+ display: block;
+ background: #eee;
+ -webkit-transition: margin-right 300ms;
+ -moz-transition: margin-right 300ms;
+ -o-transition: margin-right 300ms;
+ transition: margin-right 300ms;
+ overflow-x: hidden;
+ overflow-y: auto;
+ visibility: visible;
+ z-index: 500;
+}
+
+#app-content.with-app-sidebar {
+ margin-right: 27%;
+}
+
+#app-sidebar.disappear {
+ visibility: hidden;
+}
/* APP-SETTINGS ---------------------------------------------------------------*/
@@ -556,3 +588,50 @@ em {
padding:16px;
}
+/* generic tab styles */
+.tabHeaders {
+ margin: 15px;
+ background-color: #1D2D44;
+}
+
+.tabHeaders .tabHeader {
+ float: left;
+ border: 1px solid #ddd;
+ padding: 5px;
+ cursor: pointer;
+ background-color: #f8f8f8;
+ font-weight: bold;
+}
+.tabHeaders .tabHeader, .tabHeaders .tabHeader a {
+ color: #888;
+}
+
+.tabHeaders .tabHeader:first-child {
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+
+.tabHeaders .tabHeader:last-child {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+.tabHeaders .tabHeader.selected,
+.tabHeaders .tabHeader:hover {
+ background-color: #e8e8e8;
+}
+
+.tabHeaders .tabHeader.selected,
+.tabHeaders .tabHeader.selected a,
+.tabHeaders .tabHeader:hover,
+.tabHeaders .tabHeader:hover a {
+ color: #000;
+}
+
+.tabsContainer {
+ clear: left;
+}
+
+.tabsContainer .tab {
+ padding: 15px;
+}
diff --git a/core/css/mobile.css b/core/css/mobile.css
index 80217d7069c..2256d821d73 100644
--- a/core/css/mobile.css
+++ b/core/css/mobile.css
@@ -103,6 +103,10 @@
z-index: 1000;
}
+#app-sidebar{
+ width: 100%;
+}
+
/* allow horizontal scrollbar in settings
otherwise user management is not usable on mobile */
#body-settings #app-content {
diff --git a/core/js/apps.js b/core/js/apps.js
index 71170bbc23a..d0d351f5147 100644
--- a/core/js/apps.js
+++ b/core/js/apps.js
@@ -20,6 +20,26 @@
}
};
+ /**
+ * Shows the #app-sidebar and add .with-app-sidebar to subsequent siblings
+ */
+ exports.Apps.showAppSidebar = function() {
+ var $appSidebar = $('#app-sidebar');
+ $appSidebar.removeClass('disappear')
+ $('#app-content').addClass('with-app-sidebar');
+
+ };
+
+ /**
+ * Shows the #app-sidebar and removes .with-app-sidebar from subsequent
+ * siblings
+ */
+ exports.Apps.hideAppSidebar = function() {
+ var $appSidebar = $('#app-sidebar');
+ $appSidebar.addClass('disappear');
+ $('#app-content').removeClass('with-app-sidebar');
+ };
+
/**
* Provides a way to slide down a target area through a button and slide it
* up if the user clicks somewhere else. Used for the news app settings and
diff --git a/core/js/core.json b/core/js/core.json
index 0f052b798a9..1053debaa99 100644
--- a/core/js/core.json
+++ b/core/js/core.json
@@ -20,6 +20,7 @@
"oc-dialogs.js",
"js.js",
"l10n.js",
+ "apps.js",
"share.js",
"octemplate.js",
"eventsource.js",
diff --git a/core/js/js.js b/core/js/js.js
index 45c9c90362f..72d4edd28dd 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -1366,13 +1366,13 @@ function initCore() {
// if there is a scrollbar …
if($('#app-content').get(0).scrollHeight > $('#app-content').height()) {
if($(window).width() > 768) {
- controlsWidth = $('#content').width() - $('#app-navigation').width() - getScrollBarWidth();
+ controlsWidth = $('#content').width() - $('#app-navigation').width() - $('#app-sidebar').width() - getScrollBarWidth();
} else {
controlsWidth = $('#content').width() - getScrollBarWidth();
}
} else { // if there is none
if($(window).width() > 768) {
- controlsWidth = $('#content').width() - $('#app-navigation').width();
+ controlsWidth = $('#content').width() - $('#app-navigation').width() - $('#app-sidebar').width();
} else {
controlsWidth = $('#content').width();
}
diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js
index 29293e89bcb..dbe005ba2e9 100644
--- a/core/js/tests/specHelper.js
+++ b/core/js/tests/specHelper.js
@@ -121,6 +121,8 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
OC.TestUtil = TestUtil;
}
+ moment.locale('en');
+
// reset plugins
OC.Plugins._plugins = [];