jam-cloud/web/app/assets/javascripts/band_setup_photo.js

447 lines
20 KiB
JavaScript

(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 = $('<div class="spinner spinner-large"></div>')
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 = $('<div></div>');
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);