js/galleryfileaction.js   A
last analyzed

Complexity

Total Complexity 30
Complexity/F 2.73

Size

Lines of Code 226
Function Count 11

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 114
dl 0
loc 226
rs 10
c 0
b 0
f 0
wmc 30
mnd 19
bc 19
fnc 11
bpm 1.7272
cpm 2.7272
noi 3
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 oc_requesttoken, FileList, Gallery, SlideShow */
13
(function ($, OC, OCA, oc_requesttoken) {
14
	"use strict";
15
	var galleryFileAction = {
16
		features: [],
17
		mediaTypes: {},
18
		scrollContainer: null,
19
		slideShow: null,
20
21
		/**
22
		 * Builds a URL pointing to one of the app's controllers
23
		 *
24
		 * @param {string} endPoint
25
		 * @param {undefined|string} path
26
		 * @param {Object} params
27
		 *
28
		 * @returns {string}
29
		 */
30
		buildGalleryUrl: function (endPoint, path, params) {
31
			var extension = '';
32
			var tokenElement = $('#sharingToken');
33
			var token = (tokenElement.val()) ? tokenElement.val() : false;
34
			if (token) {
35
				params.token = token;
36
				extension = '.public';
37
			}
38
			var query = OC.buildQueryString(params);
39
			return OC.generateUrl('apps/gallery/' + endPoint + extension + path, null) + '?' +
40
				query;
41
		},
42
43
		/**
44
		 * Registers a file action for each media type
45
		 *
46
		 * @param {Array} mediaTypes
47
		 */
48
		register: function (mediaTypes) {
49
			if (OCA.Viewer) {
50
				return;
51
			}
52
			//console.log("enabledPreviewProviders: ", mediaTypes);
53
			if (mediaTypes) {
54
				// Remove SVG if the user is using an insecure browser (IE8-9)
55
				if (window.galleryFileAction.features.indexOf('native_svg') > -1 && !window.btoa) {
56
					mediaTypes.splice(mediaTypes.indexOf('image/svg+xml'), 1);
57
				}
58
				galleryFileAction.mediaTypes = mediaTypes;
59
			}
60
			var i, mediaTypesLength = mediaTypes.length;
61
			// We only want to create slideshows for supported media types
62
			for (i = 0; i < mediaTypesLength; i++) {
63
				// Each click handler gets the same function and images array and
64
				// is responsible to load the slideshow
65
				OCA.Files.fileActions.register(mediaTypes[i], 'View', OC.PERMISSION_READ, '',
66
					galleryFileAction.onView);
67
				OCA.Files.fileActions.setDefault(mediaTypes[i], 'View');
68
			}
69
		},
70
71
		/**
72
		 * Prepares the features array
73
		 *
74
		 * This is duplicated from a method found in galleryconfig. It's done that way in order to
75
		 * avoid having to load the whole utility class in the Files app
76
		 *
77
		 * @param configFeatures
78
		 * @returns {Array}
79
		 */
80
		buildFeaturesList: function (configFeatures) {
81
			var features = [];
82
			var i, configFeaturesLength = configFeatures.length;
83
			if (configFeaturesLength) {
84
				for (i = 0; i < configFeaturesLength; i++) {
85
					features.push(configFeatures[i]);
86
				}
87
			}
88
89
			window.galleryFileAction.features = features;
90
		},
91
92
		/**
93
		 * Builds an array containing all the images we can show in the slideshow
94
		 *
95
		 * @param {string} filename
96
		 * @param {Object} context
97
		 */
98
		onView: function (filename, context) {
99
			var imageUrl, downloadUrl;
100
			var fileList = context.fileList;
101
			var files = fileList.files;
102
			var start = 0;
103
			var images = [];
104
			var dir = context.dir + '/';
105
			var width = Math.ceil(screen.width * window.devicePixelRatio);
0 ignored issues
show
Bug introduced by
The variable screen seems to be never declared. If this is a global, consider adding a /** global: screen */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
106
			var height = Math.ceil(screen.height * window.devicePixelRatio);
107
108
			/* Find value of longest edge. */
109
			var longEdge = Math.max(width, height);
110
111
			/* Find the next larger image size. */
112
			if (longEdge % 100 !== 0) {
113
				longEdge = ( longEdge + 100 ) - ( longEdge % 100 );
114
			}
115
116
			for (var i = 0; i < files.length; i++) {
117
				var file = files[i];
118
				// We only add images to the slideshow if we think we'll be able
119
				// to generate previews for this media type
120
				if (galleryFileAction.mediaTypes.indexOf(file.mimetype) > -1) {
121
					/* jshint camelcase: false */
122
					var params = {
123
						width: longEdge,
124
						height: longEdge,
125
						c: file.etag,
126
						requesttoken: oc_requesttoken
127
					};
128
					imageUrl = galleryFileAction.buildGalleryUrl('preview', '/' + file.id, params);
129
					params = {
130
						c: file.etag,
131
						requesttoken: oc_requesttoken
132
					};
133
					downloadUrl =
134
						galleryFileAction.buildGalleryUrl('files', '/download/' + file.id, params);
135
136
					images.push({
137
						name: file.name,
138
						path: dir + file.name,
139
						fileId: file.id,
140
						mimeType: file.mimetype,
141
						permissions: file.permissions,
142
						url: imageUrl,
143
						downloadUrl: downloadUrl
144
					});
145
				}
146
			}
147
			for (i = 0; i < images.length; i++) {
148
				//console.log("Images in the slideshow : ", images[i]);
149
				if (images[i].name === filename) {
150
					start = i;
151
				}
152
			}
153
154
			if ($.isEmptyObject(galleryFileAction.slideShow)) {
155
				galleryFileAction.slideShow = new SlideShow();
156
				$.when(galleryFileAction.slideShow.init(
157
					false,
158
					null,
159
					window.galleryFileAction.features
160
				)).then(function () {
161
					// Don't show the download button on the "Files" slideshow
162
					galleryFileAction._startSlideshow(images, start);
163
				});
164
			} else {
165
				galleryFileAction._startSlideshow(images, start);
166
			}
167
		},
168
169
		/**
170
		 * Launches the slideshow
171
		 *
172
		 * @param {{name:string, url: string, path: string, fallBack: string}[]} images
173
		 * @param {number} start
174
		 * @private
175
		 */
176
		_startSlideshow: function (images, start) {
177
			galleryFileAction.slideShow.setImages(images, false);
178
179
			var scrollTop = galleryFileAction.scrollContainer.scrollTop();
180
			// This is only called when the slideshow is stopped
181
			galleryFileAction.slideShow.onStop = function () {
182
				FileList.$fileList.one('updated', function () {
183
					galleryFileAction.scrollContainer.scrollTop(scrollTop);
184
				});
185
			};
186
187
			// Only modern browsers can manipulate history
188
			if (history && history.replaceState) {
189
				// This stores the fileslist in the history state
190
				var stateData = {
191
					dir: FileList.getCurrentDirectory()
192
				};
193
				history.replaceState(stateData, document.title, window.location);
194
195
				// This creates a new entry in history for the slideshow. It will
196
				// be updated as the user navigates from picture to picture
197
				history.pushState(null, '', '#loading');
198
			}
199
200
			galleryFileAction.slideShow.show(start);
201
		}
202
	};
203
204
	window.galleryFileAction = galleryFileAction;
205
})(jQuery, OC, OCA, oc_requesttoken);
206
207
$(document).ready(function () {
208
	"use strict";
209
	// Deactivates fileaction on public preview page
210
	if ($('#imgframe').length > 0) {
211
		return true;
212
	}
213
214
	if ($('html').is('.ie8')) {
215
		return true; //deactivate in IE8
216
	}
217
218
	window.galleryFileAction.scrollContainer = $('#app-content');
219
	if ($('#isPublic').val()) {
220
		window.galleryFileAction.scrollContainer = $(window);
221
	}
222
223
	var utility = new Gallery.Utility();
224
	utility.addDomPurifyHooks();
225
226
	// Retrieve the config as well as the list of supported media types.
227
	// The list of media files is retrieved when the user clicks on a row
228
	var url = window.galleryFileAction.buildGalleryUrl('config', '', {extramediatypes: 1});
229
	$.getJSON(url).then(function (config) {
230
		window.galleryFileAction.buildFeaturesList(config.features);
231
		window.galleryFileAction.register(config.mediatypes);
232
	});
233
234
	// create public share links as from the files app
235
	if (!Gallery.appName) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if !Gallery.appName is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
236
		Gallery.appName = 'files';
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
237
	}
238
});
239