(function () { 'use strict'; //controller that handles backpack stuff var controllerId = 'backpackController'; angular.module('app').controller(controllerId, ['common', 'backpackDatacontext', '$upload', 'user', 'config', '$scope', '$modal', '$rootScope', 'myBadgesAdminDataContext', 'fileReader', '$window', backpackController]); function backpackController(common, backpackDatacontext, $upload, user, config, $scope, $modal, $rootScope, myBadgesAdminDataContext, fileReader, $window) { var getLogFn = common.logger.getLogFn; var log = getLogFn(controllerId); var logSuccess = getLogFn(controllerId, "success"); var logWarning = getLogFn(controllerId, "warning"); var vm = this; $scope.dropboxOptions = {}; try { $scope.Dropbox = Dropbox; } catch (err) { $scope.Dropbox = null; } $scope.productTerminology = productTerminology; $scope.badges = []; $scope.orderByPredicate = '-badgeIssuedOn'; $scope.sysUrl = sysUrl; $scope.verifiedUser = $rootScope.verifiedUser; $scope.rightPaneShow = false; $scope.loadingBadgesDone = false; $scope.initial = true; // update badges $rootScope.$on('UpdateDisplay', function () { if ($rootScope.badgeUserConfig) { $scope.badgeUserConfig = $rootScope.badgeUserConfig; $scope.badgeUserConfig.display = "0"; $scope.displayChanged = true; } }); activate(); // activate the controller function activate() { NProgress.done(); log('Activated Badges View'); getBadges(); $rootScope.$broadcast('UpdateDisplay'); } // get badges function getBadges() { $scope.todaysDate = Date.now(); if ($rootScope.initialLogIn) { $scope.loadingBadgesDone = true; $rootScope.initialLogIn = false; } backpackDatacontext.getAllBadgesForUser().then(function (data) { $scope.badges = []; for (var i = 0, il = data.backpackItems.length; i < il; i++) { if (!data.backpackItems[i].deleted && data.backpackItems[i].badgeName) { if (data.backpackItems[i].openBadge.expires) { data.backpackItems[i].openBadge.expires = new Date(data.backpackItems[i].openBadge.expires); } $scope.badges.push(data.backpackItems[i]); } } if ($scope.badges.length == 0) { $scope.noBadges = true; } else { $scope.noBadges = false; } if ($scope.initial) { $scope.loadingBadgesDone = true; $scope.initial = false; } }); } // update badges $rootScope.$on('UpdateBadges', function () { console.log('Fetching badges'); getBadges(); }); // update a badge item $scope.updateBadgeItem = function (badge) { backpackDatacontext.updateBadgeItem(badge).then(function (data) { logSuccess('Badge successfully updated'); getBadges(); }); } // delete a badge item $scope.deleteBadgeItem = function(badge) { backpackDatacontext.deleteBadgeItem(badge.id).then(function (data) { logSuccess('Badge successfully deleted'); getBadges(); }); } // Modal to preview a badge $scope.uploadBadge = function () { $modal.open({ templateUrl: '/app/backpack/uploadbadge.html', controller: uploadBadgeController, size: 'sm', backdrop: 'static', resolve: { getBadges: function () { return getBadges; }, badges: function () { return $scope.badges; } } }); } // Controller for previewing badge template var uploadBadgeController = function (common, $scope, $modalInstance, getBadges, badges) { $scope.badges = badges; $scope.productTerminology = productTerminology; try { $scope.Dropbox = Dropbox; } catch (err) { $scope.Dropbox = null; } $scope.filesReady = []; $scope.erroredFiles = []; $scope.parsedBadges = []; $scope.uploadStarted = false; $scope.dropboxOptions = { // Called when a user selects an item in the Chooser. success: function (files) { $scope.files = files; for (var i = 0, il = files.length; i < il; i++) { var blob = null; var xhr = new XMLHttpRequest(); xhr.open("GET", $scope.files[i].link); xhr.responseType = "blob";//force the HTTP response, response-type header to be blob xhr.onload = function () { blob = xhr.response;//xhr.response is now a blob object var array = []; array.push(blob); $scope.onFileSelect(array, $scope.files[0].name); } xhr.send(); } }, cancel: function () {}, linkType: "direct", // or "direct" multiselect: false, // or true extensions: ['.png', '.jpg', '.gif'], }; // We need to handle multiple files here $scope.onFileSelect = function (files, fileName) { $scope.badgeInList = false; $scope.successfulBadgeUploads = 0; $scope.filesDone = 0; $scope.files = files; var promises = []; if (!$scope.files[0].name) { $scope.files[0].name = fileName; } for (var key = 0;key < files.length; key++) { (function (i) { var reader = new FileReader(); var promise = reader.onload = function (e) { $scope.$apply(function () { $scope.filesDone = $scope.filesDone + 1; // get loaded data and render preview. setImageData($scope.files[i], e.target.result); }); }; reader.readAsDataURL($scope.files[i]); promises.push(promise); })(key); } } // Grab the files from the function in the drop directive $scope.addFiles = function (files) { $scope.onFileSelect(files); } function setImageData(file, result) { //Does this file already exist in the que? for (var i = 0, il = $scope.filesReady.length; i < il; i++) { if ($scope.filesReady[i].name == file.name && $scope.filesReady[i].size == file.size) { $scope.badgeInList = true; return; } } // check if file meets the size requirements if (file.size > 2097152) { $scope.erroredFiles.push({ preview: result, name: file.name, size: file.size, originalFile: file, progress: 0, uploaded: false, error: 'Woahh, this seems way to big to be an openbadge' }); // check if the file is in fact an image file } else if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif' || file.type === 'image/tiff') { $scope.erroredFiles.push({ preview: result, name: file.name, size: file.size, originalFile: file, progress: 0, uploaded: false, error: 'Woahh, this does not look like an image file' }); } else { // if the file has a name then i know it has come from a local source if (file.name) { $scope.filesReady.push({ preview: result, name: file.name, size: file.size, originalFile: file, progress: 0, uploaded: false }); // if the file has no name then it has been returned by dropbox } else { $scope.filesReady.push({ preview: result, name: 'DropBox', size: file.size, originalFile: file, progress: 0, uploaded: false }); } } } // start the upload process when user hits upload $scope.startUpload = function () { $scope.badgeInList = false; $scope.uploadStarted = true; // start off all uploads for (var i = 0, il = $scope.filesReady.length; i < il; i++) { uploadImage($scope.filesReady[i].originalFile, $scope.filesReady[i].originalFile, UploadSuccess, UploadProgress, UploadError, cloudinaryUploadPath, i); }; } //upload graphic to cloudinary function uploadImage(obj, file, success, progress, error, uploadPath, index) { var data = { upload_preset: cloudinaryUploadPreset, tags: 'mybadges' }; //images are uploaded to Cloudinary $upload.upload({ url: cloudinaryApiBaseUrl + cloudinaryName + uploadPath, data: { upload_preset: cloudinaryUploadPreset, tags: 'mybadges', context: 'photo=' + 'badge', file: file } }).progress(function (e) { var percent = Math.round((e.loaded * 100.0) / e.total); return progress(percent, index); }).success(function (data, status, headers, config) { return success(obj, data, index); }).error(function (data) { return error(); }); } //called when a badge is uploaded function UploadSuccess(files, data, index) { data.url = data.url.replace(/^http:\/\//i, 'https://'); //openbadges - we need to get metadata from the png file to work out if it is a badge and if so what is the badge data (which is oddly stored in the png file itself) fileReader.readAsText(files, $scope) .then(function (result) { //Get all email addresses for this user in an array // create a new badge item object $scope.item = {}; // get the badge data backpackDatacontext.parseOpenbadge(result, $rootScope.verifiedEmails, files) .then(function (parsedBadge) { if (parsedBadge === 'This badge was not issued to you') { $scope.imagePreview = null; $scope.invalidBadgeInBatch = true; $scope.filesReady[index].error = 'It appears this badge was not issued to you'; $scope.erroredFiles.push($scope.filesReady[index]); return; } else if (!parsedBadge || typeof parsedBadge !== 'object') { //its not a valid badge file so tell the user $scope.item.validBadgeFile = false; $scope.invalidBadgeInBatch = true; $scope.filesReady[index].error = 'Sorry, this is not a valid open badge'; $scope.erroredFiles.push($scope.filesReady[index]); return; } for (var i = 0, il = $scope.badges.length; i < il; i++) { if (parsedBadge.openBadge.issuedDate == $scope.badges[i].badgeIssuedOn && parsedBadge.badgeTemplate.name == $scope.badges[i].badgeName) { $scope.item.validBadgeFile = false; $scope.invalidBadgeInBatch = true; $scope.filesReady[index].error = 'Sorry, this badge already exists in your account'; $scope.erroredFiles.push($scope.filesReady[index]); return; } } //it is a valid badge so get all the badge data and add to the item so it can be saved with the item $scope.item.validBadgeFile = true; $scope.badBadgeFile = false; $scope.item.badgeData = JSON.stringify(parsedBadge); //template data if (parsedBadge.badgeTemplate != null) { $scope.item.badgeName = parsedBadge.badgeTemplate.name; $scope.item.BadgeDescription = parsedBadge.badgeTemplate.description; $scope.item.BadgeCustomData = parsedBadge.openBadge.customData; } if (parsedBadge.openBadge != null) { $scope.item.openBadgeId = parsedBadge.openBadge.id; } //graphic data if (parsedBadge.badgeGraphic != null) { $scope.item.badgeImageUrl = parsedBadge.badgeGraphic.url; } //criteria data if (parsedBadge.badgeCriteria != null) { $scope.item.BadgeCriteria = parsedBadge.badgeCriteria.url; $scope.item.BadgeCriteriaText = parsedBadge.badgeCriteria.value; $scope.item.BadgeCriteriaType = parsedBadge.badgeCriteria.type; } //issuer data if (parsedBadge.badgeIssuer != null) { $scope.item.BadgeIssuerName = parsedBadge.badgeIssuer.name; $scope.item.BadgeIssuerDescription = parsedBadge.badgeIssuer.description; $scope.item.BadgeIssuerOrigin = parsedBadge.badgeIssuer.url; $scope.item.BadgeIssuerLogo = parsedBadge.badgeIssuer.logoUrl; } $scope.item.badgeIssuedOn = parsedBadge.openBadge.issuedDate; $scope.item.BadgeAwardedTo = parsedBadge.openBadge.awardedToEmail; $scope.item.BadgeUnhashedEmail = parsedBadge.openBadge.unhashedEmail; $scope.validBadgeInBatch = true; $scope.successfulBadgeUploads = $scope.successfulBadgeUploads + 1; $scope.backpackItem = { backpackId: $scope.badgeUserConfig.backpack.id, backpackItems: [$scope.item] }; backpackDatacontext.createBadgeItem($scope.backpackItem).then(function (data) { $scope.filesReady[index].uploaded = true; getBadges(); // called when all files have been uploaded and parsed if (index === $scope.filesReady.length - 1 && $scope.validBadgeInBatch) { $scope.uploadComplete = true; // upload is complete so let's update the users badge list } }); }); }); } // Generate the image upload process percentage function UploadProgress(percentComplete, index) { $scope.filesReady[index].progress = percentComplete; } // throw an error if there was a problem uploading image function UploadError() { logWarning('There was an issue uploading your badges... Please try again.'); } // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } // Modal to preview a badge $scope.previewBadge = function (badge) { $modal.open({ templateUrl: '/app/backpack/previewbadge.html', controller: previewBadgeController, size: 'lg', backdrop: 'static', resolve: { badge: function () { return badge; } } }); } // Controller for previewing badge template var previewBadgeController = function (common, $scope, $modalInstance, badge) { $scope.badge = badge; $scope.sysUrl = sysUrl; // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } // Modal to add comments a badge $scope.addComments = function (badge) { $modal.open({ templateUrl: '/app/backpack/comments.html', controller: addCommentsController, size: 'sm', backdrop: 'static', resolve: { badge: function () { return badge; } } }); } // Controller for adding comments to a badge var addCommentsController = function (common, $scope, $modalInstance, badge) { $scope.badge = badge; $scope.tempComment = angular.copy($scope.badge.comment); $scope.save = function () { $scope.badge.comment = $scope.tempComment; backpackDatacontext.updateBadgeItem($scope.badge).then(function (data) { logSuccess('Comment saved successfully'); $modalInstance.dismiss('cancel'); }); } // close the modal $scope.cancel = function () { $scope.badge = badge; $modalInstance.dismiss('cancel'); }; } // Modal to add comments a badge $scope.viewEvidence = function (badge) { $modal.open({ templateUrl: '/app/backpack/evidence.html', controller: viewEvidenceController, size: 'sm', backdrop: 'static', resolve: { badge: function () { return badge; } } }); } // Controller for adding comments to a badge var viewEvidenceController = function (common, $scope, $modalInstance, badge) { $scope.badge = badge; $scope.viewEvidenceFile = function (id) { myBadgesAdminDataContext.getEvidence(id).then(function (data) { if (data.fileUri) { $window.open(data.fileUri); } }); }; // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } // Modal to add comments a badge $scope.shareBadge = function (badge) { $modal.open({ templateUrl: '/app/backpack/sharebadge.html', controller: shareBadgeController, size: 'sm', backdrop: 'static', resolve: { badge: function () { return badge; } } }); } // Controller for adding comments to a badge var shareBadgeController = function (common, $scope, $modalInstance, badge) { $scope.badge = badge; $scope.sysUrl = sysUrl; $scope.mybadgesRootUrl = mybadgesRootUrl; $scope.host = $window.location.host; $scope.embedUrl = ''; $scope.embedImageUrl = '' + '' + badge.badgeName + '' + ''; // close the modal $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; } } })();