jam-cloud/web/app/assets/javascripts/react-components/stores/AvatarStore.js.coffee

333 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) ->
console.log("afterImageUploaded", typeof fpfile, 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()
}
)