2014-05-08 21:00:42 +04:00
|
|
|
/*
|
2018-06-20 23:40:10 +03:00
|
|
|
* @Copyright 2014 Vincent Petry <pvince81@owncloud.com>
|
2014-05-08 21:00:42 +04:00
|
|
|
*
|
|
|
|
* @author Vincent Petry
|
2018-06-20 23:40:10 +03:00
|
|
|
* @author Felix Nüsse <felix.nuesse@t-online.de>
|
2014-05-08 21:00:42 +04:00
|
|
|
*
|
2018-06-16 23:44:18 +03:00
|
|
|
*
|
2014-05-08 21:00:42 +04:00
|
|
|
* This file is licensed under the Affero General Public License version 3
|
|
|
|
* or later.
|
|
|
|
*
|
|
|
|
* See the COPYING-README file.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2018-06-20 23:40:10 +03:00
|
|
|
(function () {
|
2014-05-08 21:00:42 +04:00
|
|
|
|
2014-06-24 01:56:10 +04:00
|
|
|
/**
|
|
|
|
* @class OCA.Files.Navigation
|
|
|
|
* @classdesc Navigation control for the files app sidebar.
|
|
|
|
*
|
|
|
|
* @param $el element containing the navigation
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
var Navigation = function ($el) {
|
2014-05-08 21:00:42 +04:00
|
|
|
this.initialize($el);
|
|
|
|
};
|
|
|
|
|
2014-06-24 01:56:10 +04:00
|
|
|
/**
|
|
|
|
* @memberof OCA.Files
|
|
|
|
*/
|
2014-05-08 21:00:42 +04:00
|
|
|
Navigation.prototype = {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Currently selected item in the list
|
|
|
|
*/
|
2014-05-09 00:06:30 +04:00
|
|
|
_activeItem: null,
|
2014-05-08 21:00:42 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Currently selected container
|
|
|
|
*/
|
|
|
|
$currentContent: null,
|
|
|
|
|
2018-06-16 23:44:18 +03:00
|
|
|
/**
|
|
|
|
* Strategy by which the quickaccesslist is sorted
|
2018-06-20 23:40:10 +03:00
|
|
|
*
|
|
|
|
* Possible Strategies:
|
|
|
|
* customorder
|
|
|
|
* datemodified
|
|
|
|
* date
|
|
|
|
* alphabet
|
|
|
|
*
|
2018-06-16 23:44:18 +03:00
|
|
|
*/
|
2018-06-27 11:40:32 +03:00
|
|
|
$sortingStrategy: 'alphabet',
|
2018-06-20 23:40:10 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Key for the quick-acces-list
|
|
|
|
*/
|
|
|
|
$quickAccessListKey: 'sublist-favorites',
|
2014-05-08 21:00:42 +04:00
|
|
|
/**
|
|
|
|
* Initializes the navigation from the given container
|
2014-06-24 01:56:10 +04:00
|
|
|
*
|
|
|
|
* @private
|
2014-05-08 21:00:42 +04:00
|
|
|
* @param $el element containing the navigation
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
initialize: function ($el) {
|
2014-05-08 21:00:42 +04:00
|
|
|
this.$el = $el;
|
2014-05-09 00:06:30 +04:00
|
|
|
this._activeItem = null;
|
2014-05-08 21:00:42 +04:00
|
|
|
this.$currentContent = null;
|
|
|
|
this._setupEvents();
|
2018-06-20 23:40:10 +03:00
|
|
|
|
2018-06-27 11:40:32 +03:00
|
|
|
var scope=this;
|
|
|
|
$.get(OC.generateUrl("/apps/files/api/v1/quickaccess/get/SortingStrategy"), function (data, status) {
|
|
|
|
scope.$sortingStrategy=data;
|
|
|
|
scope.setInitialQuickaccessSettings();
|
|
|
|
});
|
2018-06-20 23:40:10 +03:00
|
|
|
|
2014-05-08 21:00:42 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup UI events
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
_setupEvents: function () {
|
2018-06-16 23:44:18 +03:00
|
|
|
this.$el.on('click', 'li a', _.bind(this._onClickItem, this))
|
|
|
|
this.$el.on('click', 'li button', _.bind(this._onClickMenuButton, this));
|
2014-05-08 21:00:42 +04:00
|
|
|
},
|
|
|
|
|
2014-05-09 00:06:30 +04:00
|
|
|
/**
|
|
|
|
* Returns the container of the currently active app.
|
|
|
|
*
|
|
|
|
* @return app container
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
getActiveContainer: function () {
|
2014-05-09 00:06:30 +04:00
|
|
|
return this.$currentContent;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the currently active item
|
2018-06-20 23:40:10 +03:00
|
|
|
*
|
2014-05-09 00:06:30 +04:00
|
|
|
* @return item ID
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
getActiveItem: function () {
|
2014-05-09 00:06:30 +04:00
|
|
|
return this._activeItem;
|
|
|
|
},
|
|
|
|
|
2014-05-08 21:00:42 +04:00
|
|
|
/**
|
|
|
|
* Switch the currently selected item, mark it as selected and
|
|
|
|
* make the content container visible, if any.
|
2014-05-09 00:06:30 +04:00
|
|
|
*
|
2014-05-08 21:00:42 +04:00
|
|
|
* @param string itemId id of the navigation item to select
|
2014-05-09 00:06:30 +04:00
|
|
|
* @param array options "silent" to not trigger event
|
2014-05-08 21:00:42 +04:00
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
setActiveItem: function (itemId, options) {
|
2018-07-12 10:56:46 +03:00
|
|
|
var currentItem = this.$el.find('li[data-id=' + itemId + ']');
|
|
|
|
var itemDir = currentItem.data('dir');
|
|
|
|
var itemView = currentItem.data('view');
|
2014-05-12 21:54:20 +04:00
|
|
|
var oldItemId = this._activeItem;
|
2014-05-09 00:06:30 +04:00
|
|
|
if (itemId === this._activeItem) {
|
2014-05-12 21:54:20 +04:00
|
|
|
if (!options || !options.silent) {
|
|
|
|
this.$el.trigger(
|
2018-06-20 23:40:10 +03:00
|
|
|
new $.Event('itemChanged', {
|
|
|
|
itemId: itemId,
|
2018-07-12 10:56:46 +03:00
|
|
|
previousItemId: oldItemId,
|
|
|
|
dir: itemDir,
|
|
|
|
view: itemView
|
2018-06-20 23:40:10 +03:00
|
|
|
})
|
2014-05-12 21:54:20 +04:00
|
|
|
);
|
|
|
|
}
|
2014-05-08 21:00:42 +04:00
|
|
|
return;
|
|
|
|
}
|
2018-07-12 10:56:46 +03:00
|
|
|
this.$el.find('li a').removeClass('active');
|
2014-05-08 21:00:42 +04:00
|
|
|
if (this.$currentContent) {
|
|
|
|
this.$currentContent.addClass('hidden');
|
2014-05-09 00:06:30 +04:00
|
|
|
this.$currentContent.trigger(jQuery.Event('hide'));
|
2014-05-08 21:00:42 +04:00
|
|
|
}
|
2014-05-12 21:54:20 +04:00
|
|
|
this._activeItem = itemId;
|
2018-07-12 10:56:46 +03:00
|
|
|
currentItem.children('a').addClass('active');
|
2018-07-12 17:49:25 +03:00
|
|
|
this.$currentContent = $('#app-content-' + (typeof itemView === 'string' && itemView !== '' ? itemView : itemId));
|
2014-05-08 21:00:42 +04:00
|
|
|
this.$currentContent.removeClass('hidden');
|
2014-05-09 00:06:30 +04:00
|
|
|
if (!options || !options.silent) {
|
|
|
|
this.$currentContent.trigger(jQuery.Event('show'));
|
2014-05-12 21:54:20 +04:00
|
|
|
this.$el.trigger(
|
2018-06-20 23:40:10 +03:00
|
|
|
new $.Event('itemChanged', {
|
|
|
|
itemId: itemId,
|
2018-07-12 10:56:46 +03:00
|
|
|
previousItemId: oldItemId,
|
|
|
|
dir: itemDir,
|
|
|
|
view: itemView
|
2018-06-20 23:40:10 +03:00
|
|
|
})
|
2014-05-12 21:54:20 +04:00
|
|
|
);
|
2014-05-09 00:06:30 +04:00
|
|
|
}
|
2014-05-08 21:00:42 +04:00
|
|
|
},
|
|
|
|
|
2014-05-12 21:54:20 +04:00
|
|
|
/**
|
|
|
|
* Returns whether a given item exists
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
itemExists: function (itemId) {
|
2014-05-12 21:54:20 +04:00
|
|
|
return this.$el.find('li[data-id=' + itemId + ']').length;
|
|
|
|
},
|
|
|
|
|
2014-05-08 21:00:42 +04:00
|
|
|
/**
|
|
|
|
* Event handler for when clicking on an item.
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
_onClickItem: function (ev) {
|
2014-05-08 21:00:42 +04:00
|
|
|
var $target = $(ev.target);
|
|
|
|
var itemId = $target.closest('li').attr('data-id');
|
2017-06-09 19:05:23 +03:00
|
|
|
if (!_.isUndefined(itemId)) {
|
|
|
|
this.setActiveItem(itemId);
|
|
|
|
}
|
2015-05-19 15:47:13 +03:00
|
|
|
ev.preventDefault();
|
2018-06-16 23:44:18 +03:00
|
|
|
},
|
2018-06-20 23:40:10 +03:00
|
|
|
|
2018-06-16 23:44:18 +03:00
|
|
|
/**
|
2018-06-20 23:40:10 +03:00
|
|
|
* Event handler for clicking a button
|
2018-06-16 23:44:18 +03:00
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
_onClickMenuButton: function (ev) {
|
|
|
|
var $target = $(ev.target);
|
2018-07-13 10:33:57 +03:00
|
|
|
var $menu = $target.parent('li');
|
2018-06-20 23:40:10 +03:00
|
|
|
var itemId = $target.closest('button').attr('id');
|
2018-06-16 23:44:18 +03:00
|
|
|
|
2018-06-20 23:40:10 +03:00
|
|
|
var collapsibleToggles = [];
|
|
|
|
var dotmenuToggles = [];
|
2018-06-16 23:44:18 +03:00
|
|
|
|
2018-07-13 10:33:57 +03:00
|
|
|
if ($menu.hasClass('collapsible') && $menu.data('expandedstate')) {
|
|
|
|
$menu.toggleClass('open');
|
|
|
|
var show = $menu.hasClass('open') ? 1 : 0;
|
|
|
|
var key = $menu.data('expandedstate');
|
|
|
|
$.post(OC.generateUrl("/apps/files/api/v1/toggleShowFolder/" + key), {show: show});
|
|
|
|
}
|
2018-06-16 23:44:18 +03:00
|
|
|
|
2018-06-20 23:40:10 +03:00
|
|
|
dotmenuToggles.forEach(function foundToggle (item) {
|
|
|
|
if (item[0] === ("#" + itemId)) {
|
|
|
|
document.getElementById(item[1]).classList.toggle('open');
|
2018-06-16 23:44:18 +03:00
|
|
|
}
|
2018-06-20 23:40:10 +03:00
|
|
|
});
|
2018-06-16 23:44:18 +03:00
|
|
|
|
2018-06-20 23:40:10 +03:00
|
|
|
ev.preventDefault();
|
2018-06-16 23:44:18 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sort initially as setup of sidebar for QuickAccess
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
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);
|
|
|
|
});
|
2018-06-16 23:44:18 +03:00
|
|
|
|
2018-06-20 23:40:10 +03:00
|
|
|
} 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) {
|
2018-06-27 11:40:32 +03:00
|
|
|
var ordering = JSON.parse(data);
|
2018-06-20 23:40:10 +03:00
|
|
|
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;
|
2018-06-16 23:44:18 +03:00
|
|
|
}
|
|
|
|
|
2018-06-20 23:40:10 +03:00
|
|
|
if (sort) {
|
|
|
|
this.QuickSort(list, 0, list.length - 1);
|
|
|
|
}
|
|
|
|
if (reverse) {
|
2018-06-16 23:44:18 +03:00
|
|
|
this.reverse(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sorting-Algorithm for QuickAccess
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
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);
|
2018-06-16 23:44:18 +03:00
|
|
|
}
|
2018-06-20 23:40:10 +03:00
|
|
|
if (lastMatch < end) {
|
|
|
|
this.QuickSort(list, lastMatch, end);
|
2018-06-16 23:44:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sorting-Algorithm-Helper for QuickAccess
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
quicksort_helper: function (list, start, end) {
|
2018-06-16 23:44:18 +03:00
|
|
|
var pivot = Math.floor((end + start) / 2);
|
2018-06-20 23:40:10 +03:00
|
|
|
var pivotElement = this.getCompareValue(list, pivot);
|
|
|
|
var i = start;
|
|
|
|
var j = end;
|
2018-06-16 23:44:18 +03:00
|
|
|
|
2018-06-20 23:40:10 +03:00
|
|
|
while (i <= j) {
|
|
|
|
while (this.getCompareValue(list, i) < pivotElement) {
|
2018-06-16 23:44:18 +03:00
|
|
|
i++;
|
|
|
|
}
|
2018-06-20 23:40:10 +03:00
|
|
|
while (this.getCompareValue(list, j) > pivotElement) {
|
2018-06-16 23:44:18 +03:00
|
|
|
j--;
|
|
|
|
}
|
2018-06-20 23:40:10 +03:00
|
|
|
if (i <= j) {
|
2018-06-16 23:44:18 +03:00
|
|
|
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.
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
getCompareValue: function (nodes, int, strategy) {
|
|
|
|
|
|
|
|
if ((typeof strategy === 'undefined')) {
|
|
|
|
strategy = this.$sortingStrategy;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strategy === 'alphabet') {
|
2018-06-18 12:13:52 +03:00
|
|
|
return nodes[int].getElementsByTagName('a')[0].innerHTML.toLowerCase();
|
2018-06-20 23:40:10 +03:00
|
|
|
} else if (strategy === 'date') {
|
2018-06-27 01:35:28 +03:00
|
|
|
return nodes[int].getAttribute('folderPosition').toLowerCase();
|
2018-06-20 23:40:10 +03:00
|
|
|
} else if (strategy === 'datemodified') {
|
|
|
|
return nodes[int].getAttribute('mtime');
|
2018-06-27 11:40:32 +03:00
|
|
|
} else if (strategy === 'customorder') {
|
2018-06-20 23:40:10 +03:00
|
|
|
return nodes[int].getAttribute('folderPosition');
|
2018-06-16 23:44:18 +03:00
|
|
|
}
|
|
|
|
return nodes[int].getElementsByTagName('a')[0].innerHTML.toLowerCase();
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sorting-Algorithm-Helper for QuickAccess
|
|
|
|
* This method allows easy swapping of elements.
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
swap: function (list, j, i) {
|
2018-06-16 23:44:18 +03:00
|
|
|
list[i].before(list[j]);
|
|
|
|
list[j].before(list[i]);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reverse QuickAccess-List
|
|
|
|
*/
|
2018-06-20 23:40:10 +03:00
|
|
|
reverse: function (list) {
|
|
|
|
var len = list.length - 1;
|
|
|
|
for (var i = 0; i < len / 2; i++) {
|
|
|
|
this.swap(list, i, len - i);
|
2018-06-16 23:44:18 +03:00
|
|
|
}
|
2014-05-08 21:00:42 +04:00
|
|
|
}
|
2018-06-16 23:44:18 +03:00
|
|
|
|
2014-05-08 21:00:42 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
OCA.Files.Navigation = Navigation;
|
|
|
|
|
|
|
|
})();
|
2018-06-16 23:44:18 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|