/** * This model is used by admin/analyse_album.blade.php, to analyse all images. * @constructor */ function AnalyseAlbumViewModel() { this.el = '#analyse-album'; this.data = { imagesFailed: [], imagesToAnalyse: [], imagesInProgress: [], imagesRecentlyCompleted: [], numberSuccessful: 0, numberFailed: 0 }; this.computed = { failedPercentage: function () { var result = 0; if (this.numberTotal > 0) { result = (this.numberFailed / this.numberTotal) * 100; } return result.toFixed(2) + '%'; }, isCompleted: function () { return this.numberTotal > 0 && (this.numberSuccessful + this.numberFailed >= this.numberTotal); }, latestCompletedImages: function() { return this.imagesRecentlyCompleted.slice( (this.imagesRecentlyCompleted.length - 3 < 0 ? 0 : this.imagesRecentlyCompleted.length - 3) , 3); }, numberTotal: function () { return this.imagesToAnalyse.length; }, successfulPercentage: function () { var result = 0; if (this.numberTotal > 0) { result = (this.numberSuccessful / this.numberTotal) * 100; } return result.toFixed(2) + '%'; } }; this.methods = { // This method is called when an image is added to the array, automatically issue it for analysis // item is an instance of AnalyseImageViewModel analyseImage: function (item) { var self = this; this.imagesToAnalyse.push(item); $.ajax( item.url, { beforeSend: function() { self.imagesInProgress.push(item); }, dataType: 'json', error: function (xhr, textStatus, errorThrown) { self.numberFailed++; self.imagesFailed.push({ 'name': item.name, 'reason': textStatus }); item.isSuccessful = false; item.isPending = false; }, method: 'POST', success: function (data) { if (data.is_successful) { self.numberSuccessful++; item.isSuccessful = true; item.isPending = false; // Push into our "recently completed" array self.imagesRecentlyCompleted.push(item); var indexToRemove = self.imagesInProgress.indexOf(item); if (indexToRemove > -1) { self.imagesInProgress.splice(indexToRemove, 1); } // Remove it again after a few seconds /*window.setTimeout(function() { var indexToRemove = self.imagesRecentlyCompleted.indexOf(item); if (indexToRemove > -1) { self.imagesRecentlyCompleted.splice(indexToRemove, 1); } }, 2000);*/ } else { self.numberFailed++; self.imagesFailed.push({ 'name': item.name, 'reason': data.message }); item.isSuccessful = false; item.isPending = false; } } } ); } }; } /** * This model is used by admin/analyse_album.blade.php, as a sub-model of AnalyseAlbumViewModel. * @param image_info Array of information about the image * @constructor */ function AnalyseImageViewModel(image_info) { this.isPending = true; this.isSuccessful = false; this.name = image_info.name; this.photoID = image_info.photo_id; this.url = image_info.url; } /** * This model is used by admin/show_album.blade.php to handle photo uploads. * @param album_id ID of the album the photos are being uploaded to * @param queue_token Unique token of the upload queue to save the photos to * @param language Array containing language strings * @param urls Array containing URLs * @constructor */ function UploadPhotosViewModel(album_id, queue_token, language, urls) { this.el = '#upload-tab'; this.data = { currentStatus: '', imagesFailed: 0, imagesTotal: 0, imagesUploaded: 0, isBulkUploadInProgress: false, isUploadInProgress: false, statusMessages: [] }; this.computed = { failedPercentage: function () { var result = 0; if (this.imagesTotal > 0) { result = (this.imagesFailed / this.imagesTotal) * 100; } return result.toFixed(2) + '%'; }, successfulPercentage: function () { var result = 0; if (this.imagesTotal > 0) { result = (this.imagesUploaded / this.imagesTotal) * 100; } return result.toFixed(2) + '%'; } }; this.methods = { // This method is called when an image is uploaded - regardless if it fails or not onUploadCompleted: function () { this.currentStatus = language.upload_status .replace(':current', (this.imagesUploaded + this.imagesFailed)) .replace(':total', this.imagesTotal); if ((this.imagesFailed + this.imagesUploaded) >= this.imagesTotal) { this.isUploadInProgress = false; if (this.imagesFailed === 0 && this.imagesUploaded > 0) { window.location = urls.analyse; } } }, // This method is called when an uploaded image fails onUploadFailed: function (data, file_name) { this.imagesFailed++; this.statusMessages.push({ 'message_class': 'text-danger', 'message_text': language.image_failed.replace(':file_name', file_name) }); this.onUploadCompleted(); }, // This method is called when an uploaded image succeeds onUploadSuccessful: function (data, file_name) { if (data.is_successful) { this.imagesUploaded++; // Don't add to statusMessages() array so user only sees errors /*self.statusMessages.push({ 'message_class': 'text-success', 'message_text': language.image_uploaded.replace(':file_name', file_name) });*/ this.onUploadCompleted(); } else { this.onUploadFailed(data, file_name); } }, uploadFile: function uploadImageFile(formObject, imageFile) { var self = this; var formData = new FormData(); formData.append('album_id', album_id); formData.append('queue_token', queue_token); formData.append('photo[]', imageFile, imageFile.name); $.ajax( { contentType: false, data: formData, error: function (data) { self.onUploadFailed(data, imageFile.name); }, method: $(formObject).attr('method'), processData: false, success: function (data) { self.onUploadSuccessful(data, imageFile.name); }, url: $(formObject).attr('action') } ); this.isUploadInProgress = true; this.currentStatus = language.upload_status .replace(':current', 0) .replace(':total', this.imagesTotal); }, uploadIndividualFiles: function(event) { var fileSelect = $('input[type=file]', event.target); // Get the selected files var files = fileSelect[0].files; // Reset statistics this.currentStatus = ''; this.statusMessages = []; this.imagesUploaded = 0; this.imagesFailed = 0; this.imagesTotal = files.length; this.isUploadInProgress = true; // Loop through each of the selected files and upload them individually for (var i = 0; i < files.length; i++) { var file = files[i]; // We're only interested in image files if (!file.type.match('image.*')) { alert(language.not_an_image_file.replace(':file_name', file.name)); this.onUploadFailed(null, file.name); continue; } // Upload the file this.uploadFile(event.target, file); } // Prevent standard form upload event.preventDefault(); return false; } }; }