nextcloud /
gallery
| 1 | /** |
||
| 2 | * Nextcloud - Gallery |
||
| 3 | * |
||
| 4 | * |
||
| 5 | * This file is licensed under the Affero General Public License version 3 or |
||
| 6 | * later. See the COPYING file. |
||
| 7 | * |
||
| 8 | * @author Olivier Paroz <[email protected]> |
||
| 9 | * |
||
| 10 | * @copyright Olivier Paroz 2017 |
||
| 11 | */ |
||
| 12 | /* global Handlebars, Gallery */ |
||
| 13 | (function ($, OC, t, Gallery) { |
||
| 14 | "use strict"; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Breadcrumbs that represent the path to the current album |
||
| 18 | * |
||
| 19 | * @constructor |
||
| 20 | */ |
||
| 21 | var Breadcrumb = function () { |
||
| 22 | this.breadcrumbsElement = $('#breadcrumbs'); |
||
| 23 | }; |
||
| 24 | |||
| 25 | Breadcrumb.prototype = { |
||
| 26 | breadcrumbs: [], |
||
| 27 | breadcrumbsElement: null, |
||
| 28 | ellipsis: null, |
||
| 29 | albumPath: null, |
||
| 30 | availableWidth: 0, |
||
| 31 | onClick: null, |
||
| 32 | droppableOptions: { |
||
| 33 | accept: "#gallery > .row > a", |
||
| 34 | activeClass: 'breadcrumbs-droppable', |
||
| 35 | hoverClass: 'breadcrumbs-droppable-hover', |
||
| 36 | tolerance: 'pointer' |
||
| 37 | }, |
||
| 38 | |||
| 39 | /** |
||
| 40 | * Initialises the breadcrumbs for the current album |
||
| 41 | * |
||
| 42 | * @param {string} albumPath |
||
| 43 | * @param {int} availableWidth |
||
| 44 | */ |
||
| 45 | init: function (albumPath, availableWidth) { |
||
| 46 | this.albumPath = albumPath; |
||
| 47 | this.availableWidth = availableWidth; |
||
| 48 | this.breadcrumbs = []; |
||
| 49 | this._build(); |
||
| 50 | this._resize(this.availableWidth); |
||
| 51 | }, |
||
| 52 | |||
| 53 | /** |
||
| 54 | * Defines the maximum available width in which we can build the breadcrumb and resizes it |
||
| 55 | * |
||
| 56 | * @param {int} availableWidth |
||
| 57 | */ |
||
| 58 | setMaxWidth: function (availableWidth) { |
||
| 59 | if (this.availableWidth > availableWidth || this.ellipsis.is(":visible")) { |
||
| 60 | this.availableWidth = availableWidth; |
||
| 61 | this._resize(this.availableWidth); |
||
| 62 | } |
||
| 63 | }, |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Processes UI elements dropped on the breadcrumbs |
||
| 67 | * |
||
| 68 | * @param event |
||
| 69 | * @param ui |
||
| 70 | */ |
||
| 71 | onDrop: function (event, ui) { |
||
| 72 | var $item = ui.draggable; |
||
| 73 | var $clone = ui.helper; |
||
| 74 | var $target = $(event.target); |
||
| 75 | if (!$target.is('.crumb')) { |
||
| 76 | $target = $target.closest('.crumb'); |
||
| 77 | } |
||
| 78 | var targetPath = $(event.target).data('dir').toString(); |
||
| 79 | var dir = Gallery.currentAlbum; |
||
| 80 | |||
| 81 | while (dir.substr(0, 1) === '/') {//remove extra leading /'s |
||
| 82 | dir = dir.substr(1); |
||
| 83 | } |
||
| 84 | dir = '/' + dir; |
||
| 85 | if (dir.substr(-1, 1) !== '/') { |
||
| 86 | dir = dir + '/'; |
||
| 87 | } |
||
| 88 | // Do nothing if dragged on current dir |
||
| 89 | if (targetPath === dir || targetPath + '/' === dir) { |
||
| 90 | return; |
||
| 91 | } |
||
| 92 | var filePath = $item.data('path').toString(); |
||
| 93 | var fileName = OC.basename(filePath); |
||
| 94 | |||
| 95 | $clone.fadeOut("normal", function () { |
||
| 96 | Gallery.move($item, fileName, filePath, $target, targetPath); |
||
| 97 | }); |
||
| 98 | }, |
||
| 99 | |||
| 100 | /** |
||
| 101 | * Shows the dark spinner on the crumb |
||
| 102 | */ |
||
| 103 | showLoader: function () { |
||
| 104 | $(this).addClass("icon-loading-small-dark"); |
||
| 105 | }, |
||
| 106 | |||
| 107 | /** |
||
| 108 | * Builds the breadcrumbs array |
||
| 109 | * |
||
| 110 | * @private |
||
| 111 | */ |
||
| 112 | _build: function () { |
||
| 113 | var i, crumbs, name, path, currentAlbum; |
||
| 114 | var albumName = $('#app-content').data('albumname'); |
||
| 115 | if (!albumName) { |
||
| 116 | albumName = t('gallery', 'Gallery'); |
||
| 117 | } |
||
| 118 | path = ''; |
||
| 119 | name = ''; |
||
|
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
| 120 | crumbs = this.albumPath.split('/'); |
||
| 121 | currentAlbum = crumbs.pop(); |
||
| 122 | |||
| 123 | // This adds the home button |
||
| 124 | this._addHome(albumName, currentAlbum); |
||
| 125 | // We always add a hidden ellipsis |
||
| 126 | this._pushCrumb('...', '', null, 'ellipsis'); |
||
| 127 | |||
| 128 | if (currentAlbum) { |
||
| 129 | // This builds the crumbs between home and the current folder |
||
| 130 | var crumbsLength = crumbs.length; |
||
| 131 | if (crumbsLength > 0) { |
||
| 132 | // We add all albums to the breadcrumbs array |
||
| 133 | for (i = 0; i < crumbsLength; i++) { |
||
| 134 | if (crumbs[i]) { |
||
| 135 | name = crumbs[i]; |
||
| 136 | if (path) { |
||
| 137 | path += '/' + crumbs[i]; |
||
| 138 | } else { |
||
| 139 | path += crumbs[i]; |
||
| 140 | } |
||
| 141 | this._pushCrumb(name, path, null, ''); |
||
| 142 | } |
||
| 143 | } |
||
| 144 | } |
||
| 145 | // We finally push the current folder |
||
| 146 | this._pushCrumb(currentAlbum, '', null, 'last'); |
||
| 147 | } |
||
| 148 | |||
| 149 | this._render(); |
||
| 150 | }, |
||
| 151 | |||
| 152 | /** |
||
| 153 | * Adds the Home button |
||
| 154 | * |
||
| 155 | * @param {string} albumName |
||
| 156 | * @param {string} currentAlbum |
||
| 157 | * @private |
||
| 158 | */ |
||
| 159 | _addHome: function (albumName, currentAlbum) { |
||
| 160 | var crumbImg = { |
||
| 161 | imageSrc: OC.imagePath('core', 'places/home'), |
||
| 162 | title: albumName |
||
| 163 | }; |
||
| 164 | var cssClass = 'home'; |
||
| 165 | if (!currentAlbum) { |
||
| 166 | cssClass += ' last'; |
||
| 167 | } |
||
| 168 | |||
| 169 | this._pushCrumb('', '', crumbImg, cssClass); |
||
| 170 | }, |
||
| 171 | |||
| 172 | /** |
||
| 173 | * Pushes crumb objects to the breadcrumbs array |
||
| 174 | * |
||
| 175 | * @param {string} name |
||
| 176 | * @param {string|boolean} link |
||
| 177 | * @param {Object} img |
||
| 178 | * @param {string} cssClass |
||
| 179 | * @private |
||
| 180 | */ |
||
| 181 | _pushCrumb: function (name, link, img, cssClass) { |
||
| 182 | var hash = ''; |
||
| 183 | |||
| 184 | // Prevent the last crumb from getting a link unless the last crumb is 'home'. |
||
| 185 | if ( cssClass.indexOf('last') === -1 || cssClass.indexOf('home') > -1 ) { |
||
| 186 | hash = '#' + encodeURIComponent(link); |
||
| 187 | } |
||
| 188 | |||
| 189 | this.breadcrumbs.push({ |
||
| 190 | name: name, |
||
| 191 | dir: link, |
||
| 192 | link: hash, |
||
| 193 | img: img, |
||
| 194 | cssClass: cssClass |
||
| 195 | }); |
||
| 196 | }, |
||
| 197 | |||
| 198 | /** |
||
| 199 | * Renders the full breadcrumb based on crumbs we have collected |
||
| 200 | * |
||
| 201 | * @private |
||
| 202 | */ |
||
| 203 | _render: function () { |
||
| 204 | this.breadcrumbsElement.children().remove(); |
||
| 205 | |||
| 206 | var breadcrumbs = Gallery.Templates.breadcrumb({ |
||
| 207 | crumbs: this.breadcrumbs |
||
| 208 | }); |
||
| 209 | |||
| 210 | this.breadcrumbsElement.append(breadcrumbs); |
||
| 211 | |||
| 212 | this.droppableOptions.drop = this.onDrop.bind(this); |
||
| 213 | this.breadcrumbsElement.find('.crumb:not(.last)').droppable(this.droppableOptions); |
||
| 214 | }, |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Alters the breadcrumb to make it fit within the asked dimensions |
||
| 218 | * |
||
| 219 | * @param {int} availableWidth |
||
| 220 | * |
||
| 221 | * @private |
||
| 222 | */ |
||
| 223 | _resize: function (availableWidth) { |
||
| 224 | var crumbs = this.breadcrumbsElement.children(); |
||
| 225 | var shorten = false; |
||
| 226 | var ellipsisPath = ''; |
||
| 227 | var self = this; |
||
| 228 | |||
| 229 | // Hide everything first, so that we can check the width after adding each crumb |
||
| 230 | crumbs.hide(); |
||
| 231 | |||
| 232 | // We go through the array in reverse order |
||
| 233 | var crumbsElement = crumbs.get().reverse(); |
||
| 234 | $(crumbsElement).each(function () { |
||
| 235 | if ($(this).hasClass('home')) { |
||
| 236 | $(this).show(); |
||
| 237 | if (self.breadcrumbs.length > 2) { |
||
| 238 | $(this).click(self.showLoader); |
||
| 239 | } |
||
| 240 | return; |
||
| 241 | } |
||
| 242 | // 1st sub-album has no-parent and the breadcrumbs contain home, ellipsis and last |
||
| 243 | if (self.breadcrumbs.length > 3) { |
||
| 244 | $(this).click(self.showLoader); |
||
| 245 | } |
||
| 246 | if ($(this).hasClass('ellipsis')) { |
||
| 247 | self.ellipsis = $(this); |
||
| 248 | return; |
||
| 249 | } |
||
| 250 | if (!shorten) { |
||
| 251 | $(this).show(); |
||
| 252 | } |
||
| 253 | |||
| 254 | // If we've reached the maximum width, we start hiding crumbs |
||
| 255 | if (self.breadcrumbsElement.width() > availableWidth) { |
||
| 256 | shorten = true; |
||
| 257 | $(this).hide(); |
||
| 258 | if (!ellipsisPath) { |
||
| 259 | ellipsisPath = $(this).data('dir'); |
||
| 260 | } |
||
| 261 | } |
||
| 262 | }); |
||
| 263 | |||
| 264 | // If we had to hide crumbs, we add a way to go to the parent folder |
||
| 265 | if (shorten) { |
||
| 266 | this.ellipsis.show(); |
||
| 267 | |||
| 268 | if (!ellipsisPath) { |
||
| 269 | ellipsisPath = OC.dirname(this.albumPath); |
||
| 270 | } |
||
| 271 | |||
| 272 | this.ellipsis.children('a').attr('href', '#' + encodeURIComponent(ellipsisPath)); |
||
| 273 | this.ellipsis.attr('data-original-title', ellipsisPath).tooltip({ |
||
| 274 | fade: true, |
||
| 275 | placement: 'bottom', |
||
| 276 | delay: { |
||
| 277 | hide: 5 |
||
| 278 | } |
||
| 279 | }); |
||
| 280 | } |
||
| 281 | } |
||
| 282 | }; |
||
| 283 | |||
| 284 | Gallery.Breadcrumb = Breadcrumb; |
||
| 285 | })(jQuery, OC, t, Gallery); |
||
| 286 |