168 lines
4.6 KiB
CoffeeScript
168 lines
4.6 KiB
CoffeeScript
context = window
|
|
rest = context.JK.Rest()
|
|
logger = context.JK.logger
|
|
|
|
AvatarStore = context.AvatarStore
|
|
|
|
@AvatarUploader = React.createClass({
|
|
|
|
mixins: [
|
|
Reflux.listenTo(@AppStore, "onAppInit"),
|
|
Reflux.listenTo(AvatarStore, "onAvatarUpdate"),
|
|
]
|
|
|
|
onAppInit: (@app) ->
|
|
|
|
onAvatarUpdate: (avatar) ->
|
|
@setState({avatar: avatar})
|
|
|
|
getInitialState: () ->
|
|
{
|
|
avatar: null,
|
|
imageLoadedFpfile: null
|
|
}
|
|
|
|
componentWillMount: () ->
|
|
|
|
|
|
componentDidMount: () ->
|
|
@root = $(@getDOMNode())
|
|
|
|
# get filepicker loaded!
|
|
`(function (a) {
|
|
if (window.filepicker) {
|
|
return
|
|
}
|
|
var b = a.createElement("script");
|
|
b.type = "text/javascript";
|
|
b.async = !0;
|
|
b.src = ("https:" === a.location.protocol ? "https:" : "http:") + "//api.filepicker.io/v1/filepicker.js";
|
|
var c = a.getElementsByTagName("script")[0];
|
|
c.parentNode.insertBefore(b, c);
|
|
var d = {};
|
|
d._queue = [];
|
|
var e = "pick,pickMultiple,pickAndStore,read,write,writeUrl,export,convert,store,storeUrl,remove,stat,setKey,constructWidget,makeDropPane".split(",");
|
|
var f = function (a, b) {
|
|
return function () {
|
|
b.push([a, arguments])
|
|
}
|
|
};
|
|
for (var g = 0; g < e.length; g++) {
|
|
d[e[g]] = f(e[g], d._queue)
|
|
}
|
|
window.filepicker = d
|
|
})(document);`
|
|
|
|
componentDidUpdate: () ->
|
|
#$jcropHolder = @root.find('.jcrop-holder')
|
|
#$spinner = @root.find('.spinner-large')
|
|
# $spinner.width($jcropHolder.width());
|
|
# $spinner.height($jcropHolder.height());
|
|
|
|
startUpdate: (e) ->
|
|
e.preventDefault();
|
|
|
|
AvatarActions.pick()
|
|
|
|
onSelect: (selection) ->
|
|
AvatarActions.select(selection)
|
|
|
|
imageLoaded: (e) ->
|
|
avatar = $(e.target)
|
|
width = avatar.naturalWidth();
|
|
height = avatar.naturalHeight();
|
|
logger.debug("image loaded", avatar, width, height)
|
|
|
|
storedSelection = this.state.avatar?.currentCropSelection
|
|
if storedSelection?
|
|
left = storedSelection.x
|
|
right = storedSelection.x2
|
|
top = storedSelection.y
|
|
bottom = storedSelection.y2
|
|
else
|
|
if width < height
|
|
left = width * .25
|
|
right = width * .75
|
|
top = (height / 2) - (width / 4)
|
|
bottom = (height / 2) + (width / 4)
|
|
else
|
|
top = height * .25
|
|
bottom = height * .75
|
|
left = (width / 2) - (height / 4)
|
|
right = (width / 2) + (height / 4)
|
|
|
|
container = @root.find('.avatar-space')
|
|
|
|
jcrop = avatar.data('Jcrop');
|
|
|
|
if jcrop
|
|
logger.debug("jcrop destroy!")
|
|
jcrop.destroy()
|
|
|
|
@root.find('.jcrop-holder').remove()
|
|
|
|
logger.debug("initial selection box: left: #{left}, top: #{top}, right: #{right}, bottom: #{bottom}")
|
|
avatar.Jcrop({
|
|
aspectRatio: 1,
|
|
boxWidth: container.width() * 1,
|
|
boxHeight: container.height() * 1,
|
|
setSelect: [left, top, right, bottom],
|
|
trueSize: [width, height],
|
|
onSelect: this.onSelect
|
|
});
|
|
|
|
@setState({imageLoadedFpfile: this.state.avatar.currentFpfile})
|
|
|
|
imageLoadError: () ->
|
|
logger.debug("image did not load")
|
|
|
|
|
|
doCancel: (e) ->
|
|
e.preventDefault()
|
|
@app.layout.closeDialog('upload-avatar', true);
|
|
|
|
doDelete: (e) ->
|
|
e.preventDefault()
|
|
AvatarActions.delete()
|
|
|
|
doSave: (e) ->
|
|
AvatarActions.update()
|
|
|
|
render: () ->
|
|
if this.state.avatar?.signedCurrentFpfile?
|
|
fpfile = this.state.avatar.currentFpfile
|
|
signedUrl = this.state.avatar.signedCurrentFpfile
|
|
#console.log("filefile info", fpfile, signedUrl, this.state.imageLoadedFpfile)
|
|
#spinner = `<div className="spinner spinner-large op50"></div>`
|
|
if fpfile.url != this.state.imageLoadedFpfile?.url || this.state.avatar.updatingAvatar || this.state.avatar.pickerOpen
|
|
spinner = `<div className="spinner spinner-large op50"></div>`
|
|
|
|
`<div className="avatar-area">
|
|
<div className="avatar-space image-available">
|
|
<img src={signedUrl} onLoad={this.imageLoaded} onError={this.imageLoadError}/>
|
|
</div>
|
|
{spinner}
|
|
<div className="actions">
|
|
<a className="upload-new" onClick={this.startUpdate}>upload new logo</a>
|
|
<a onClick={this.doCancel} className="button-grey">CANCEL</a>
|
|
<a onClick={this.doDelete} className="button-grey">DELETE</a>
|
|
<a onClick={this.doSave} className="button-orange">SAVE & CLOSE</a>
|
|
|
|
</div>
|
|
</div>`
|
|
|
|
else
|
|
`<div className="avatar-area">
|
|
<div className="avatar-space">
|
|
<div className="no-avatar-space">
|
|
No logo graphic uploaded
|
|
</div>
|
|
|
|
</div>
|
|
<div className="actions">
|
|
<a onClick={this.startUpdate}>upload new logo</a>
|
|
</div>
|
|
|
|
</div>`
|
|
|
|
}) |