summaryrefslogtreecommitdiffstats
path: root/apps/files/js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/js')
-rw-r--r--apps/files/js/app.js8
-rw-r--r--apps/files/js/navigation.js257
-rw-r--r--apps/files/js/tagsplugin.js134
3 files changed, 355 insertions, 44 deletions
diff --git a/apps/files/js/app.js b/apps/files/js/app.js
index 6a21bce975b..52c92645b2d 100644
--- a/apps/files/js/app.js
+++ b/apps/files/js/app.js
@@ -53,6 +53,8 @@
this.$showHiddenFiles = $('input#showhiddenfilesToggle');
var showHidden = $('#showHiddenFiles').val() === "1";
this.$showHiddenFiles.prop('checked', showHidden);
+
+
if ($('#fileNotFound').val() === "1") {
OC.Notification.show(t('files', 'File could not be found'), {type: 'error'});
}
@@ -219,7 +221,7 @@
},
/**
- * Persist show hidden preference on ther server
+ * Persist show hidden preference on the server
*
* @returns {undefined}
*/
@@ -237,8 +239,8 @@
var params;
if (e && e.itemId) {
params = {
- view: e.itemId,
- dir: '/'
+ view: typeof e.view === 'string' && e.view !== '' ? e.view : e.itemId,
+ dir: e.dir ? e.dir : '/'
};
this._changeUrl(params.view, params.dir);
OC.Apps.hideAppSidebar($('.detailsView'));
diff --git a/apps/files/js/navigation.js b/apps/files/js/navigation.js
index d213d0467b6..d4fa06cb45e 100644
--- a/apps/files/js/navigation.js
+++ b/apps/files/js/navigation.js
@@ -1,8 +1,9 @@
/*
- * Copyright (c) 2014
+ * @Copyright 2014 Vincent Petry <pvince81@owncloud.com>
*
* @author Vincent Petry
- * @copyright 2014 Vincent Petry <pvince81@owncloud.com>
+ * @author Felix NĂ¼sse <felix.nuesse@t-online.de>
+ *
*
* This file is licensed under the Affero General Public License version 3
* or later.
@@ -11,7 +12,7 @@
*
*/
-(function() {
+(function () {
/**
* @class OCA.Files.Navigation
@@ -19,7 +20,7 @@
*
* @param $el element containing the navigation
*/
- var Navigation = function($el) {
+ var Navigation = function ($el) {
this.initialize($el);
};
@@ -39,23 +40,47 @@
$currentContent: null,
/**
+ * Strategy by which the quickaccesslist is sorted
+ *
+ * Possible Strategies:
+ * customorder
+ * datemodified
+ * date
+ * alphabet
+ *
+ */
+ $sortingStrategy: 'alphabet',
+
+ /**
+ * Key for the quick-acces-list
+ */
+ $quickAccessListKey: 'sublist-favorites',
+ /**
* Initializes the navigation from the given container
*
* @private
* @param $el element containing the navigation
*/
- initialize: function($el) {
+ initialize: function ($el) {
this.$el = $el;
this._activeItem = null;
this.$currentContent = null;
this._setupEvents();
+
+ var scope=this;
+ $.get(OC.generateUrl("/apps/files/api/v1/quickaccess/get/SortingStrategy"), function (data, status) {
+ scope.$sortingStrategy=data;
+ scope.setInitialQuickaccessSettings();
+ });
+
},
/**
* Setup UI events
*/
- _setupEvents: function() {
- this.$el.on('click', 'li a', _.bind(this._onClickItem, this));
+ _setupEvents: function () {
+ this.$el.on('click', 'li a', _.bind(this._onClickItem, this))
+ this.$el.on('click', 'li button', _.bind(this._onClickMenuButton, this));
},
/**
@@ -63,16 +88,16 @@
*
* @return app container
*/
- getActiveContainer: function() {
+ getActiveContainer: function () {
return this.$currentContent;
},
/**
* Returns the currently active item
- *
+ *
* @return item ID
*/
- getActiveItem: function() {
+ getActiveItem: function () {
return this._activeItem;
},
@@ -83,29 +108,42 @@
* @param string itemId id of the navigation item to select
* @param array options "silent" to not trigger event
*/
- setActiveItem: function(itemId, options) {
+ setActiveItem: function (itemId, options) {
+ var currentItem = this.$el.find('li[data-id=' + itemId + ']');
+ var itemDir = currentItem.data('dir');
+ var itemView = currentItem.data('view');
var oldItemId = this._activeItem;
if (itemId === this._activeItem) {
if (!options || !options.silent) {
this.$el.trigger(
- new $.Event('itemChanged', {itemId: itemId, previousItemId: oldItemId})
+ new $.Event('itemChanged', {
+ itemId: itemId,
+ previousItemId: oldItemId,
+ dir: itemDir,
+ view: itemView
+ })
);
}
return;
}
- this.$el.find('li').removeClass('active');
+ this.$el.find('li a').removeClass('active');
if (this.$currentContent) {
this.$currentContent.addClass('hidden');
this.$currentContent.trigger(jQuery.Event('hide'));
}
this._activeItem = itemId;
- this.$el.find('li[data-id=' + itemId + ']').addClass('active');
- this.$currentContent = $('#app-content-' + itemId);
+ currentItem.children('a').addClass('active');
+ this.$currentContent = $('#app-content-' + (typeof itemView === 'string' && itemView !== '' ? itemView : itemId));
this.$currentContent.removeClass('hidden');
if (!options || !options.silent) {
this.$currentContent.trigger(jQuery.Event('show'));
this.$el.trigger(
- new $.Event('itemChanged', {itemId: itemId, previousItemId: oldItemId})
+ new $.Event('itemChanged', {
+ itemId: itemId,
+ previousItemId: oldItemId,
+ dir: itemDir,
+ view: itemView
+ })
);
}
},
@@ -113,23 +151,206 @@
/**
* Returns whether a given item exists
*/
- itemExists: function(itemId) {
+ itemExists: function (itemId) {
return this.$el.find('li[data-id=' + itemId + ']').length;
},
/**
* Event handler for when clicking on an item.
*/
- _onClickItem: function(ev) {
+ _onClickItem: function (ev) {
var $target = $(ev.target);
var itemId = $target.closest('li').attr('data-id');
if (!_.isUndefined(itemId)) {
this.setActiveItem(itemId);
}
ev.preventDefault();
+ },
+
+ /**
+ * Event handler for clicking a button
+ */
+ _onClickMenuButton: function (ev) {
+ var $target = $(ev.target);
+ var itemId = $target.closest('button').attr('id');
+
+ var collapsibleToggles = [];
+ var dotmenuToggles = [];
+
+ // The collapsibleToggles-Array consists of a list of Arrays. Every subarray must contain the Button to listen to at the 0th index,
+ // and the parent, which should be toggled at the first arrayindex.
+ collapsibleToggles.push(["#button-collapse-favorites", "#button-collapse-parent-favorites"]);
+
+ // The dotmenuToggles-Array consists of a list of Arrays. Every subarray must contain the Button to listen to at the 0th index,
+ // and the parent, which should be toggled at the first arrayindex.
+ dotmenuToggles.push(["#dotmenu-button-favorites", "dotmenu-content-favorites"]);
+
+ collapsibleToggles.forEach(function foundToggle (item) {
+ if (item[0] === ("#" + itemId)) {
+ $(item[1]).toggleClass('open');
+ var show = 1;
+ if (!$(item[1]).hasClass('open')) {
+ show = 0;
+ }
+ $.get(OC.generateUrl("/apps/files/api/v1/quickaccess/set/showList"), {show: show}, function (data, status) {
+ });
+ }
+ });
+
+ dotmenuToggles.forEach(function foundToggle (item) {
+ if (item[0] === ("#" + itemId)) {
+ document.getElementById(item[1]).classList.toggle('open');
+ }
+ });
+
+ ev.preventDefault();
+ },
+
+ /**
+ * Sort initially as setup of sidebar for QuickAccess
+ */
+ setInitialQuickaccessSettings: function () {
+
+ var quickAccesKey = this.$quickAccessListKey;
+ var list = document.getElementById(quickAccesKey).getElementsByTagName('li');
+
+ var sort = true;
+ var reverse = false;
+ if (this.$sortingStrategy === 'datemodified') {
+ sort = false;
+ reverse = false;
+
+ var scope = this;
+ $.get(OC.generateUrl("/apps/files/api/v1/quickaccess/get/FavoriteFolders/"), function (data, status) {
+ for (var i = 0; i < data.favoriteFolders.length; i++) {
+ for (var j = 0; j < list.length; j++) {
+ if (scope.getCompareValue(list, j, 'alphabet').toLowerCase() === data.favoriteFolders[i].name.toLowerCase()) {
+ list[j].setAttribute("mtime", data.favoriteFolders[i].mtime);
+ }
+ }
+ }
+ scope.QuickSort(list, 0, list.length - 1);
+ scope.reverse(list);
+ });
+
+ } else if (this.$sortingStrategy === 'alphabet') {
+ sort = true;
+ } else if (this.$sortingStrategy === 'date') {
+ sort = true;
+ } else if (this.$sortingStrategy === 'customorder') {
+ var scope = this;
+ $.get(OC.generateUrl("/apps/files/api/v1/quickaccess/get/CustomSortingOrder"), function (data, status) {
+ var ordering = JSON.parse(data);
+ for (var i = 0; i < ordering.length; i++) {
+ for (var j = 0; j < list.length; j++) {
+ if (scope.getCompareValue(list, j, 'alphabet').toLowerCase() === ordering[i].name.toLowerCase()) {
+ list[j].setAttribute("folderPosition", ordering[i].id);
+ }
+ }
+ }
+ scope.QuickSort(list, 0, list.length - 1);
+ });
+ sort = false;
+ }
+
+ if (sort) {
+ this.QuickSort(list, 0, list.length - 1);
+ }
+ if (reverse) {
+ this.reverse(list);
+ }
+
+ },
+
+ /**
+ * Sorting-Algorithm for QuickAccess
+ */
+ QuickSort: function (list, start, end) {
+ var lastMatch;
+ if (list.length > 1) {
+ lastMatch = this.quicksort_helper(list, start, end);
+ if (start < lastMatch - 1) {
+ this.QuickSort(list, start, lastMatch - 1);
+ }
+ if (lastMatch < end) {
+ this.QuickSort(list, lastMatch, end);
+ }
+ }
+ },
+
+ /**
+ * Sorting-Algorithm-Helper for QuickAccess
+ */
+ quicksort_helper: function (list, start, end) {
+ var pivot = Math.floor((end + start) / 2);
+ var pivotElement = this.getCompareValue(list, pivot);
+ var i = start;
+ var j = end;
+
+ while (i <= j) {
+ while (this.getCompareValue(list, i) < pivotElement) {
+ i++;
+ }
+ while (this.getCompareValue(list, j) > pivotElement) {
+ j--;
+ }
+ if (i <= j) {
+ this.swap(list, i, j);
+ i++;
+ j--;
+ }
+ }
+ return i;
+ },
+
+ /**
+ * Sorting-Algorithm-Helper for QuickAccess
+ * This method allows easy access to the element which is sorted by.
+ */
+ getCompareValue: function (nodes, int, strategy) {
+
+ if ((typeof strategy === 'undefined')) {
+ strategy = this.$sortingStrategy;
+ }
+
+ if (strategy === 'alphabet') {
+ return nodes[int].getElementsByTagName('a')[0].innerHTML.toLowerCase();
+ } else if (strategy === 'date') {
+ return nodes[int].getAttribute('folderPosition').toLowerCase();
+ } else if (strategy === 'datemodified') {
+ return nodes[int].getAttribute('mtime');
+ } else if (strategy === 'customorder') {
+ return nodes[int].getAttribute('folderPosition');
+ }
+ return nodes[int].getElementsByTagName('a')[0].innerHTML.toLowerCase();
+ },
+
+ /**
+ * Sorting-Algorithm-Helper for QuickAccess
+ * This method allows easy swapping of elements.
+ */
+ swap: function (list, j, i) {
+ list[i].before(list[j]);
+ list[j].before(list[i]);
+ },
+
+ /**
+ * Reverse QuickAccess-List
+ */
+ reverse: function (list) {
+ var len = list.length - 1;
+ for (var i = 0; i < len / 2; i++) {
+ this.swap(list, i, len - i);
+ }
}
+
};
OCA.Files.Navigation = Navigation;
})();
+
+
+
+
+
diff --git a/apps/files/js/tagsplugin.js b/apps/files/js/tagsplugin.js
index b174aa7d766..bc1396b5104 100644
--- a/apps/files/js/tagsplugin.js
+++ b/apps/files/js/tagsplugin.js
@@ -10,11 +10,11 @@
/* global Handlebars */
-(function(OCA) {
+(function (OCA) {
_.extend(OC.Files.Client, {
- PROPERTY_TAGS: '{' + OC.Files.Client.NS_OWNCLOUD + '}tags',
- PROPERTY_FAVORITE: '{' + OC.Files.Client.NS_OWNCLOUD + '}favorite'
+ PROPERTY_TAGS: '{' + OC.Files.Client.NS_OWNCLOUD + '}tags',
+ PROPERTY_FAVORITE: '{' + OC.Files.Client.NS_OWNCLOUD + '}favorite'
});
var TEMPLATE_FAVORITE_MARK =
@@ -30,7 +30,7 @@
* @param {boolean} state true if starred, false otherwise
* @return {string} icon class for star image
*/
- function getStarIconClass(state) {
+ function getStarIconClass (state) {
return state ? 'icon-starred' : 'icon-star';
}
@@ -40,7 +40,7 @@
* @param {boolean} state true if starred, false otherwise
* @return {Object} jQuery object
*/
- function renderStar(state) {
+ function renderStar (state) {
if (!this._template) {
this._template = Handlebars.compile(TEMPLATE_FAVORITE_MARK);
}
@@ -57,11 +57,95 @@
* @param {Object} $favoriteMarkEl favorite mark element
* @param {boolean} state true if starred, false otherwise
*/
- function toggleStar($favoriteMarkEl, state) {
+ function toggleStar ($favoriteMarkEl, state) {
$favoriteMarkEl.removeClass('icon-star icon-starred').addClass(getStarIconClass(state));
$favoriteMarkEl.toggleClass('permanent', state);
}
+ /**
+ * Remove Item from Quickaccesslist
+ *
+ * @param {String} appfolder folder to be removed
+ */
+ function removeFavoriteFromList (appfolder) {
+
+ var quickAccessList = 'sublist-favorites';
+ var collapsibleButtonId = 'button-collapse-favorites';
+ var listULElements = document.getElementById(quickAccessList);
+ if (!listULElements) {
+ return;
+ }
+ var listLIElements = listULElements.getElementsByTagName('li');
+
+ var apppath=appfolder;
+ if(appfolder.startsWith("//")){
+ apppath=appfolder.substring(1, appfolder.length);
+ }
+
+ for (var i = 0; i <= listLIElements.length - 1; i++) {
+ if (listLIElements[i].getElementsByTagName('a')[0].href.endsWith("dir=" + apppath)) {
+ listLIElements[i].remove();
+ }
+ }
+
+ if (listULElements.childElementCount === 0) {
+ var collapsibleButton = document.getElementById("button-collapse-favorites");
+ collapsibleButton.style.display = 'none';
+ $("#button-collapse-parent-favorites").removeClass('collapsible');
+ }
+ }
+
+ /**
+ * Add Item to Quickaccesslist
+ *
+ * @param {String} appfolder folder to be added
+ */
+ function addFavoriteToList (appfolder) {
+ var quickAccessList = 'sublist-favorites';
+ var collapsibleButtonId = 'button-collapse-favorites';
+ var listULElements = document.getElementById(quickAccessList);
+ if (!listULElements) {
+ return;
+ }
+ var listLIElements = listULElements.getElementsByTagName('li');
+
+ var appName = appfolder.substring(appfolder.lastIndexOf("/") + 1, appfolder.length);
+ var apppath=appfolder;
+
+ if(appfolder.startsWith("//")){
+ apppath=appfolder.substring(1, appfolder.length);
+ }
+ var url=OC.generateUrl('/apps/files/?dir=')+apppath;
+
+
+ var innerTagA = document.createElement('A');
+ innerTagA.setAttribute("href", url);
+ innerTagA.setAttribute("class", "nav-icon-files svg");
+ innerTagA.innerHTML = appName;
+
+ var length = listLIElements.length + 1;
+ var innerTagLI = document.createElement('li');
+ innerTagLI.setAttribute("data-id", url);
+ innerTagLI.setAttribute("class", "nav-" + appName);
+ innerTagLI.setAttribute("folderpos", length.toString());
+ innerTagLI.appendChild(innerTagA);
+
+ $.get(OC.generateUrl("/apps/files/api/v1/quickaccess/get/NodeType"),{folderpath: apppath}, function (data, status) {
+ if (data === "dir") {
+ if (listULElements.childElementCount <= 0) {
+ listULElements.appendChild(innerTagLI);
+ var collapsibleButton = document.getElementById(collapsibleButtonId);
+ collapsibleButton.style.display = '';
+
+ $("#button-collapse-parent-favorites").addClass('collapsible');
+ } else {
+ listLIElements[listLIElements.length - 1].after(innerTagLI);
+ }
+ }
+ }
+ );
+ }
+
OCA.Files = OCA.Files || {};
/**
@@ -83,12 +167,12 @@
'shares.link'
],
- _extendFileActions: function(fileActions) {
+ _extendFileActions: function (fileActions) {
var self = this;
fileActions.registerAction({
name: 'Favorite',
- displayName: function(context) {
+ displayName: function (context) {
var $file = context.$file;
var isFavorite = $file.data('favorite') === true;
@@ -105,7 +189,7 @@
mime: 'all',
order: -100,
permissions: OC.PERMISSION_NONE,
- iconClass: function(fileName, context) {
+ iconClass: function (fileName, context) {
var $file = context.$file;
var isFavorite = $file.data('favorite') === true;
@@ -115,12 +199,13 @@
return 'icon-starred';
},
- actionHandler: function(fileName, context) {
+ actionHandler: function (fileName, context) {
var $favoriteMarkEl = context.$file.find('.favorite-mark');
var $file = context.$file;
var fileInfo = context.fileList.files[$file.index()];
var dir = context.dir || context.fileList.getCurrentDirectory();
var tags = $file.attr('data-tags');
+
if (_.isUndefined(tags)) {
tags = '';
}
@@ -130,8 +215,10 @@
if (isFavorite) {
// remove tag from list
tags = _.without(tags, OC.TAG_FAVORITE);
+ removeFavoriteFromList(dir + '/' + fileName);
} else {
tags.push(OC.TAG_FAVORITE);
+ addFavoriteToList(dir + '/' + fileName);
}
// pre-toggle the star
@@ -144,7 +231,7 @@
tags,
$favoriteMarkEl,
isFavorite
- ).then(function(result) {
+ ).then(function (result) {
context.fileInfoModel.trigger('busy', context.fileInfoModel, false);
// response from server should contain updated tags
var newTags = result.tags;
@@ -160,10 +247,10 @@
});
},
- _extendFileList: function(fileList) {
+ _extendFileList: function (fileList) {
// extend row prototype
var oldCreateRow = fileList._createRow;
- fileList._createRow = function(fileData) {
+ fileList._createRow = function (fileData) {
var $tr = oldCreateRow.apply(this, arguments);
var isFavorite = false;
if (fileData.tags) {
@@ -178,7 +265,7 @@
return $tr;
};
var oldElementToFile = fileList.elementToFile;
- fileList.elementToFile = function($el) {
+ fileList.elementToFile = function ($el) {
var fileInfo = oldElementToFile.apply(this, arguments);
var tags = $el.attr('data-tags');
if (_.isUndefined(tags)) {
@@ -191,22 +278,22 @@
};
var oldGetWebdavProperties = fileList._getWebdavProperties;
- fileList._getWebdavProperties = function() {
+ fileList._getWebdavProperties = function () {
var props = oldGetWebdavProperties.apply(this, arguments);
props.push(OC.Files.Client.PROPERTY_TAGS);
props.push(OC.Files.Client.PROPERTY_FAVORITE);
return props;
};
- fileList.filesClient.addFileInfoParser(function(response) {
+ fileList.filesClient.addFileInfoParser(function (response) {
var data = {};
var props = response.propStat[0].properties;
var tags = props[OC.Files.Client.PROPERTY_TAGS];
var favorite = props[OC.Files.Client.PROPERTY_FAVORITE];
if (tags && tags.length) {
- tags = _.chain(tags).filter(function(xmlvalue) {
+ tags = _.chain(tags).filter(function (xmlvalue) {
return (xmlvalue.namespaceURI === OC.Files.Client.NS_OWNCLOUD && xmlvalue.nodeName.split(':')[1] === 'tag');
- }).map(function(xmlvalue) {
+ }).map(function (xmlvalue) {
return xmlvalue.textContent || xmlvalue.text;
}).value();
}
@@ -221,7 +308,7 @@
});
},
- attach: function(fileList) {
+ attach: function (fileList) {
if (this.allowedLists.indexOf(fileList.id) < 0) {
return;
}
@@ -237,7 +324,7 @@
* @param {Object} $favoriteMarkEl favorite mark element
* @param {boolean} isFavorite Was the item favorited before
*/
- applyFileTags: function(fileName, tagNames, $favoriteMarkEl, isFavorite) {
+ applyFileTags: function (fileName, tagNames, $favoriteMarkEl, isFavorite) {
var encodedPath = OC.encodePath(fileName);
while (encodedPath[0] === '/') {
encodedPath = encodedPath.substr(1);
@@ -250,10 +337,10 @@
}),
dataType: 'json',
type: 'POST'
- }).fail(function(response) {
+ }).fail(function (response) {
var message = '';
// show message if it is available
- if(response.responseJSON && response.responseJSON.message) {
+ if (response.responseJSON && response.responseJSON.message) {
message = ': ' + response.responseJSON.message;
}
OC.Notification.show(t('files', 'An error occurred while trying to update the tags' + message), {type: 'error'});
@@ -261,6 +348,7 @@
});
}
};
-})(OCA);
+})
+(OCA);
OC.Plugins.register('OCA.Files.FileList', OCA.Files.TagsPlugin);