(function(context,$) { "use strict"; context.JK = context.JK || {}; context.JK.BandSetupPhotoScreen = function(app) { var self = this; var logger = context.JK.logger; var rest = context.JK.Rest(); var bandId; var band = {}; var tmpUploadPath = null; var bandDetail = null; var bandPhoto; var selection = null; var targetCropSize = 88; var largeCropSize = 200; var updatingBandPhoto = false; function beforeShow(data) { bandId = data.id; } function afterShow(data) { resetForm(); renderBandPhotoScreen() } function resetForm() { // remove all display errors $('#band-setup-photo-content-scroller form .error-text').remove() $('#band-setup-photo-content-scroller form .error').removeClass("error") } function populateBandPhoto(bandDetail) { self.bandDetail = bandDetail; rest.getBandPhotoFilepickerPolicy({ id:bandId }) .done(function(filepicker_policy) { var template= context.JK.fillTemplate($('#template-band-setup-photo').html(), { "fp_apikey" : gon.fp_apikey, "data-fp-store-path" : createStorePath(bandDetail) + createOriginalFilename(bandDetail), "fp_policy" : filepicker_policy.policy, "fp_signature" : filepicker_policy.signature }); $('#band-setup-photo-content-scroller').html(template); var currentFpfile = determineCurrentFpfile(); var currentCropSelection = determineCurrentSelection(bandDetail); renderBandPhoto(currentFpfile, currentCropSelection ? JSON.parse(currentCropSelection) : null); }) .error(app.ajaxError); } // events for main screen function events() { // wire up main panel clicks $('#band-setup-photo-content-scroller').on('click', '#band-setup-photo-upload', function(evt) { evt.stopPropagation(); handleFilePick(); return false; } ); $('#band-setup-photo-content-scroller').on('click', '#band-setup-photo-delete', function(evt) { evt.stopPropagation(); handleDeleteBandPhoto(); return false; } ); $('#band-setup-photo-content-scroller').on('click', '#band-setup-photo-cancel', function(evt) { evt.stopPropagation(); navToEditProfile(); return false; } ); $('#band-setup-photo-content-scroller').on('click', '#band-setup-photo-submit', function(evt) { evt.stopPropagation(); handleUpdateBandPhoto(); return false; } ); //$('#band-setup-photo-content-scroller').on('change', 'input[type=filepicker-dragdrop]', function(evt) { evt.stopPropagation(); afterImageUpload(evt.originalEvent.fpfile); return false; } ); } function handleDeleteBandPhoto() { if(self.updatingBandPhoto) { // protect against concurrent update attempts return; } self.updatingBandPhoto = true; renderBandPhotoSpinner(); rest.deleteBandPhoto({ id: bandId }) .done(function() { removeBandPhotoSpinner({ delete:true }); deleteBandPhotoSuccess(arguments); selection = null; }) .fail(function() { app.ajaxError(arguments); $.cookie('original_fpfile_band_photo', null); self.updatingBandPhoto = false; }) .always(function() { }) } function deleteBandPhotoSuccess(response) { renderBandPhoto(null, null); rest.getBand(bandId) .done(function(bandDetail) { self.bandDetail = bandDetail; }) .error(app.ajaxError) .always(function() { self.updatingBandPhoto = false; }) } function handleFilePick() { rest.getBandPhotoFilepickerPolicy({ id: bandId }) .done(function(filepickerPolicy) { renderBandPhotoSpinner(); logger.debug("rendered spinner"); filepicker.setKey(gon.fp_apikey); filepicker.pickAndStore({ mimetype: 'image/*', maxSize: 10000*1024, policy: filepickerPolicy.policy, signature: filepickerPolicy.signature }, { path: createStorePath(self.bandDetail), access: 'public' }, function(fpfiles) { removeBandPhotoSpinner(); afterImageUpload(fpfiles[0]); }, function(fperror) { removeBandPhotoSpinner(); if(fperror.code != 101) { // 101 just means the user closed the dialog alert("unable to upload file: " + JSON.stringify(fperror)) } }) }) .fail(app.ajaxError); } function renderBandPhotoScreen() { rest.getBand(bandId) .done(populateBandPhoto) .error(app.ajaxError) } function navToEditProfile() { resetForm(); context.location = '/client#/band/setup/' + bandId; } function renderBandPhotoSpinner() { var bandPhotoSpace = $('#band-setup-photo-content-scroller .band-setup-photo .avatar-space'); // if there is already an image tag, we only obscure it. var bandPhoto = $('img.preview_profile_avatar', bandPhotoSpace); var spinner = $('
') if(bandPhoto.length === 0) { bandPhotoSpace.prepend(spinner); } else { // in this case, just style the spinner to obscure using opacity, and center it var jcropHolder = $('.jcrop-holder', bandPhotoSpace); spinner.width(jcropHolder.width()); spinner.height(jcropHolder.height()); spinner.addClass('op50'); var jcrop = bandPhoto.data('Jcrop'); if(jcrop) { jcrop.disable(); } bandPhotoSpace.append(spinner); } } function removeBandPhotoSpinner(options) { var bandPhotoSpace = $('#band-setup-photo-content-scroller .band-setup-photo .avatar-space'); if(options && options.delete) { bandPhotoSpace.children().remove(); } var spinner = $('.spinner-large', bandPhotoSpace); spinner.remove(); var bandPhoto = $('img.preview_profile_avatar', bandPhotoSpace); var jcrop = bandPhoto.data('Jcrop') if(jcrop) { jcrop.enable(); } } function renderBandPhoto(fpfile, storedSelection) { // clear out var bandPhotoSpace = $('#band-setup-photo-content-scroller .band-setup-photo .avatar-space'); if(!fpfile) { renderNoBandPhoto(bandPhotoSpace); } else { rest.getBandPhotoFilepickerPolicy({handle: fpfile.url, id: bandId}) .done(function(filepickerPolicy) { bandPhotoSpace.children().remove(); renderBandPhotoSpinner(); var photo_url = fpfile.url + '?signature=' + filepickerPolicy.signature + '&policy=' + filepickerPolicy.policy; bandPhoto = new Image(); $(bandPhoto) .load(function(e) { removeBandPhotoSpinner(); bandPhoto = $(this); bandPhotoSpace.append(bandPhoto); var width = bandPhoto.naturalWidth(); var height = bandPhoto.naturalHeight(); if(storedSelection) { var left = storedSelection.x; var right = storedSelection.x2; var top = storedSelection.y; var bottom = storedSelection.y2; } else { if(width < height) { var left = width * .25; var right = width * .75; var top = (height / 2) - (width / 4); var bottom = (height / 2) + (width / 4); } else { var top = height * .25; var bottom = height * .75; var left = (width / 2) - (height / 4); var right = (width / 2) + (height / 4); } } // jcrop only works well with px values (not percentages) // so we get container, and work out a decent % ourselves var container = $('#band-setup-photo-content-scroller'); bandPhoto.Jcrop({ aspectRatio: 1, boxWidth: container.width() * .75, boxHeight: container.height() * .75, // minSelect: [targetCropSize, targetCropSize], unnecessary with scaling involved setSelect: [ left, top, right, bottom ], trueSize: [width, height], onRelease: onSelectRelease, onSelect: onSelect, onChange: onChange }); }) .error(function() { // default to no avatar look of UI renderNoBandPhoto(bandPhotoSpace); }) .attr('src', photo_url) .attr('alt', 'profile avatar') .addClass('preview_profile_avatar'); }) .fail(app.ajaxError); } } function afterImageUpload(fpfile) { $.cookie('original_fpfile_band_photo', JSON.stringify(fpfile)); renderBandPhoto(fpfile, null); } function renderNoBandPhoto(bandPhotoSpace) { // no photo found for band removeBandPhotoSpinner(); var noAvatarSpace = $(''); noAvatarSpace.addClass('no-avatar-space'); noAvatarSpace.text('Please upload a photo'); bandPhotoSpace.append(noAvatarSpace); } function handleUpdateBandPhoto(event) { if(self.updatingBandPhoto) { // protect against concurrent update attempts return; } if(selection) { var currentSelection = selection; self.updatingBandPhoto = true; renderBandPhotoSpinner(); logger.debug("Converting..."); // we convert two times; first we crop to the selected region, // then we scale to 88x88 (targetCropSize X targetCropSize), which is the largest size we use throughout the site. var fpfile = determineCurrentFpfile(); rest.getBandPhotoFilepickerPolicy({ handle: fpfile.url, convert: true, id: bandId }) .done(function(filepickerPolicy) { filepicker.setKey(gon.fp_apikey); filepicker.convert(fpfile, { crop: [ Math.round(currentSelection.x), Math.round(currentSelection.y), Math.round(currentSelection.w), Math.round(currentSelection.w)], fit: 'crop', format: 'jpg', quality: 90, policy: filepickerPolicy.policy, signature: filepickerPolicy.signature }, { path: createStorePath(self.bandDetail) + 'cropped-' + new Date().getTime() + '.jpg', access: 'public' }, function(cropped) { logger.debug("converting cropped"); rest.getBandPhotoFilepickerPolicy({handle: cropped.url, convert: true, id: bandId}) .done(function(filepickerPolicy) { filepicker.convert(cropped, { height: targetCropSize, width: targetCropSize, fit: 'scale', format: 'jpg', quality: 75, policy: filepickerPolicy.policy, signature: filepickerPolicy.signature }, { path: createStorePath(self.bandDetail), access: 'public' }, function(scaled) { filepicker.convert(cropped, { height: largeCropSize, width: largeCropSize, fit: 'scale', format: 'jpg', quality: 75, policy: filepickerPolicy.policy, signature: filepickerPolicy.signature }, { path: createStorePath(self.bandDetail) + 'large.jpg', access: 'public' }, function(scaledLarger) { logger.debug("converted and scaled final image %o", scaled); rest.updateBandPhoto({ original_fpfile: determineCurrentFpfile(), cropped_fpfile: scaled, cropped_large_fpfile: scaledLarger, crop_selection: currentSelection, id: bandId }) .done(updateBandPhotoSuccess) .fail(app.ajaxError) .always(function() { removeBandPhotoSpinner(); self.updatingBandPhoto = false;}) }, function(fperror) { alert("unable to scale larger selection. error code: " + fperror.code); removeBandPhotoSpinner(); self.updatingBandPhoto = false; }) }, function(fperror) { alert("unable to scale selection. error code: " + fperror.code); removeBandPhotoSpinner(); self.updatingBandPhoto = false; }) }) .fail(app.ajaxError); }, function(fperror) { alert("unable to crop selection. error code: " + fperror.code); removeBandPhotoSpinner(); self.updatingBandPhoto = false; } ); }) .fail(app.ajaxError); } else { app.notify( { title: "Upload a Band Photo First", text: "To update your band photo, first you must upload an image using the UPLOAD button" }, null, true); } } function updateBandPhotoSuccess(response) { $.cookie('original_fpfile_band_photo', null); self.bandDetail = response; app.notify( { title: "Band Photo Changed", text: "You have updated your band photo successfully." }, null, true); } function onSelectRelease(event) { } function onSelect(event) { selection = event; } function onChange(event) { } function createStorePath(bandDetail) { return gon.fp_upload_dir + '/' + bandDetail.id + '/' } function createOriginalFilename(bandDetail) { // get the s3 var fpfile = bandDetail.original_fpfile_photo ? JSON.parse(bandDetail.original_fpfile_photo) : null; return 'original_band_photo.jpg' } // retrieves a file that has not yet been used as an band photo (uploaded, but not cropped) function getWorkingFpfile() { return JSON.parse($.cookie('original_fpfile_band_photo')) } function determineCurrentFpfile() { // precedence is as follows: // * tempOriginal: if set, then the user is working on a new upload // * storedOriginal: if set, then the user has previously uploaded and cropped a band photo // * null: neither are set above var tempOriginal = getWorkingFpfile(); var storedOriginal = self.bandDetail.original_fpfile_photo ? JSON.parse(self.bandDetail.original_fpfile_photo) : null; return tempOriginal ? tempOriginal : storedOriginal; } function determineCurrentSelection(bandDetail) { // if the cookie is set, don't use the storage selection, just default to null return $.cookie('original_fpfile_band_photo') == null ? bandDetail.crop_selection_photo : null; } function initialize() { var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow }; app.bindScreen('band/setup/photo', screenBindings); events(); } this.initialize = initialize; this.beforeShow = beforeShow; this.afterShow = afterShow; return this; }; })(window,jQuery);