// Responsible for an invidiual thumbnail. This view is intended to remain
// fairly dumb - let AssetLibraryView handle events.
slices.AssetThumbView = Backbone.View.extend({
tagName: 'li',
className: 'asset-library-item',
happyTime: 1000,
template: Handlebars.compile(
'
' +
'{{displayName}}' +
'
' +
'- {{name}}
' +
'- {{size}}
' +
'- Added {{createdAt}}
' +
'- Edit
' +
'
'
),
events: {
'mousedown' : 'press',
'mouseup' : 'release',
'mousedown [data-action="edit"]' : 'pressEdit',
'click [data-action="edit"]' : 'releaseEdit'
},
initialize: function() {
_.bindAll(this);
this.$el.append('');
this.model.bind('change', this.whenModelChanges);
this.model.bind('destroying', this.whenModelIsDestroying);
},
render: function() {
this.$el.find('.asset-details').html(this.template(this));
return this;
},
src: function() {
return this.model.get('asset_url')
|| '<%= asset_path 'slices/icon_generic_file.png' %>';
},
name: function() {
return this.model.get('name');
},
url: function() {
return this.model.url();
},
displayName: function() {
if (!this.model.isImage()) return this.name();
},
createdAt: function() {
return moment(this.model.get('created_at')).calendar();
},
size: function() {
return humanFileSize(this.model.get('file_file_size'));
},
select: function() {
$(this.el).addClass('selected');
},
deselect: function() {
$(this.el).removeClass('selected');
},
selected: function() {
return $(this.el).hasClass('selected');
},
remove: function() {
this.unbind();
$(this.el).remove();
},
press: function(event) {
if (!this.options.selectable) return;
if (event.which !== 1) return;
event.preventDefault();
event.stopImmediatePropagation();
this.trigger('thumb:press', event, this);
},
release: function(event) {
if (!this.options.selectable) return;
if (event.which !== 1) return;
this.trigger('thumb:release', event, this);
},
pressEdit: function(e) {
e.stopImmediatePropagation();
},
releaseEdit: function(e) {
e.preventDefault();
e.stopImmediatePropagation();
this.trigger('thumb:blur');
var el = $(this.el);
el.addClass('editing');
var editor = slices.AssetEditorView.openModal({ model: this.model });
editor.bind('close', function() {
_.delay(function() { el.removeClass('editing') }, 350);
});
},
whenModelChanges: function() {
this.render();
},
whenModelIsDestroying: function() {
$(this.el).addClass('destroying');
},
// Update the upload progress information, wrapped around the file.
updateFile: function(attrs) {
if (!this.fileView) this.makeFileView();
$(this.el).
removeClass(this.fileView.possibleStatusList).
addClass('status-' + this.fileView.model.status());
},
// Update the upload progress information so we see happy face, then
// wait for the thumbnail to load or happyTime, whichever is longer.
updateFileAndComplete: function(file) {
this.updateFile(file);
this.gracefullyRemoveFileView();
},
// Make fileview, this gets done on the fly.
makeFileView: function() {
this.fileView = new slices.FileView({
model: this.model.get('file')
});
this.$el.append(this.fileView.el);
$(this.fileView.el).css({ position: 'absolute', top: 0 });
},
// Remove fileview
removeFileView: function() {
if (this.fileView) {
this.fileView.remove();
delete this.fileView;
}
},
// Wait for thumnail to load and happyTime to pass, then complete the
// transition to showing our lovely new thumbnail.
gracefullyRemoveFileView: function() {
$.when(
this.thumbnailHasLoaded(),
this.happyTimeHasPassed()
).then(this.resolveGracefully);
},
// Complete transition by fading out fileView, rendering, then
// fading our thumbnail in.
resolveGracefully: function() {
this.$('.asset-details').css({ opacity: 0 });
$(this.fileView.el).animate({ opacity: 0 }, 'fast', _.bind(function() {
this.removeFileView();
this.$('.asset-details').animate({ opacity: 1 });
}, this));
},
// Returns a deferred promise wrapping thumbnail pre-load.
thumbnailHasLoaded: function() {
var dfd = new $.Deferred();
this.$('img').load(dfd.resolve);
return dfd.promise();
},
// Returns a deferred promise wrapping happyTime.
happyTimeHasPassed: function() {
var dfd = new $.Deferred();
_.delay(dfd.resolve, this.happyTime);
return dfd.promise();
}
});