function AnalyseAlbumViewModel() { var self = this; self.imagesFailed = ko.observableArray(); self.imagesToAnalyse = ko.observableArray(); self.numberSuccessful = ko.observable(0); self.numberFailed = ko.observable(0); self.numberTotal = ko.computed(function() { return self.imagesToAnalyse().length; }); self.failedPercentage = ko.computed(function() { return ((self.numberFailed() / self.numberTotal()) * 100).toFixed(2) + '%'; }); self.successfulPercentage = ko.computed(function() { return ((self.numberSuccessful() / self.numberTotal()) * 100).toFixed(2) + '%'; }); self.isCompleted = ko.computed(function() { return self.numberTotal() > 0 && (self.numberSuccessful() + self.numberFailed() >= self.numberTotal()); }); // When an image is added to the array, automatically issue it for analysis self.imagesToAnalyse.subscribe(function(changes) { // changes[0].value is an instance of AnalyseImageViewModel var item = changes[0].value; $.ajax( item.url(), { dataType: 'json', error: function (xhr, textStatus, errorThrown) { self.numberFailed(self.numberFailed() + 1); 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(self.numberSuccessful() + 1); item.isSuccessful(true); item.isPending(false); } else { self.numberFailed(self.numberFailed() + 1); self.imagesFailed.push({ 'name': item.name(), 'reason': data.message }); item.isSuccessful(false); item.isPending(false); } } } ); }, null, 'arrayChange'); } function AnalyseImageViewModel(image_info) { var self = this; self.isPending = ko.observable(true); self.isSuccessful = ko.observable(false); self.name = ko.observable(image_info.name); self.photoID = ko.observable(image_info.photo_id); self.url = ko.observable(image_info.url); self.iconClass = ko.computed(function() { var string = 'fa fa-fw '; if (!self.isPending()) { string += (self.isSuccessful() ? 'check text-success' : 'times text-danger') } return string; }); } function StorageLocationsViewModel() { var self = this; self.selectedLocation = ko.observable(true); } /** * This file 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 language Array containing language strings * @param urls Array containing URLs * @constructor */ function UploadPhotosViewModel(album_id, language, urls) { var self = this; self.currentStatus = ko.observable(''); self.imagesFailed = ko.observable(0); self.imagesUploaded = ko.observable(0); self.imagesTotal = ko.observable(0); self.isBulkUploadInProgress = ko.observable(false); self.isUploadInProgress = ko.observable(false); self.statusMessages = ko.observableArray(); self.failedPercentage = ko.computed(function() { return ((self.imagesFailed() / self.imagesTotal()) * 100).toFixed(2) + '%'; }); // This method is called when an image is uploaded - regardless if it fails or not self.onUploadCompleted = function() { self.currentStatus(language.upload_status .replace(':current', (self.imagesUploaded() + self.imagesFailed())) .replace(':total', self.imagesTotal())); if ((self.imagesFailed() + self.imagesUploaded()) >= self.imagesTotal()) { self.isUploadInProgress(false); if (self.imagesFailed() == 0 && self.imagesUploaded() > 0) { window.location = urls.analyse; } } }; // This method is called when an uploaded image fails self.onUploadFailed = function(data, file_name) { self.imagesFailed(self.imagesFailed() + 1); self.statusMessages.push({ 'message_class': 'text-danger', 'message_text': language.image_failed.replace(':file_name', file_name) }); self.onUploadCompleted(); }; // This method is called when an uploaded image succeeds self.onUploadSuccessful = function(data, file_name) { if (data.is_successful) { self.imagesUploaded(self.imagesUploaded() + 1); // 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) });*/ self.onUploadCompleted(); } else { self.onUploadFailed(data, file_name); } }; self.startUpload = function(number_images) { self.currentStatus(''); self.statusMessages.removeAll(); self.imagesUploaded(0); self.imagesFailed(0); self.imagesTotal(number_images); self.isUploadInProgress(true); }; self.successfulPercentage = ko.computed(function() { return ((self.imagesUploaded() / self.imagesTotal()) * 100).toFixed(2) + '%'; }); self.uploadFile = function uploadImageFile(formObject, imageFile) { var formData = new FormData(); formData.append('album_id', album_id); 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') } ); viewModel.isUploadInProgress(true); }; }