Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/gallery.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--js/album.js486
-rw-r--r--js/breadcrumb.js7
-rw-r--r--js/eventsource.js5
-rw-r--r--js/gallery.js4
-rw-r--r--js/galleryalbum.js300
-rw-r--r--js/gallerybutton.js10
-rw-r--r--js/galleryfileaction.js4
-rw-r--r--js/galleryimage.js115
-rw-r--r--js/galleryrow.js92
-rw-r--r--js/galleryview.js4
-rw-r--r--js/thumbnail.js235
-rw-r--r--templates/part.content.php4
-rw-r--r--templates/public.php4
13 files changed, 654 insertions, 616 deletions
diff --git a/js/album.js b/js/album.js
deleted file mode 100644
index 3b7f964b..00000000
--- a/js/album.js
+++ /dev/null
@@ -1,486 +0,0 @@
-/* global $, OC, Gallery, Thumbnails */
-/**
- * Creates a new album object to store information about an album
- *
- * @param {string} path
- * @param {Array<Album|GalleryImage>} subAlbums
- * @param {Array<Album|GalleryImage>} images
- * @param {string} name
- * @constructor
- */
-function Album (path, subAlbums, images, name) {
- this.path = path;
- this.subAlbums = subAlbums;
- this.images = images;
- this.viewedItems = 0;
- this.name = name;
- this.domDef = null;
- this.preloadOffset = 0;
-}
-
-/**
- * Creates a row
- *
- * @param targetWidth
- * @param requestId
- * @constructor
- */
-function Row (targetWidth, requestId) {
- this.targetWidth = targetWidth;
- this.items = [];
- this.width = 8; // 4px margin to start with
- this.requestId = requestId;
-}
-
-/**
- * Creates a new image object to store information about a media file
- *
- * @param src
- * @param path
- * @param fileId
- * @param mimeType
- * @param mTime modification time
- * @param etag
- * @constructor
- */
-function GalleryImage (src, path, fileId, mimeType, mTime, etag) {
- this.src = src;
- this.path = path;
- this.fileId = fileId;
- this.mimeType = mimeType;
- this.mTime = mTime;
- this.etag = etag;
- this.thumbnail = null;
- this.domDef = null;
- this.domHeigth = null;
-}
-
-Album.prototype = {
- _getThumbnail: function () {
- if (this.images.length) {
- return this.images[0].getThumbnail(true);
- }
- return this.subAlbums[0]._getThumbnail();
- },
-
- /**
- * Retrieves a thumbnail and adds it to the album representation
- *
- * Only attaches valid thumbnails to the album
- *
- * @param {GalleryImage} image
- * @param {number} targetHeight Each row has a specific height
- * @param {number} calcWidth Album width
- * @param {object} a
- *
- * @returns {$.Deferred<Thumbnail>}
- * @private
- */
- _getOneImage: function (image, targetHeight, calcWidth, a) {
- // img is a Thumbnail.image, true means square thumbnails
- return image.getThumbnail(true).then(function (img) {
- if (image.thumbnail.valid) {
- var backgroundHeight, backgroundWidth;
- img.alt = '';
-
- backgroundHeight = (targetHeight / 2);
- backgroundWidth = calcWidth - 2.01;
-
- // Adjust the size because of the margins around pictures
- backgroundHeight -= 2;
-
- var croppedDiv = $('<div class="cropped">');
- croppedDiv.css("background-image", "url('" + img.src + "')");
- croppedDiv.css("height", backgroundHeight);
- croppedDiv.css("width", backgroundWidth);
- a.append(croppedDiv);
- }
- });
- },
-
- /**
- * Builds the album representation by placing 1 to 4 images on a grid
- *
- * @param {array<GalleryImage>} images
- * @param {number} targetHeight Each row has a specific height
- * @param {object} a
- *
- * @returns {$.Deferred<array>}
- * @private
- */
- _getFourImages: function (images, targetHeight, a) {
- var calcWidth = targetHeight / 2;
- var targetWidth;
- var imagesCount = images.length;
- var def = new $.Deferred();
- var validImages = [];
- var fail = false;
- var thumbsArray = [];
-
- for (var i = 0; i < imagesCount; i++) {
- targetWidth = calcWidth;
- if (imagesCount === 2 || (imagesCount === 3 && i === 0)) {
- targetWidth = calcWidth * 2;
- }
- targetWidth = targetWidth.toFixed(3);
-
- thumbsArray.push(this._getOneImage(images[i], targetHeight, targetWidth, a));
- }
-
- var labelWidth = (targetHeight - 0.01);
- a.find('.album-label').width(labelWidth);
-
- // This technique allows us to wait for all objects to be resolved before making a decision
- $.when.apply($, thumbsArray).done(function () {
- for (var i = 0; i < imagesCount; i++) {
- // Collect all valid images, just in case
- if (images[i].thumbnail.valid) {
- validImages.push(images[i]);
- } else {
- fail = true;
- }
- }
-
- // At least one thumbnail could not be retrieved
- if (fail) {
- // Clean up the album
- a.children().not('.album-label').remove();
- // Send back the list of images which have thumbnails
- def.reject(validImages);
- }
- });
-
- return def.promise();
- },
-
- /**
- * Fills the album representation with images we've received
- *
- * * Each album includes between 1 and 4 images
- * * Each album is also a link to open that folder
- * * An album has a natural size of 200x200 and is comprised of 4 thumbnails which have a
- * natural size of 200x200 The whole thing gets resized to match the targetHeight
- *
- * @param targetHeight
- * @param a
- * @private
- */
- _fillSubAlbum: function (targetHeight, a) {
- var album = this;
-
- if (this.images.length > 1) {
- this._getFourImages(this.images, targetHeight, a).fail(function (validImages) {
- album.images = validImages;
- album._fillSubAlbum(targetHeight, a);
- });
- } else if (this.images.length === 1) {
- this._getOneImage(this.images[0], 2 * targetHeight, targetHeight, a).fail(function () {
- album.images = [];
- album._showFolder(targetHeight, a);
- });
- } else {
- this._showFolder(targetHeight, a);
- }
- },
-
- /**
- * Shows a folder icon in the album since we couldn't get any proper thumbnail
- *
- * @param {number} targetHeight
- * @param a
- * @private
- */
- _showFolder: function (targetHeight, a) {
- var image = new GalleryImage('Generic folder', 'Generic folder', -1, 'image/png',
- Gallery.token);
- var thumb = Thumbnails.getStandardIcon(-1);
- image.thumbnail = thumb;
- this.images.push(image);
- thumb.loadingDeferred.done(function (img) {
- a.append(img);
- img.height = (targetHeight - 2);
- img.width = (targetHeight) - 2;
- });
- },
-
- /**
- * Preloads the first $count thumbnails
- *
- * @param {number} count
- * @private
- */
- _preload: function (count) {
- var items = this.subAlbums.concat(this.images);
- var realCounter = 0;
- var maxThumbs = 0;
- var fileIds = [];
- var squareFileIds = [];
- for (var i = this.preloadOffset; i < this.preloadOffset + count && i < items.length; i++) {
- if (items[i].subAlbums) {
- maxThumbs = 4;
- var imagesLength = items[i].images.length;
- if (imagesLength > 0 && imagesLength < 4) {
- maxThumbs = imagesLength;
- }
- var squareFileId = items[i].getThumbnailIds(maxThumbs);
- squareFileIds = squareFileIds.concat(squareFileId);
- realCounter = realCounter + maxThumbs;
- } else {
- var fileId = items[i].getThumbnailIds();
- fileIds = fileIds.concat(fileId);
- realCounter++;
- }
- if (realCounter >= count) {
- i++;
- break;
- }
- }
-
- this.preloadOffset = i;
- Thumbnails.loadBatch(fileIds, false);
- Thumbnails.loadBatch(squareFileIds, true);
- },
-
- /**
- * Creates the album, which will include between 1 and 4 images
- *
- * * Each album is also a link to open that folder
- * * An album has a natural size of 200x200 and is comprised of 4 thumbnails which have a
- * natural size of 200x200 The whole thing gets resized to match the targetHeight
- * * Thumbnails are checked first in order to make sure that we have something to show
- *
- * @param {number} targetHeight Each row has a specific height
- *
- * @return {a} The album to be placed on the row
- */
- getDom: function (targetHeight) {
- var album = this;
-
- return this._getThumbnail().then(function () {
- var a = $('<a/>').addClass('album').attr('href', '#' + encodeURIComponent(album.path));
-
- a.append($('<span/>').addClass('album-label').text(album.name));
-
- a.width(targetHeight);
- a.height(targetHeight);
-
- album._fillSubAlbum(targetHeight, a);
-
- return a;
- });
- },
-
- /**
- * Fills the row with albums and images
- *
- * @param {number} width
- * @returns {$.Deferred<Row>}
- */
- getNextRow: function (width) {
- var numberOfThumbnailsToPreload = 6;
-
- /**
- * Add images to the row until it's full
- *
- * @todo The number of images to preload should be a user setting
- *
- * @param {Album} album
- * @param {Row} row
- * @param {Array<Album|GalleryImage>} images
- *
- * @returns {$.Deferred<Row>}
- */
- var addRowElements = function (album, row, images) {
- if ((album.viewedItems + 5) > album.preloadOffset) {
- album._preload(numberOfThumbnailsToPreload);
- }
-
- var image = images[album.viewedItems];
- return row.addElement(image).then(function (more) {
- album.viewedItems++;
- if (more && album.viewedItems < images.length) {
- return addRowElements(album, row, images);
- }
- return row;
- });
- };
- var items = this.subAlbums.concat(this.images);
- var row = new Row(width, this.requestId);
- return addRowElements(this, row, items);
- },
-
- /**
- * Returns IDs of thumbnails belonging to the album
- *
- * @param {number} count
- *
- * @return number[]
- */
- getThumbnailIds: function (count) {
- var ids = [];
- var items = this.images.concat(this.subAlbums);
- for (var i = 0; i < items.length && i < count; i++) {
- ids = ids.concat(items[i].getThumbnailIds(count));
- }
-
- return ids;
- }
-};
-
-Row.prototype = {
- /**
- * Calculates if the row is full
- *
- * @returns {boolean}
- * @private
- */
- _isFull: function () {
- return this.width > this.targetWidth;
- },
-
- /**
- * Adds sub-albums and images to the row until it's full
- *
- * @param {Album|GalleryImage} element
- *
- * @return {jQuery.Deferred<bool>} true if more images can be added to the row
- */
- addElement: function (element) {
- var row = this;
- var fileNotFoundStatus = 404;
- var def = new $.Deferred();
-
- var appendDom = function (width) {
- row.items.push(element);
- row.width += width + 4; // add 4px for the margin
- def.resolve(!row._isFull());
- };
-
- // No need to use getThumbnailWidth() for albums, the width is always 200
- if (element instanceof Album) {
- var width = 200;
- appendDom(width);
- } else {
- element.getThumbnailWidth().then(function (width) {
- if (element.thumbnail.status !== fileNotFoundStatus) {
- appendDom(width);
- } else {
- def.resolve(true);
- }
- }, function () {
- def.resolve(true);
- });
- }
-
- return def.promise();
- },
-
- getDom: function () {
- var scaleRatio = (this.width > this.targetWidth) ? this.targetWidth / this.width : 1;
- var targetHeight = 200 * scaleRatio;
- targetHeight = targetHeight.toFixed(3);
- var row = $('<div/>').addClass('row loading');
- /**
- * @param row
- * @param {GalleryImage[]} items
- * @param i
- * @returns {*}
- */
- var addImageToDom = function (row, items, i) {
- return items[i].getDom(targetHeight).then(function (itemDom) {
- i++;
- row.append(itemDom);
- if (i < items.length) {
- return addImageToDom(row, items, i);
- }
- return row;
- });
- };
- return addImageToDom(row, this.items, 0);
- }
-};
-
-GalleryImage.prototype = {
- /**
- * Returns the Thumbnail ID
- *
- * @returns {[number]}
- */
- getThumbnailIds: function () {
- return [this.fileId];
- },
-
- /**
- * Returns a reference to a loading Thumbnail.image
- *
- * @param {bool} square
- *
- * @returns {jQuery.Deferred<Thumbnail.image>}
- */
- getThumbnail: function (square) {
- if (this.thumbnail === null) {
- this.thumbnail = Thumbnails.get(this.fileId, square);
- }
- return this.thumbnail.loadingDeferred;
- },
-
- /**
- * Returns the width of a thumbnail
- *
- * Used to calculate the width of the row as we add more images to it
- *
- * @returns {number}
- */
- getThumbnailWidth: function () {
-
- // img is a Thumbnail.image
- return this.getThumbnail(false).then(function (img) {
- if (img) {
- return img.originalWidth;
- }
- return 0;
- });
- },
-
- /**
- * Creates the a and img element in the DOM
- *
- * Each image is also a link to start the full screen slideshow
- *
- * @return {a}
- */
- getDom: function (targetHeight) {
- var image = this;
- if (this.domDef === null || this.domHeigth !== targetHeight) {
- this.domHeigth = targetHeight;
- // img is a Thumbnail.image
- this.domDef = this.getThumbnail(false).then(function (img) {
- img.height = targetHeight;
- img.width = targetHeight * img.ratio;
- img.setAttribute('width', 'auto');
- img.alt = encodeURI(image.path);
- var url = '#' + encodeURIComponent(image.path);
-
- if (!image.thumbnail.valid) {
- url = Gallery.utility.getPreviewUrl(image.fileId, image.etag);
- url = url + '&download';
- }
- var a = $('<a/>').addClass('image').attr('href', url).attr('data-path', image.path);
-
- var imageLabel = $('<span/>').addClass('image-label');
- var imageTitle = $('<span/>').addClass('title').html(
- OC.basename(image.path));
- imageLabel.append(imageTitle);
- a.hover(function () {
- imageLabel.slideToggle(OC.menuSpeed);
- }, function () {
- imageLabel.slideToggle(OC.menuSpeed);
- });
- a.append(imageLabel);
- a.append(img);
- return a;
- });
- }
- return this.domDef;
- }
-};
diff --git a/js/breadcrumb.js b/js/breadcrumb.js
index e0a754ab..3d6f67f7 100644
--- a/js/breadcrumb.js
+++ b/js/breadcrumb.js
@@ -1,5 +1,6 @@
-/* global $, OC, t, Gallery */
-(function () {
+/* global Gallery */
+(function ($, OC, t, Gallery) {
+ "use strict";
/**
* Breadcrumbs that represent the path to the current album
*
@@ -173,4 +174,4 @@
};
Gallery.Breadcrumb = Breadcrumb;
-})();
+})(jQuery, OC, t, Gallery);
diff --git a/js/eventsource.js b/js/eventsource.js
index c70ea938..77a85b53 100644
--- a/js/eventsource.js
+++ b/js/eventsource.js
@@ -17,7 +17,8 @@
*/
/* global EventSource, oc_requesttoken, Gallery */
-(function () {
+(function (oc_requesttoken) {
+ "use strict";
/**
* Create a new event source
*
@@ -102,4 +103,4 @@
};
Gallery.EventSource = CustomEventSource;
-})();
+})(oc_requesttoken);
diff --git a/js/gallery.js b/js/gallery.js
index a2fceeda..ab749d47 100644
--- a/js/gallery.js
+++ b/js/gallery.js
@@ -1,5 +1,5 @@
/* global Album, GalleryImage */
-(function (OC, $, t) {
+(function ($, OC, t) {
"use strict";
var Gallery = {
currentAlbum: null,
@@ -487,4 +487,4 @@
}
};
window.Gallery = Gallery;
-}(OC, jQuery, t));
+})(jQuery, OC, t);
diff --git a/js/galleryalbum.js b/js/galleryalbum.js
new file mode 100644
index 00000000..6d31a7a1
--- /dev/null
+++ b/js/galleryalbum.js
@@ -0,0 +1,300 @@
+/* global Gallery, Thumbnails, GalleryImage, Row */
+(function ($, Gallery) {
+ "use strict";
+ /**
+ * Creates a new album object to store information about an album
+ *
+ * @param {string} path
+ * @param {Array<Album|GalleryImage>} subAlbums
+ * @param {Array<Album|GalleryImage>} images
+ * @param {string} name
+ * @constructor
+ */
+ var Album = function (path, subAlbums, images, name) {
+ this.path = path;
+ this.subAlbums = subAlbums;
+ this.images = images;
+ this.viewedItems = 0;
+ this.name = name;
+ this.domDef = null;
+ this.preloadOffset = 0;
+ };
+
+ Album.prototype = {
+ _getThumbnail: function () {
+ if (this.images.length) {
+ return this.images[0].getThumbnail(true);
+ }
+ return this.subAlbums[0]._getThumbnail();
+ },
+
+ /**
+ * Retrieves a thumbnail and adds it to the album representation
+ *
+ * Only attaches valid thumbnails to the album
+ *
+ * @param {Image} image
+ * @param {number} targetHeight Each row has a specific height
+ * @param {number} calcWidth Album width
+ * @param {object} a
+ *
+ * @returns {$.Deferred<Thumbnail>}
+ * @private
+ */
+ _getOneImage: function (image, targetHeight, calcWidth, a) {
+ // img is a Thumbnail.image, true means square thumbnails
+ return image.getThumbnail(true).then(function (img) {
+ if (image.thumbnail.valid) {
+ var backgroundHeight, backgroundWidth;
+ img.alt = '';
+
+ backgroundHeight = (targetHeight / 2);
+ backgroundWidth = calcWidth - 2.01;
+
+ // Adjust the size because of the margins around pictures
+ backgroundHeight -= 2;
+
+ var croppedDiv = $('<div class="cropped">');
+ croppedDiv.css("background-image", "url('" + img.src + "')");
+ croppedDiv.css("height", backgroundHeight);
+ croppedDiv.css("width", backgroundWidth);
+ a.append(croppedDiv);
+ }
+ });
+ },
+
+ /**
+ * Builds the album representation by placing 1 to 4 images on a grid
+ *
+ * @param {array<GalleryImage>} images
+ * @param {number} targetHeight Each row has a specific height
+ * @param {object} a
+ *
+ * @returns {$.Deferred<array>}
+ * @private
+ */
+ _getFourImages: function (images, targetHeight, a) {
+ var calcWidth = targetHeight / 2;
+ var targetWidth;
+ var imagesCount = images.length;
+ var def = new $.Deferred();
+ var validImages = [];
+ var fail = false;
+ var thumbsArray = [];
+
+ for (var i = 0; i < imagesCount; i++) {
+ targetWidth = calcWidth;
+ if (imagesCount === 2 || (imagesCount === 3 && i === 0)) {
+ targetWidth = calcWidth * 2;
+ }
+ targetWidth = targetWidth.toFixed(3);
+
+ thumbsArray.push(this._getOneImage(images[i], targetHeight, targetWidth, a));
+ }
+
+ var labelWidth = (targetHeight - 0.01);
+ a.find('.album-label').width(labelWidth);
+
+ // This technique allows us to wait for all objects to be resolved before making a
+ // decision
+ $.when.apply($, thumbsArray).done(function () {
+ for (var i = 0; i < imagesCount; i++) {
+ // Collect all valid images, just in case
+ if (images[i].thumbnail.valid) {
+ validImages.push(images[i]);
+ } else {
+ fail = true;
+ }
+ }
+
+ // At least one thumbnail could not be retrieved
+ if (fail) {
+ // Clean up the album
+ a.children().not('.album-label').remove();
+ // Send back the list of images which have thumbnails
+ def.reject(validImages);
+ }
+ });
+
+ return def.promise();
+ },
+
+ /**
+ * Fills the album representation with images we've received
+ *
+ * * Each album includes between 1 and 4 images
+ * * Each album is also a link to open that folder
+ * * An album has a natural size of 200x200 and is comprised of 4 thumbnails which have a
+ * natural size of 200x200 The whole thing gets resized to match the targetHeight
+ *
+ * @param targetHeight
+ * @param a
+ * @private
+ */
+ _fillSubAlbum: function (targetHeight, a) {
+ var album = this;
+
+ if (this.images.length > 1) {
+ this._getFourImages(this.images, targetHeight, a).fail(function (validImages) {
+ album.images = validImages;
+ album._fillSubAlbum(targetHeight, a);
+ });
+ } else if (this.images.length === 1) {
+ this._getOneImage(this.images[0], 2 * targetHeight, targetHeight,
+ a).fail(function () {
+ album.images = [];
+ album._showFolder(targetHeight, a);
+ });
+ } else {
+ this._showFolder(targetHeight, a);
+ }
+ },
+
+ /**
+ * Shows a folder icon in the album since we couldn't get any proper thumbnail
+ *
+ * @param {number} targetHeight
+ * @param a
+ * @private
+ */
+ _showFolder: function (targetHeight, a) {
+ var image = new GalleryImage('Generic folder', 'Generic folder', -1, 'image/png',
+ Gallery.token);
+ var thumb = Thumbnails.getStandardIcon(-1);
+ image.thumbnail = thumb;
+ this.images.push(image);
+ thumb.loadingDeferred.done(function (img) {
+ a.append(img);
+ img.height = (targetHeight - 2);
+ img.width = (targetHeight) - 2;
+ });
+ },
+
+ /**
+ * Preloads the first $count thumbnails
+ *
+ * @param {number} count
+ * @private
+ */
+ _preload: function (count) {
+ var items = this.subAlbums.concat(this.images);
+ var realCounter = 0;
+ var maxThumbs = 0;
+ var fileIds = [];
+ var squareFileIds = [];
+ for (var i = this.preloadOffset; i < this.preloadOffset + count &&
+ i < items.length; i++) {
+ if (items[i].subAlbums) {
+ maxThumbs = 4;
+ var imagesLength = items[i].images.length;
+ if (imagesLength > 0 && imagesLength < 4) {
+ maxThumbs = imagesLength;
+ }
+ var squareFileId = items[i].getThumbnailIds(maxThumbs);
+ squareFileIds = squareFileIds.concat(squareFileId);
+ realCounter = realCounter + maxThumbs;
+ } else {
+ var fileId = items[i].getThumbnailIds();
+ fileIds = fileIds.concat(fileId);
+ realCounter++;
+ }
+ if (realCounter >= count) {
+ i++;
+ break;
+ }
+ }
+
+ this.preloadOffset = i;
+ Thumbnails.loadBatch(fileIds, false);
+ Thumbnails.loadBatch(squareFileIds, true);
+ },
+
+ /**
+ * Creates the album, which will include between 1 and 4 images
+ *
+ * * Each album is also a link to open that folder
+ * * An album has a natural size of 200x200 and is comprised of 4 thumbnails which have a
+ * natural size of 200x200 The whole thing gets resized to match the targetHeight
+ * * Thumbnails are checked first in order to make sure that we have something to show
+ *
+ * @param {number} targetHeight Each row has a specific height
+ *
+ * @return {a} The album to be placed on the row
+ */
+ getDom: function (targetHeight) {
+ var album = this;
+
+ return this._getThumbnail().then(function () {
+ var a = $('<a/>').addClass('album').attr('href',
+ '#' + encodeURIComponent(album.path));
+
+ a.append($('<span/>').addClass('album-label').text(album.name));
+
+ a.width(targetHeight);
+ a.height(targetHeight);
+
+ album._fillSubAlbum(targetHeight, a);
+
+ return a;
+ });
+ },
+
+ /**
+ * Fills the row with albums and images
+ *
+ * @param {number} width
+ * @returns {$.Deferred<Gallery.Row>}
+ */
+ getNextRow: function (width) {
+ var numberOfThumbnailsToPreload = 6;
+
+ /**
+ * Add images to the row until it's full
+ *
+ * @todo The number of images to preload should be a user setting
+ *
+ * @param {Album} album
+ * @param {Row} row
+ * @param {Array<Album|GalleryImage>} images
+ *
+ * @returns {$.Deferred<Gallery.Row>}
+ */
+ var addRowElements = function (album, row, images) {
+ if ((album.viewedItems + 5) > album.preloadOffset) {
+ album._preload(numberOfThumbnailsToPreload);
+ }
+
+ var image = images[album.viewedItems];
+ return row.addElement(image).then(function (more) {
+ album.viewedItems++;
+ if (more && album.viewedItems < images.length) {
+ return addRowElements(album, row, images);
+ }
+ return row;
+ });
+ };
+ var items = this.subAlbums.concat(this.images);
+ var row = new Gallery.Row(width, this.requestId);
+ return addRowElements(this, row, items);
+ },
+
+ /**
+ * Returns IDs of thumbnails belonging to the album
+ *
+ * @param {number} count
+ *
+ * @return number[]
+ */
+ getThumbnailIds: function (count) {
+ var ids = [];
+ var items = this.images.concat(this.subAlbums);
+ for (var i = 0; i < items.length && i < count; i++) {
+ ids = ids.concat(items[i].getThumbnailIds(count));
+ }
+
+ return ids;
+ }
+ };
+
+ window.Album = Album;
+})(jQuery, Gallery);
diff --git a/js/gallerybutton.js b/js/gallerybutton.js
index 3f23f7c8..1ac46650 100644
--- a/js/gallerybutton.js
+++ b/js/gallerybutton.js
@@ -5,6 +5,7 @@ GalleryButton.button = {};
GalleryButton.url = null;
GalleryButton.onFileListUpdated = function () {
+ "use strict";
var fileList;
if (GalleryButton.isPublic) {
@@ -17,18 +18,21 @@ GalleryButton.onFileListUpdated = function () {
};
GalleryButton.buildGalleryUrl = function (dir) {
+ "use strict";
var params = {};
var tokenPath = '';
- var token = ($('#sharingToken').val()) ? $('#sharingToken').val() : false;
+ var sharingTokenElement = $('#sharingToken');
+ var token = (sharingTokenElement.val()) ? sharingTokenElement.val() : false;
if (token) {
params.token = token;
tokenPath = 's/{token}';
}
- GalleryButton.url = OC.generateUrl('apps/galleryplus/' + tokenPath, params) + '#' + encodeURIComponent(dir);
+ GalleryButton.url =
+ OC.generateUrl('apps/galleryplus/' + tokenPath, params) + '#' + encodeURIComponent(dir);
};
$(document).ready(function () {
-
+ "use strict";
if ($('#body-login').length > 0) {
return true; //deactivate on login page
}
diff --git a/js/galleryfileaction.js b/js/galleryfileaction.js
index 9fb5a3ad..3f562b98 100644
--- a/js/galleryfileaction.js
+++ b/js/galleryfileaction.js
@@ -1,5 +1,5 @@
/* global oc_requesttoken, FileList, SlideShow */
-(function (OC, OCA, $, oc_requesttoken) {
+(function ($, OC, OCA, oc_requesttoken) {
"use strict";
var galleryFileAction = {
config: null,
@@ -148,7 +148,7 @@
};
window.galleryFileAction = galleryFileAction;
-}(OC, OCA, jQuery, oc_requesttoken));
+})(jQuery, OC, OCA, oc_requesttoken);
$(document).ready(function () {
"use strict";
diff --git a/js/galleryimage.js b/js/galleryimage.js
new file mode 100644
index 00000000..2df86d9e
--- /dev/null
+++ b/js/galleryimage.js
@@ -0,0 +1,115 @@
+/* global Gallery, Thumbnails */
+(function ($, Gallery) {
+ "use strict";
+ /**
+ * Creates a new image object to store information about a media file
+ *
+ * @param src
+ * @param path
+ * @param fileId
+ * @param mimeType
+ * @param mTime modification time
+ * @param etag
+ * @constructor
+ */
+ var GalleryImage = function (src, path, fileId, mimeType, mTime, etag) {
+ this.src = src;
+ this.path = path;
+ this.fileId = fileId;
+ this.mimeType = mimeType;
+ this.mTime = mTime;
+ this.etag = etag;
+ this.thumbnail = null;
+ this.domDef = null;
+ this.domHeigth = null;
+ };
+
+ GalleryImage.prototype = {
+ /**
+ * Returns the Thumbnail ID
+ *
+ * @returns {[number]}
+ */
+ getThumbnailIds: function () {
+ return [this.fileId];
+ },
+
+ /**
+ * Returns a reference to a loading Thumbnail.image
+ *
+ * @param {bool} square
+ *
+ * @returns {jQuery.Deferred<Thumbnail.image>}
+ */
+ getThumbnail: function (square) {
+ if (this.thumbnail === null) {
+ this.thumbnail = Thumbnails.get(this.fileId, square);
+ }
+ return this.thumbnail.loadingDeferred;
+ },
+
+ /**
+ * Returns the width of a thumbnail
+ *
+ * Used to calculate the width of the row as we add more images to it
+ *
+ * @returns {number}
+ */
+ getThumbnailWidth: function () {
+
+ // img is a Thumbnail.image
+ return this.getThumbnail(false).then(function (img) {
+ if (img) {
+ return img.originalWidth;
+ }
+ return 0;
+ });
+ },
+
+ /**
+ * Creates the a and img element in the DOM
+ *
+ * Each image is also a link to start the full screen slideshow
+ *
+ * @return {a}
+ */
+ getDom: function (targetHeight) {
+ var image = this;
+ if (this.domDef === null || this.domHeigth !== targetHeight) {
+ this.domHeigth = targetHeight;
+ // img is a Thumbnail.image
+ this.domDef = this.getThumbnail(false).then(function (img) {
+ img.height = targetHeight;
+ img.width = targetHeight * img.ratio;
+ img.setAttribute('width', 'auto');
+ img.alt = encodeURI(image.path);
+ var url = '#' + encodeURIComponent(image.path);
+
+ if (!image.thumbnail.valid) {
+ url = Gallery.utility.getPreviewUrl(image.fileId, image.etag);
+ url = url + '&download';
+ }
+ var a = $('<a/>').addClass('image').attr('href', url).attr('data-path',
+ image.path);
+
+ var imageLabel = $('<span/>').addClass('image-label');
+ var imageTitle = $('<span/>').addClass('title').html(
+ OC.basename(image.path));
+ imageLabel.append(imageTitle);
+ a.hover(function () {
+ imageLabel.slideToggle(OC.menuSpeed);
+ }, function () {
+ imageLabel.slideToggle(OC.menuSpeed);
+ });
+ a.append(imageLabel);
+ a.append(img);
+ return a;
+ });
+ }
+ return this.domDef;
+ }
+ };
+
+ window.GalleryImage = GalleryImage;
+})(jQuery, Gallery);
+
diff --git a/js/galleryrow.js b/js/galleryrow.js
new file mode 100644
index 00000000..39251edc
--- /dev/null
+++ b/js/galleryrow.js
@@ -0,0 +1,92 @@
+/* global Gallery, Album */
+(function ($, Gallery) {
+ "use strict";
+ /**
+ * Creates a row
+ *
+ * @param targetWidth
+ * @param requestId
+ * @constructor
+ */
+ var Row = function (targetWidth, requestId) {
+ this.targetWidth = targetWidth;
+ this.items = [];
+ this.width = 8; // 4px margin to start with
+ this.requestId = requestId;
+ };
+
+ Row.prototype = {
+ /**
+ * Calculates if the row is full
+ *
+ * @returns {boolean}
+ * @private
+ */
+ _isFull: function () {
+ return this.width > this.targetWidth;
+ },
+
+ /**
+ * Adds sub-albums and images to the row until it's full
+ *
+ * @param {Album|GalleryImage} element
+ *
+ * @return {jQuery.Deferred<bool>} true if more images can be added to the row
+ */
+ addElement: function (element) {
+ var row = this;
+ var fileNotFoundStatus = 404;
+ var def = new $.Deferred();
+
+ var appendDom = function (width) {
+ row.items.push(element);
+ row.width += width + 4; // add 4px for the margin
+ def.resolve(!row._isFull());
+ };
+
+ // No need to use getThumbnailWidth() for albums, the width is always 200
+ if (element instanceof Album) {
+ var width = 200;
+ appendDom(width);
+ } else {
+ element.getThumbnailWidth().then(function (width) {
+ if (element.thumbnail.status !== fileNotFoundStatus) {
+ appendDom(width);
+ } else {
+ def.resolve(true);
+ }
+ }, function () {
+ def.resolve(true);
+ });
+ }
+
+ return def.promise();
+ },
+
+ getDom: function () {
+ var scaleRatio = (this.width > this.targetWidth) ? this.targetWidth / this.width : 1;
+ var targetHeight = 200 * scaleRatio;
+ targetHeight = targetHeight.toFixed(3);
+ var row = $('<div/>').addClass('row loading');
+ /**
+ * @param row
+ * @param {Gallery.Image[]} items
+ * @param i
+ * @returns {*}
+ */
+ var addImageToDom = function (row, items, i) {
+ return items[i].getDom(targetHeight).then(function (itemDom) {
+ i++;
+ row.append(itemDom);
+ if (i < items.length) {
+ return addImageToDom(row, items, i);
+ }
+ return row;
+ });
+ };
+ return addImageToDom(row, this.items, 0);
+ }
+ };
+
+ Gallery.Row = Row;
+})(jQuery, Gallery);
diff --git a/js/galleryview.js b/js/galleryview.js
index eb616fc0..75b35b6c 100644
--- a/js/galleryview.js
+++ b/js/galleryview.js
@@ -1,5 +1,5 @@
/* global Gallery */
-(function (OC, t, $, _) {
+(function ($, _, OC, t, Gallery) {
"use strict";
/**
* Builds and updates the Gallery view
@@ -280,4 +280,4 @@
};
Gallery.View = View;
-})(OC, t, jQuery, _);
+})(jQuery, _, OC, t, Gallery);
diff --git a/js/thumbnail.js b/js/thumbnail.js
index 19b20491..a711a0a2 100644
--- a/js/thumbnail.js
+++ b/js/thumbnail.js
@@ -18,130 +18,137 @@ function Thumbnail (fileId, square) {
this.status = 200;
}
-var Thumbnails = {};
-Thumbnails.map = {};
-Thumbnails.squareMap = {};
+(function ($, OC, Gallery) {
+ "use strict";
+ var Thumbnails = {
+ map: {},
+ squareMap: {},
-/**
- * Retrieves the thumbnail linked to the given fileID
- *
- * @param {number} fileId
- * @param {bool} square
- *
- * @returns {Thumbnail}
- */
-Thumbnails.get = function (fileId, square) {
- var map = {};
- if (square === true) {
- map = Thumbnails.squareMap;
- square = true;
- } else {
- map = Thumbnails.map;
- square = false;
- }
- if (!map[fileId]) {
- map[fileId] = new Thumbnail(fileId, square);
- }
-
- return map[fileId];
-};
+ /**
+ * Retrieves the thumbnail linked to the given fileID
+ *
+ * @param {number} fileId
+ * @param {bool} square
+ *
+ * @returns {Thumbnail}
+ */
+ get: function (fileId, square) {
+ var map = {};
+ if (square === true) {
+ map = Thumbnails.squareMap;
+ square = true;
+ } else {
+ map = Thumbnails.map;
+ square = false;
+ }
+ if (!map[fileId]) {
+ map[fileId] = new Thumbnail(fileId, square);
+ }
-/**
- * Returns an icon of a specific type
- *
- * -1 is for a folder
- * -404 is for a broken file icon
- * -500 is for a media type icon
- *
- * @param {number} type
- *
- * @returns {Thumbnail}
- */
-Thumbnails.getStandardIcon = function (type) {
- if (!Thumbnails.squareMap[type]) {
- var icon = '';
- // true means square
- var thumb = new Thumbnail(type, true);
- thumb.image = new Image();
- thumb.image.onload = function () {
- thumb.loadingDeferred.resolve(thumb.image);
- };
+ return map[fileId];
+ },
- if (type === -1) {
- icon = 'folder.svg';
- }
- thumb.image.src = OC.imagePath(Gallery.appName, icon);
+ /**
+ * Returns an icon of a specific type
+ *
+ * -1 is for a folder
+ * -404 is for a broken file icon
+ * -500 is for a media type icon
+ *
+ * @param {number} type
+ *
+ * @returns {Thumbnail}
+ */
+ getStandardIcon: function (type) {
+ if (!Thumbnails.squareMap[type]) {
+ var icon = '';
+ // true means square
+ var thumb = new Thumbnail(type, true);
+ thumb.image = new Image();
+ thumb.image.onload = function () {
+ thumb.loadingDeferred.resolve(thumb.image);
+ };
- Thumbnails.squareMap[type] = thumb;
- }
+ if (type === -1) {
+ icon = 'folder.svg';
+ }
+ thumb.image.src = OC.imagePath(Gallery.appName, icon);
- return Thumbnails.squareMap[type];
-};
+ Thumbnails.squareMap[type] = thumb;
+ }
-/**
- * Loads thumbnails in batch, using EventSource
- *
- * @param {array} ids
- * @param {bool} square
- *
- * @returns {{}}
- */
-Thumbnails.loadBatch = function (ids, square) {
- var map = (square) ? Thumbnails.squareMap : Thumbnails.map;
- // Purely here as a precaution
- ids = ids.filter(function (id) {
- return !map[id];
- });
- var batch = {};
- var i, idsLength = ids.length;
- if (idsLength) {
- for (i = 0; i < idsLength; i++) {
- var thumb = new Thumbnail(ids[i], square);
- thumb.image = new Image();
- map[ids[i]] = batch[ids[i]] = thumb;
+ return Thumbnails.squareMap[type];
+ },
- }
- var params = {
- ids: ids.join(';'),
- scale: window.devicePixelRatio,
- square: (square) ? 1 : 0
- };
- var url = Gallery.utility.buildGalleryUrl('thumbnails', '', params);
+ /**
+ * Loads thumbnails in batch, using EventSource
+ *
+ * @param {Array} ids
+ * @param {bool} square
+ *
+ * @returns {{}}
+ */
+ loadBatch: function (ids, square) {
+ var map = (square) ? Thumbnails.squareMap : Thumbnails.map;
+ // Purely here as a precaution
+ ids = ids.filter(function (id) {
+ return !map[id];
+ });
+ var batch = {};
+ var i, idsLength = ids.length;
+ if (idsLength) {
+ for (i = 0; i < idsLength; i++) {
+ var thumb = new Thumbnail(ids[i], square);
+ thumb.image = new Image();
+ map[ids[i]] = batch[ids[i]] = thumb;
- var eventSource = new Gallery.EventSource(url);
- eventSource.listen('preview', function (/**{path, status, mimetype, preview}*/ preview) {
- var id = preview.fileid;
- var thumb = batch[id];
- thumb.status = preview.status;
- if (thumb.status === 404) {
- thumb.valid = false;
- thumb.loadingDeferred.resolve(null);
- } else {
- thumb.image.onload = function () {
- // Fix for SVG files which can come in all sizes
- if (square) {
- thumb.image.width = 200;
- thumb.image.height = 200;
- }
- thumb.image.ratio = thumb.image.width / thumb.image.height;
- thumb.image.originalWidth = 200 * thumb.image.ratio;
- thumb.loadingDeferred.resolve(thumb.image);
- };
- thumb.image.onerror = function () {
- thumb.valid = false;
- thumb.loadingDeferred.resolve(null);
+ }
+ var params = {
+ ids: ids.join(';'),
+ scale: window.devicePixelRatio,
+ square: (square) ? 1 : 0
};
+ var url = Gallery.utility.buildGalleryUrl('thumbnails', '', params);
- if (thumb.status === 200) {
- thumb.image.src = 'data:' + preview.mimetype + ';base64,' + preview.preview;
- } else {
- thumb.valid = false;
- thumb.image.src = Gallery.config.mediaTypes[preview.mimetype];
+ var eventSource = new Gallery.EventSource(url);
+ eventSource.listen('preview',
+ function (/**{path, status, mimetype, preview}*/ preview) {
+ var id = preview.fileid;
+ var thumb = batch[id];
+ thumb.status = preview.status;
+ if (thumb.status === 404) {
+ thumb.valid = false;
+ thumb.loadingDeferred.resolve(null);
+ } else {
+ thumb.image.onload = function () {
+ // Fix for SVG files which can come in all sizes
+ if (square) {
+ thumb.image.width = 200;
+ thumb.image.height = 200;
+ }
+ thumb.image.ratio = thumb.image.width / thumb.image.height;
+ thumb.image.originalWidth = 200 * thumb.image.ratio;
+ thumb.loadingDeferred.resolve(thumb.image);
+ };
+ thumb.image.onerror = function () {
+ thumb.valid = false;
+ thumb.loadingDeferred.resolve(null);
+ };
- }
+ if (thumb.status === 200) {
+ thumb.image.src =
+ 'data:' + preview.mimetype + ';base64,' + preview.preview;
+ } else {
+ thumb.valid = false;
+ thumb.image.src = Gallery.config.mediaTypes[preview.mimetype];
+ }
+ }
+ });
}
- });
- }
- return batch;
-};
+ return batch;
+ }
+ };
+
+ window.Thumbnails = Thumbnails;
+})(jQuery, OC, Gallery);
diff --git a/templates/part.content.php b/templates/part.content.php
index e9ab1926..fe13bb6e 100644
--- a/templates/part.content.php
+++ b/templates/part.content.php
@@ -15,7 +15,9 @@ script(
'galleryinfobox',
'galleryview',
'breadcrumb',
- 'album',
+ 'galleryalbum',
+ 'galleryrow',
+ 'galleryimage',
'thumbnail',
'vendor/eventsource-polyfill/dist/eventsource.min',
'eventsource',
diff --git a/templates/public.php b/templates/public.php
index 15d0d769..a567f75a 100644
--- a/templates/public.php
+++ b/templates/public.php
@@ -15,7 +15,9 @@ script(
'galleryinfobox',
'galleryview',
'breadcrumb',
- 'album',
+ 'galleryalbum',
+ 'galleryrow',
+ 'galleryimage',
'thumbnail',
'vendor/eventsource-polyfill/dist/eventsource.min',
'eventsource',