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, Thumbnails */ |
||
13 | (function ($, _, OC, t, Gallery) { |
||
14 | "use strict"; |
||
15 | |||
16 | var TEMPLATE_ADDBUTTON = '<a href="#" class="button new"><span class="icon icon-add"></span><span class="hidden-visually">New</span></a>'; |
||
17 | |||
18 | /** |
||
19 | * Builds and updates the Gallery view |
||
20 | * |
||
21 | * @constructor |
||
22 | */ |
||
23 | var View = function () { |
||
24 | this.element = $('#gallery'); |
||
25 | this.loadVisibleRows.loading = false; |
||
26 | this._setupUploader(); |
||
27 | this.breadcrumb = new Gallery.Breadcrumb(); |
||
28 | this.emptyContentElement = $('#emptycontent'); |
||
29 | this.controlsElement = $('#controls'); |
||
30 | }; |
||
31 | |||
32 | View.prototype = { |
||
33 | element: null, |
||
34 | breadcrumb: null, |
||
35 | requestId: -1, |
||
36 | emptyContentElement: null, |
||
37 | controlsElement: null, |
||
38 | |||
39 | /** |
||
40 | * Removes all thumbnails from the view |
||
41 | */ |
||
42 | clear: function () { |
||
43 | this.loadVisibleRows.processing = false; |
||
44 | this.loadVisibleRows.loading = null; |
||
45 | // We want to keep all the events |
||
46 | this.element.children().detach(); |
||
47 | this.showLoading(); |
||
48 | }, |
||
49 | |||
50 | /** |
||
51 | * @param {string} path |
||
52 | * @returns {boolean} |
||
53 | */ |
||
54 | _isValidPath: function(path) { |
||
55 | var sections = path.split('/'); |
||
56 | for (var i = 0; i < sections.length; i++) { |
||
57 | if (sections[i] === '..') { |
||
58 | return false; |
||
59 | } |
||
60 | } |
||
61 | |||
62 | return path.toLowerCase().indexOf(decodeURI('%0a')) === -1 && |
||
63 | path.toLowerCase().indexOf(decodeURI('%00')) === -1; |
||
64 | }, |
||
65 | |||
66 | /** |
||
67 | * Populates the view if there are images or albums to show |
||
68 | * |
||
69 | * @param {string} albumPath |
||
70 | * @param {string|undefined} errorMessage |
||
71 | */ |
||
72 | init: function (albumPath, errorMessage) { |
||
73 | // Set path to an empty value if not a valid one |
||
74 | if(!this._isValidPath(albumPath)) { |
||
75 | albumPath = ''; |
||
76 | } |
||
77 | |||
78 | // Only do it when the app is initialised |
||
79 | if (this.requestId === -1) { |
||
80 | this._initButtons(); |
||
81 | this._blankUrl(); |
||
82 | } |
||
83 | if ($.isEmptyObject(Gallery.imageMap)) { |
||
84 | Gallery.view.showEmptyFolder(albumPath, errorMessage); |
||
85 | } else { |
||
86 | this.viewAlbum(albumPath); |
||
87 | } |
||
88 | |||
89 | this._setBackgroundColour(); |
||
90 | }, |
||
91 | |||
92 | /** |
||
93 | * Starts the slideshow |
||
94 | * |
||
95 | * @param {string} path |
||
96 | * @param {string} albumPath |
||
97 | */ |
||
98 | startSlideshow: function (path, albumPath) { |
||
99 | var album = Gallery.albumMap[albumPath]; |
||
100 | var images = album.images; |
||
101 | var startImage = Gallery.imageMap[path]; |
||
102 | Gallery.slideShow(images, startImage, false); |
||
103 | }, |
||
104 | |||
105 | /** |
||
106 | * Sets up the controls and starts loading the gallery rows |
||
107 | * |
||
108 | * @param {string|null} albumPath |
||
109 | */ |
||
110 | viewAlbum: function (albumPath) { |
||
111 | albumPath = albumPath || ''; |
||
112 | if (!Gallery.albumMap[albumPath]) { |
||
113 | return; |
||
114 | } |
||
115 | |||
116 | this.clear(); |
||
117 | |||
118 | if (albumPath !== Gallery.currentAlbum |
||
119 | || (albumPath === Gallery.currentAlbum && |
||
120 | Gallery.albumMap[albumPath].etag !== Gallery.currentEtag)) { |
||
121 | Gallery.currentAlbum = albumPath; |
||
122 | Gallery.currentEtag = Gallery.albumMap[albumPath].etag; |
||
123 | this._setupButtons(albumPath); |
||
124 | } |
||
125 | |||
126 | Gallery.albumMap[albumPath].viewedItems = 0; |
||
127 | Gallery.albumMap[albumPath].preloadOffset = 0; |
||
128 | |||
129 | // Each request has a unique ID, so that we can track which request a row belongs to |
||
130 | this.requestId = Math.random(); |
||
131 | Gallery.albumMap[Gallery.currentAlbum].requestId = this.requestId; |
||
132 | |||
133 | // Loading rows without blocking the execution of the rest of the script |
||
134 | setTimeout(function () { |
||
135 | this.loadVisibleRows.activeIndex = 0; |
||
136 | this.loadVisibleRows(Gallery.albumMap[Gallery.currentAlbum]); |
||
137 | }.bind(this), 0); |
||
138 | }, |
||
139 | |||
140 | /** |
||
141 | * Manages the sorting interface |
||
142 | * |
||
143 | * @param {string} sortType name or date |
||
144 | * @param {string} sortOrder asc or des |
||
145 | */ |
||
146 | sortControlsSetup: function (sortType, sortOrder) { |
||
147 | var reverseSortType = 'date'; |
||
148 | if (sortType === 'date') { |
||
149 | reverseSortType = 'name'; |
||
150 | } |
||
151 | this._setSortButton(sortType, sortOrder, true); |
||
152 | this._setSortButton(reverseSortType, 'asc', false); // default icon |
||
153 | }, |
||
154 | |||
155 | /** |
||
156 | * Loads and displays gallery rows on screen |
||
157 | * |
||
158 | * view.loadVisibleRows.loading holds the Promise of a row |
||
159 | * |
||
160 | * @param {Album} album |
||
161 | */ |
||
162 | loadVisibleRows: function (album) { |
||
163 | var view = this; |
||
164 | // Wait for the previous request to be completed |
||
165 | if (this.loadVisibleRows.processing) { |
||
166 | return; |
||
167 | } |
||
168 | |||
169 | /** |
||
170 | * At this stage, there is no loading taking place, so we can look for new rows |
||
171 | */ |
||
172 | |||
173 | var scroll = $(window).scrollTop() + $(window).scrollTop(); |
||
174 | // 2 windows worth of rows is the limit from which we need to start loading new rows. |
||
175 | // As we scroll down, it grows |
||
176 | var targetHeight = ($(window).height() * 2) + scroll; |
||
177 | // We throttle rows in order to try and not generate too many CSS resizing events at |
||
178 | // the same time |
||
179 | var showRows = _.throttle(function (album) { |
||
180 | |||
181 | // If we've reached the end of the album, we kill the loader |
||
182 | if (!(album.viewedItems < album.subAlbums.length + album.images.length)) { |
||
183 | view.loadVisibleRows.processing = false; |
||
184 | view.loadVisibleRows.loading = null; |
||
185 | return; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
![]() |
|||
186 | } |
||
187 | |||
188 | // Prevents creating rows which are no longer required. I.e when changing album |
||
189 | if (view.requestId !== album.requestId) { |
||
190 | return; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
191 | } |
||
192 | |||
193 | // We can now safely create a new row |
||
194 | var row = album.getRow($(window).width()); |
||
195 | var rowDom = row.getDom(); |
||
196 | view.element.append(rowDom); |
||
197 | |||
198 | return album.fillNextRow(row).then(function () { |
||
199 | if (album.viewedItems < album.subAlbums.length + album.images.length && |
||
200 | view.element.height() < targetHeight) { |
||
201 | return showRows(album); |
||
202 | } |
||
203 | // No more rows to load at the moment |
||
204 | view.loadVisibleRows.processing = false; |
||
205 | view.loadVisibleRows.loading = null; |
||
0 ignored issues
–
show
|
|||
206 | }, function () { |
||
207 | // Something went wrong, so kill the loader |
||
208 | view.loadVisibleRows.processing = false; |
||
209 | view.loadVisibleRows.loading = null; |
||
210 | }); |
||
211 | }, 100); |
||
212 | if (this.element.height() < targetHeight) { |
||
213 | this._showNormal(); |
||
214 | this.loadVisibleRows.processing = true; |
||
215 | album.requestId = view.requestId; |
||
216 | this.loadVisibleRows.loading = showRows(album); |
||
217 | } |
||
218 | }, |
||
219 | |||
220 | /** |
||
221 | * Shows an empty gallery message |
||
222 | * |
||
223 | * @param {string} albumPath |
||
224 | * @param {string|null} errorMessage |
||
225 | */ |
||
226 | showEmptyFolder: function (albumPath, errorMessage) { |
||
227 | var message = '<div class="icon-gallery"></div>'; |
||
228 | var uploadAllowed = true; |
||
229 | |||
230 | this.element.children().detach(); |
||
231 | this.removeLoading(); |
||
232 | |||
233 | if (!_.isUndefined(errorMessage) && errorMessage !== null) { |
||
234 | message += '<h2>' + t('gallery', |
||
235 | 'Album cannot be shown') + '</h2>'; |
||
236 | message += '<p>' + escapeHTML(errorMessage) + '</p>'; |
||
237 | uploadAllowed = false; |
||
238 | } else { |
||
239 | message += '<h2>' + t('gallery', |
||
240 | 'No media files found') + '</h2>'; |
||
241 | // We can't upload yet on the public side |
||
242 | if (Gallery.token) { |
||
243 | message += '<p>' + t('gallery', |
||
244 | 'Upload pictures in the Files app to display them here') + '</p>'; |
||
245 | } else { |
||
246 | message += '<p>' + t('gallery', |
||
247 | 'Upload new files via drag and drop or by using the [+] button above') + |
||
248 | '</p>'; |
||
249 | } |
||
250 | } |
||
251 | this.emptyContentElement.html(message); |
||
252 | this.emptyContentElement.removeClass('hidden'); |
||
253 | |||
254 | this._hideButtons(uploadAllowed); |
||
255 | Gallery.currentAlbum = albumPath; |
||
256 | var availableWidth = $(window).width() - Gallery.buttonsWidth; |
||
257 | this.breadcrumb.init(albumPath, availableWidth); |
||
258 | Gallery.config.albumDesign = null; |
||
259 | }, |
||
260 | |||
261 | /** |
||
262 | * Dims the controls bar when retrieving new content. Matches the effect in Files |
||
263 | */ |
||
264 | dimControls: function () { |
||
265 | // Use the existing mask if its already there |
||
266 | var $mask = this.controlsElement.find('.mask'); |
||
267 | if ($mask.exists()) { |
||
268 | return; |
||
269 | } |
||
270 | $mask = $('<div class="mask transparent"></div>'); |
||
271 | this.controlsElement.append($mask); |
||
272 | $mask.removeClass('transparent'); |
||
273 | }, |
||
274 | |||
275 | /** |
||
276 | * Shows the infamous loading spinner |
||
277 | */ |
||
278 | showLoading: function () { |
||
279 | this.emptyContentElement.addClass('hidden'); |
||
280 | this.controlsElement.removeClass('hidden'); |
||
281 | $('#content').addClass('icon-loading'); |
||
282 | this.dimControls(); |
||
283 | }, |
||
284 | |||
285 | /** |
||
286 | * Removes the spinner in the main area and restore normal visibility of the controls bar |
||
287 | */ |
||
288 | removeLoading: function () { |
||
289 | $('#content').removeClass('icon-loading'); |
||
290 | this.controlsElement.find('.mask').remove(); |
||
291 | }, |
||
292 | |||
293 | /** |
||
294 | * Shows thumbnails |
||
295 | */ |
||
296 | _showNormal: function () { |
||
297 | this.emptyContentElement.addClass('hidden'); |
||
298 | this.controlsElement.removeClass('hidden'); |
||
299 | this.removeLoading(); |
||
300 | }, |
||
301 | |||
302 | /** |
||
303 | * Sets up our custom handlers for folder uploading operations |
||
304 | * |
||
305 | * @see OC.Upload.init/file_upload_param.done() |
||
306 | * |
||
307 | * @private |
||
308 | */ |
||
309 | _setupUploader: function () { |
||
310 | var $uploadEl = $('#file_upload_start'); |
||
311 | if (!$uploadEl.exists()) { |
||
312 | return; |
||
313 | } |
||
314 | |||
315 | this._operationProgressBar = new OCA.Files.OperationProgressBar(); |
||
316 | this._operationProgressBar.render(); |
||
317 | $('#content').find('#uploadprogresswrapper').replaceWith(this._operationProgressBar.$el); |
||
318 | |||
319 | this._uploader = new OC.Uploader($uploadEl, { |
||
320 | fileList: FileList, |
||
321 | dropZone: $('#content'), |
||
322 | progressBar: this._operationProgressBar |
||
323 | }); |
||
324 | this._uploader.on('add', function (e, data) { |
||
325 | data.targetDir = '/' + Gallery.currentAlbum; |
||
326 | }); |
||
327 | this._uploader.on('done', function (e, upload) { |
||
328 | var data = upload.data; |
||
329 | |||
330 | // is that the last upload ? |
||
331 | if (data.files[0] === data.originalFiles[data.originalFiles.length - 1]) { |
||
332 | var fileList = data.originalFiles; |
||
333 | //Ask for a refresh of the photowall |
||
334 | Gallery.getFiles(Gallery.currentAlbum).done(function () { |
||
335 | var fileId, path; |
||
336 | // Removes the cached thumbnails of files which have been re-uploaded |
||
337 | _(fileList).each(function (fileName) { |
||
338 | path = Gallery.currentAlbum + '/' + fileName; |
||
339 | if (Gallery.imageMap[path]) { |
||
340 | fileId = Gallery.imageMap[path].fileId; |
||
341 | if (Thumbnails.map[fileId]) { |
||
342 | delete Thumbnails.map[fileId]; |
||
343 | } |
||
344 | } |
||
345 | }); |
||
346 | |||
347 | Gallery.view.init(Gallery.currentAlbum); |
||
348 | }); |
||
349 | } |
||
350 | }); |
||
351 | |||
352 | // Since Nextcloud 9.0 |
||
353 | if (OC.Uploader) { |
||
354 | OC.Uploader.prototype._isReceivedSharedFile = function (file) { |
||
355 | var path = file.name; |
||
356 | var sharedWith = false; |
||
357 | |||
358 | if (Gallery.currentAlbum !== '' && Gallery.currentAlbum !== '/') { |
||
359 | path = Gallery.currentAlbum + '/' + path; |
||
360 | } |
||
361 | if (Gallery.imageMap[path] && Gallery.imageMap[path].sharedWithUser) { |
||
362 | sharedWith = true; |
||
363 | } |
||
364 | |||
365 | return sharedWith; |
||
366 | }; |
||
367 | } |
||
368 | }, |
||
369 | |||
370 | /** |
||
371 | * Adds all the click handlers to buttons the first time they appear in the interface |
||
372 | * |
||
373 | * @private |
||
374 | */ |
||
375 | _initButtons: function () { |
||
376 | this.element.on("contextmenu", function(e) { e.preventDefault(); }); |
||
377 | $('#filelist-button').click(Gallery.switchToFilesView); |
||
378 | $('#download').click(Gallery.download); |
||
379 | $('#shared-button').click(Gallery.share); |
||
380 | Gallery.infoBox = new Gallery.InfoBox(); |
||
381 | $('#album-info-button').click(Gallery.showInfo); |
||
382 | $('#sort-name-button').click(Gallery.sorter); |
||
383 | $('#sort-date-button').click(Gallery.sorter); |
||
384 | $('.save-form').submit(Gallery.saveForm); |
||
385 | this._renderNewButton(); |
||
386 | // Trigger cancelling of file upload |
||
387 | $('#uploadprogresswrapper .stop').on('click', function () { |
||
388 | OC.Upload.cancelUploads(); |
||
389 | }); |
||
390 | this.requestId = Math.random(); |
||
391 | }, |
||
392 | |||
393 | /** |
||
394 | * Sets up all the buttons of the interface and the breadcrumbs |
||
395 | * |
||
396 | * @param {string} albumPath |
||
397 | * @private |
||
398 | */ |
||
399 | _setupButtons: function (albumPath) { |
||
400 | this._shareButtonSetup(albumPath); |
||
401 | this._infoButtonSetup(); |
||
402 | |||
403 | var availableWidth = $(window).width() - Gallery.buttonsWidth; |
||
404 | this.breadcrumb.init(albumPath, availableWidth); |
||
405 | var album = Gallery.albumMap[albumPath]; |
||
406 | |||
407 | var sum = album.images.length + album.subAlbums.length; |
||
408 | //If sum of the number of images and subalbums exceeds 1 then show the buttons. |
||
409 | if(sum > 1) |
||
410 | { |
||
411 | $('#sort-name-button').show(); |
||
412 | $('#sort-date-button').show(); |
||
413 | } |
||
414 | else |
||
415 | { |
||
416 | $('#sort-name-button').hide(); |
||
417 | $('#sort-date-button').hide(); |
||
418 | } |
||
419 | var currentSort = Gallery.config.albumSorting; |
||
420 | this.sortControlsSetup(currentSort.type, currentSort.order); |
||
421 | Gallery.albumMap[Gallery.currentAlbum].images.sort( |
||
422 | Gallery.utility.sortBy(currentSort.type, |
||
423 | currentSort.order)); |
||
424 | Gallery.albumMap[Gallery.currentAlbum].subAlbums.sort(Gallery.utility.sortBy('name', |
||
425 | currentSort.albumOrder)); |
||
426 | |||
427 | $('#save-button').show(); |
||
428 | $('#download').show(); |
||
429 | $('a.button.new').show(); |
||
430 | }, |
||
431 | |||
432 | /** |
||
433 | * Hide buttons in the controls bar |
||
434 | * |
||
435 | * @param uploadAllowed |
||
436 | */ |
||
437 | _hideButtons: function (uploadAllowed) { |
||
438 | $('#album-info-button').hide(); |
||
439 | $('#shared-button').hide(); |
||
440 | $('#sort-name-button').hide(); |
||
441 | $('#sort-date-button').hide(); |
||
442 | $('#save-button').hide(); |
||
443 | $('#download').hide(); |
||
444 | |||
445 | if (!uploadAllowed) { |
||
446 | $('a.button.new').hide(); |
||
447 | } |
||
448 | }, |
||
449 | |||
450 | /** |
||
451 | * Shows or hides the share button depending on if we're in a public gallery or not |
||
452 | * |
||
453 | * @param {string} albumPath |
||
454 | * @private |
||
455 | */ |
||
456 | _shareButtonSetup: function (albumPath) { |
||
457 | var shareButton = $('#shared-button'); |
||
458 | if (albumPath === '' || Gallery.token) { |
||
459 | shareButton.hide(); |
||
460 | } else { |
||
461 | shareButton.show(); |
||
462 | } |
||
463 | }, |
||
464 | |||
465 | /** |
||
466 | * Shows or hides the info button based on the information we've received from the server |
||
467 | * |
||
468 | * @private |
||
469 | */ |
||
470 | _infoButtonSetup: function () { |
||
471 | var infoButton = $('#album-info-button'); |
||
472 | infoButton.find('span').hide(); |
||
473 | var infoContentContainer = $('.album-info-container'); |
||
474 | infoContentContainer.slideUp(); |
||
475 | infoContentContainer.css('max-height', |
||
476 | $(window).height() - Gallery.browserToolbarHeight); |
||
477 | var albumInfo = Gallery.config.albumInfo; |
||
478 | if (Gallery.config.albumError) { |
||
479 | infoButton.hide(); |
||
480 | var text = '<strong>' + t('gallery', 'Configuration error') + '</strong></br>' + |
||
481 | Gallery.config.albumError.message + '</br></br>'; |
||
482 | Gallery.utility.showHtmlNotification(text, 7); |
||
483 | } else if ($.isEmptyObject(albumInfo)) { |
||
484 | infoButton.hide(); |
||
485 | } else { |
||
486 | infoButton.show(); |
||
487 | if (albumInfo.inherit !== 'yes' || albumInfo.level === 0) { |
||
488 | infoButton.find('span').delay(1000).slideDown(); |
||
489 | } |
||
490 | } |
||
491 | }, |
||
492 | |||
493 | /** |
||
494 | * Sets the background colour of the photowall |
||
495 | * |
||
496 | * @private |
||
497 | */ |
||
498 | _setBackgroundColour: function () { |
||
499 | var wrapper = $('#app-content'); |
||
500 | var albumDesign = Gallery.config.albumDesign; |
||
501 | if (!$.isEmptyObject(albumDesign) && albumDesign.background) { |
||
502 | wrapper.css('background-color', albumDesign.background); |
||
503 | } else { |
||
504 | wrapper.css('background-color', '#fff'); |
||
505 | } |
||
506 | }, |
||
507 | |||
508 | /** |
||
509 | * Picks the image which matches the sort order |
||
510 | * |
||
511 | * @param {string} sortType name or date |
||
512 | * @param {string} sortOrder asc or des |
||
513 | * @param {boolean} active determines if we're setting up the active sort button |
||
514 | * @private |
||
515 | */ |
||
516 | _setSortButton: function (sortType, sortOrder, active) { |
||
517 | var button = $('#sort-' + sortType + '-button'); |
||
518 | // Removing all the classes which control the image in the button |
||
519 | button.removeClass('active'); |
||
520 | button.find('img').removeClass('front'); |
||
521 | button.find('img').removeClass('back'); |
||
522 | |||
523 | // We need to determine the reverse order in order to send that image to the back |
||
524 | var reverseSortOrder = 'des'; |
||
525 | if (sortOrder === 'des') { |
||
526 | reverseSortOrder = 'asc'; |
||
527 | } |
||
528 | |||
529 | // We assign the proper order to the button images |
||
530 | button.find('img.' + sortOrder).addClass('front'); |
||
531 | button.find('img.' + reverseSortOrder).addClass('back'); |
||
532 | |||
533 | // The active button needs a hover action for the flip effect |
||
534 | if (active) { |
||
535 | button.addClass('active'); |
||
536 | if (button.is(":hover")) { |
||
537 | button.removeClass('hover'); |
||
538 | } |
||
539 | // We can't use a toggle here |
||
540 | button.hover(function () { |
||
541 | $(this).addClass('hover'); |
||
542 | }, |
||
543 | function () { |
||
544 | $(this).removeClass('hover'); |
||
545 | }); |
||
546 | } |
||
547 | }, |
||
548 | |||
549 | /** |
||
550 | * If no url is entered then do not show the error box. |
||
551 | * |
||
552 | */ |
||
553 | _blankUrl: function() { |
||
554 | $('#remote_address').on("change keyup paste", function() { |
||
555 | if ($(this).val() === '') { |
||
556 | $('#save-button-confirm').prop('disabled', true); |
||
557 | } else { |
||
558 | $('#save-button-confirm').prop('disabled', false); |
||
559 | } |
||
560 | }); |
||
561 | }, |
||
562 | |||
563 | /** |
||
564 | * Creates the [+] button allowing users who can't drag and drop to upload files |
||
565 | * |
||
566 | * @see core/apps/files/js/filelist.js |
||
567 | * @private |
||
568 | */ |
||
569 | _renderNewButton: function () { |
||
570 | // if no actions container exist, skip |
||
571 | var $actionsContainer = $('.actions'); |
||
572 | if (!$actionsContainer.length) { |
||
573 | return; |
||
574 | } |
||
575 | |||
576 | var $newButton = $(TEMPLATE_ADDBUTTON); |
||
577 | |||
578 | $actionsContainer.prepend($newButton); |
||
579 | $newButton.tooltip({'placement': 'bottom'}); |
||
580 | |||
581 | $newButton.click(_.bind(this._onClickNewButton, this)); |
||
582 | this._newButton = $newButton; |
||
583 | }, |
||
584 | |||
585 | /** |
||
586 | * Creates the click handler for the [+] button |
||
587 | * @param event |
||
588 | * @returns {boolean} |
||
589 | * |
||
590 | * @see core/apps/files/js/filelist.js |
||
591 | * @private |
||
592 | */ |
||
593 | _onClickNewButton: function (event) { |
||
594 | var $target = $(event.target); |
||
595 | if (!$target.hasClass('.button')) { |
||
596 | $target = $target.closest('.button'); |
||
597 | } |
||
598 | this._newButton.tooltip('hide'); |
||
599 | event.preventDefault(); |
||
600 | if ($target.hasClass('disabled')) { |
||
601 | return false; |
||
602 | } |
||
603 | if (!this._newFileMenu) { |
||
604 | this._newFileMenu = new Gallery.NewFileMenu(); |
||
605 | $('.actions').append(this._newFileMenu.$el); |
||
606 | } |
||
607 | this._newFileMenu.showAt($target); |
||
608 | |||
609 | if (Gallery.currentAlbum === '') { |
||
610 | $('.menuitem[data-action="hideAlbum"]').parent().hide(); |
||
611 | } |
||
612 | return false; |
||
613 | } |
||
614 | }; |
||
615 | |||
616 | Gallery.View = View; |
||
617 | })(jQuery, _, OC, t, Gallery); |
||
618 |