332 lines
9.9 KiB
CoffeeScript
332 lines
9.9 KiB
CoffeeScript
$ = jQuery
|
|
context = window
|
|
logger = context.JK.logger
|
|
rest = new context.JK.Rest()
|
|
|
|
@AvatarStore = Reflux.createStore(
|
|
{
|
|
|
|
listenables: @AvatarActions
|
|
selection: null
|
|
updatingAvatar: false
|
|
targetCropSize: 88
|
|
largerCropSize: 200
|
|
currentFpfile: null
|
|
signedCurrentFpfile: null
|
|
|
|
init: ->
|
|
this.listenTo(context.AppStore, this.onAppInit)
|
|
|
|
onAppInit: (@app) ->
|
|
|
|
onStart: (target, type) ->
|
|
logger.debug("AvatarStore start", target.id, type)
|
|
@target = target
|
|
@type = type
|
|
|
|
@selection = null
|
|
@updatingAvatar = false
|
|
|
|
@currentFpfile = @determineCurrentFpfile();
|
|
@currentCropSelection = @determineCurrentSelection(@target);
|
|
@signedCurrentFpFile = null
|
|
@changed()
|
|
@signFpfile()
|
|
|
|
@app.layout.showDialog('upload-avatar')
|
|
|
|
onSelect: (selection) ->
|
|
@selection = select
|
|
@changed()
|
|
|
|
onPick: () ->
|
|
|
|
if @type == 'school'
|
|
genpolicy = rest.generateSchoolFilePickerPolicy({id: @target.id})
|
|
else if @type == 'retailer'
|
|
genpolicy = rest.generateRetailerFilePickerPolicy({id: @target.id})
|
|
|
|
genpolicy.done((filepickerPolicy) =>
|
|
@pickerOpen = true
|
|
@changed()
|
|
window.filepicker.setKey(gon.fp_apikey);
|
|
window.filepicker.pickAndStore({
|
|
mimetype: 'image/*',
|
|
maxSize: 10000*1024,
|
|
policy: filepickerPolicy.policy,
|
|
signature: filepickerPolicy.signature
|
|
}, { path: @createStorePath(@target), access: 'public' },
|
|
(fpfiles) => (
|
|
@pickerOpen = false
|
|
@afterImageUpload(fpfiles[0]);
|
|
),
|
|
(fperror) => (
|
|
@pickerOpen = false
|
|
@changed()
|
|
|
|
if fperror.code != 101 # 101 just means the user closed the dialog
|
|
alert("unable to upload file: " + JSON.stringify(fperror))
|
|
|
|
)
|
|
)
|
|
)
|
|
.fail(@app.ajaxError)
|
|
|
|
afterImageUpload: (fpfile) ->
|
|
logger.debug("afterImageUploaded", typeof fpfile, fpfile)
|
|
$.cookie('original_fpfile', JSON.stringify(fpfile));
|
|
|
|
@currentFpfile = fpfile
|
|
@signedCurrentFpfile = null
|
|
@currentCropSelection = null
|
|
@changed()
|
|
@signFpfile()
|
|
|
|
signFpfile: () ->
|
|
if @type == 'school'
|
|
genpolicy = rest.generateSchoolFilePickerPolicy({id: @target.id})
|
|
else if @type == 'retailer'
|
|
genpolicy = rest.generateRetailerFilePickerPolicy({id: @target.id})
|
|
|
|
genpolicy.done((policy) => (
|
|
@signedCurrentFpfile = @currentFpfile.url + '?signature=' + policy.signature + '&policy=' + policy.policy;
|
|
@changed()
|
|
))
|
|
|
|
getState: () ->
|
|
{
|
|
target: @target,
|
|
type: @type,
|
|
selection: @selection,
|
|
updatingAvatar: @updatingAvatar,
|
|
currentFpfile: @currentFpfile,
|
|
currentCropSelection: @currentCropSelection,
|
|
signedCurrentFpfile: @signedCurrentFpfile
|
|
}
|
|
|
|
changed: () ->
|
|
state = @getState()
|
|
logger.debug("change: ", state)
|
|
@trigger(state)
|
|
|
|
onSelect: (event) ->
|
|
@selection = event;
|
|
|
|
|
|
delete: () ->
|
|
|
|
update: () ->
|
|
|
|
getPolicy: () ->
|
|
|
|
|
|
updateAvatarSuccess: (response) ->
|
|
$.cookie('original_fpfile', null)
|
|
|
|
@target = response
|
|
|
|
# notify any listeners that the avatar changed
|
|
# userDropdown.loadMe();
|
|
# $('.avatar_large img').trigger('avatar_changed', [self.userDetail.photo_url]);
|
|
# $(document).triggerHandler(EVENTS.USER_UPDATED, response);
|
|
@app.notify({ title: "Logo Updated", text: "You have updated your avatar successfully." }, null, true);
|
|
|
|
if @type == 'school'
|
|
window.SchoolActions.refresh()
|
|
if @type == 'retailer'
|
|
window.RetailerActions.refresh()
|
|
|
|
@app.layout.closeDialog('upload-avatar')
|
|
|
|
|
|
# retrieves a file that has not yet been used as an avatar (uploaded, but not cropped)
|
|
getWorkingFpfile: () ->
|
|
return JSON.parse($.cookie('original_fpfile'))
|
|
|
|
|
|
createStorePath: (target) ->
|
|
gon.fp_upload_dir + '/' + @type + '/' + target.id + '/'
|
|
|
|
|
|
createOriginalFilename: (target) ->
|
|
# get the s3
|
|
if target.original_fpfile
|
|
fpfile = JSON.parse(target.original_fpfile)
|
|
else
|
|
fpfile = null
|
|
return 'original_avatar.jpg'
|
|
|
|
|
|
|
|
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 an avatar
|
|
# * null: neither are set above
|
|
|
|
tempOriginal = @getWorkingFpfile()
|
|
if @target.original_fpfile
|
|
storedOriginal = JSON.parse(@target.original_fpfile)
|
|
else
|
|
storedOriginal = null
|
|
|
|
if tempOriginal
|
|
tempOriginal
|
|
else
|
|
storedOriginal
|
|
|
|
determineCurrentSelection: (target) ->
|
|
# if the cookie is set, don't use the storage selection, just default to null
|
|
if $.cookie('original_fpfile') == null
|
|
result = target.crop_selection
|
|
else
|
|
result = null
|
|
|
|
if result?
|
|
JSON.parse(result)
|
|
else
|
|
null
|
|
|
|
onDelete: () ->
|
|
if @updatingAvatar
|
|
return
|
|
|
|
@updatingAvatar = true
|
|
@changed()
|
|
|
|
if @type == 'school'
|
|
rest.deleteSchoolAvatar({id: @target.id}).done((response) => @deleteDone(response)).fail((jqXHR) => @deleteFail(jqXHR))
|
|
else if @type == 'retailer'
|
|
rest.deleteRetailerAvatar({id: @target.id}).done((response) => @deleteDone(response)).fail((jqXHR) => @deleteFail(jqXHR))
|
|
|
|
deleteDone: (response) ->
|
|
@currentFpfile = null
|
|
@signedCurrentFpfile = null
|
|
@updatingAvatar = false
|
|
@selection = null
|
|
@currentCropSelection = null
|
|
if @type == 'school'
|
|
window.SchoolActions.refresh()
|
|
else if @type == 'retailer'
|
|
window.RetailerActions.refresh()
|
|
|
|
@app.layout.closeDialog('upload-avatar');
|
|
|
|
@changed()
|
|
|
|
deleteFail: (jqXHR) ->
|
|
$.cookie('original_fpfile', null)
|
|
@currentFpfile = null
|
|
@signedCurrentFpfile = null
|
|
@selection = null
|
|
@updatingAvatar = false
|
|
@currentCropSelection = null
|
|
@changed()
|
|
@app.ajaxError(jqXHR)
|
|
onUpdate: () ->
|
|
if @updatingAvatar
|
|
return
|
|
|
|
if @selection?
|
|
@updatingAvatar = true
|
|
@changed()
|
|
currentSelection = @selection
|
|
logger.debug("Converting...");
|
|
fpfile = @determineCurrentFpfile();
|
|
|
|
if @type == 'school'
|
|
genpolicy = rest.generateSchoolFilePickerPolicy({ id: @target.id, handle: fpfile.url, convert: true })
|
|
else if @type == 'retailer'
|
|
genpolicy = rest.generateRetailerFilePickerPolicy({ id: @target.id, handle: fpfile.url, convert: true })
|
|
|
|
genpolicy.done((filepickerPolicy) =>
|
|
window.filepicker.setKey(gon.fp_apikey)
|
|
window.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(@target) + 'cropped-' + new Date().getTime() + '.jpg', access: 'public' },
|
|
(cropped) => (@scale(cropped))
|
|
)
|
|
)
|
|
else
|
|
@app.notify( { title: "Upload an Avatar First", text: "To update your avatar, first you must upload an image using the UPLOAD button"}, null, true);
|
|
|
|
scale: (cropped) ->
|
|
logger.debug("converting cropped");
|
|
|
|
if @type == 'school'
|
|
genpolicy = rest.generateSchoolFilePickerPolicy({id: @target.id, handle: cropped.url, convert: true})
|
|
else if @type == 'retailer'
|
|
genpolicy = rest.generateRetailerFilePickerPolicy({id: @target.id, handle: cropped.url, convert: true})
|
|
|
|
genpolicy.done((filepickerPolicy) => (
|
|
window.filepicker.convert(cropped, {
|
|
height: @targetCropSize,
|
|
width: @targetCropSize,
|
|
fit: 'scale',
|
|
format: 'jpg',
|
|
quality: 75,
|
|
policy: filepickerPolicy.policy,
|
|
signature: filepickerPolicy.signature
|
|
}, { path: @createStorePath(@target), access: 'public' },
|
|
(scaled) => (@scaledLarger(scaled, cropped, filepickerPolicy)),
|
|
(fperror) => (@handleFpError(fperror)))
|
|
))
|
|
.fail(@app.ajaxError)
|
|
|
|
scaledLarger: (scaled, cropped, filepickerPolicy) ->
|
|
window.filepicker.convert(cropped, {
|
|
height: @largerCropSize,
|
|
width: @largerCropSize,
|
|
fit: 'scale',
|
|
format: 'jpg',
|
|
quality: 75,
|
|
policy: filepickerPolicy.policy,
|
|
signature: filepickerPolicy.signature
|
|
}, { path: @createStorePath(@target) + 'large.jpg', access: 'public' },
|
|
(scaledLarger) => (@updateServer(scaledLarger, scaled, cropped)),
|
|
(fperror) => (@handleFpError(fperror))
|
|
)
|
|
|
|
updateServer: (scaledLarger, scaled, cropped) ->
|
|
logger.debug("converted and scaled final image %o", scaled);
|
|
if @type == 'school'
|
|
update = rest.updateSchoolAvatar({
|
|
id: @target.id,
|
|
original_fpfile: @determineCurrentFpfile(),
|
|
cropped_fpfile: scaled,
|
|
cropped_large_fpfile: scaledLarger,
|
|
crop_selection: @selection
|
|
})
|
|
else if @type == 'retailer'
|
|
update = rest.updateRetailerAvatar({
|
|
id: @target.id,
|
|
original_fpfile: @determineCurrentFpfile(),
|
|
cropped_fpfile: scaled,
|
|
cropped_large_fpfile: scaledLarger,
|
|
crop_selection: @selection
|
|
})
|
|
|
|
update.done((response) => @updateAvatarSuccess(response))
|
|
.fail(@app.ajaxError)
|
|
.always(() => (
|
|
@updatingAvatar = false
|
|
@changed()
|
|
))
|
|
|
|
handleFpError: (fperror) ->
|
|
alert("unable to scale larger selection. error code: " + fperror.code);
|
|
@updatingAvatar = false;
|
|
@changed()
|
|
|
|
}
|
|
)
|