43:1ba0ab25df12
Anton Shestakov <av6@dwimlabs.net>, Wed, 25 Jul 2018 17:10:37 +0800
docs: list supported formats and links to various collections of music files

previous change 37:a8a87d02cf00

ui.js

Permissions: -rw-r--r--

Other formats: Feeds:
rivets.adapters[':'] = {
observe: function(obj, keypath, callback) {
obj.on('change:' + keypath, callback);
},
unobserve: function(obj, keypath, callback) {
obj.off('change:' + keypath, callback);
},
get: function(obj, keypath) {
return obj.get(keypath);
},
set: function(obj, keypath, value) {
obj.set(keypath, value);
}
};
rivets.formatters.time = function(ms) {
if (isNaN(ms)) {
return '0:00';
}
var s = Math.round(ms / 1000);
var m = Math.floor(s / 60);
s = s % 60;
if (s < 10) {
s = '0' + s;
}
return m + ':' + s;
};
rivets.formatters.percent = function(value, total) {
var ratio = value / total;
if (isNaN(ratio) || !isFinite(ratio)) {
return null;
} else {
return Math.min(ratio, 1.0) * 100 + '%';
}
};
rivets.formatters.is = function(a, b) {
return a === b;
};
rivets.binders.width = function(el, value) {
el.style.width = value;
};
var Track = Backbone.Model.extend({
defaults: {
song: '<no file loaded>'
}
});
var Tracks = Backbone.Collection.extend({
model: Track
});
var FrontView = Backbone.View.extend({
initialize: function() {
this.rivet = rivets.bind(this.el, {player: this.model, front: this});
this.listenTo(this.model, 'ended', this.advance);
this.listenTo(this.model, 'change:random', this.makeOrder);
this.listenTo(this.model.tracks, 'reset', this.makeOrder);
},
remove: function() {
this.rivet.unbind();
Backbone.View.prototype.remove.apply(this);
},
advance: function() {
if (this.model.tracks.length === 1) {
this.model.seek(0);
}
this.fastForward(null, {player: this.model, front: this});
},
makeOrder: function() {
if (this.model.get('random')) {
var trackNumber = this.model.get('track').get('id') || 0;
var shuffled = _.shuffle(_.range(this.model.tracks.length));
this.order = [trackNumber].concat(_(shuffled).without(trackNumber));
} else {
this.order = _.range(this.model.tracks.length);
}
},
fastBackward: function(event, context) {
var trackNumber = context.player.get('track').get('id') || 0;
var oi = context.front.order.indexOf(trackNumber) - 1;
if (oi < 0 && context.player.get('repeat')) {
oi = context.player.tracks.length - 1;
}
if (oi >= 0 && oi < context.player.tracks.length) {
context.player.startTrack(context.front.order[oi]);
context.player.play();
}
},
fastForward: function(event, context) {
var trackNumber = context.player.get('track').get('id') || 0;
var oi = context.front.order.indexOf(trackNumber) + 1;
if (oi >= context.player.tracks.length && context.player.get('repeat')) {
oi = 0;
}
if (oi >= 0 && oi < context.player.tracks.length) {
context.player.startTrack(context.front.order[oi]);
context.player.play();
}
},
play: function(event, context) {
context.player.play();
},
pause: function(event, context) {
context.player.stop();
},
stop: function(event, context) {
context.player.seek(0);
context.player.stop();
},
toggleAutoplay: function(event, context) {
context.player.set('autoplay', !context.player.get('autoplay'));
},
toggleRepeat: function(event, context) {
context.player.set('repeat', !context.player.get('repeat'));
},
toggleRandom: function(event, context) {
context.player.set('random', !context.player.get('random'));
}
});
var TrackView = Backbone.View.extend({
templateEl: $($.trim($('#track-template').html())),
initialize: function() {
var $el = this.templateEl.clone();
this.setElement($el);
this.rivet = rivets.bind(this.el, {track: this.model, view: this});
},
remove: function() {
this.rivet.unbind();
Backbone.View.prototype.remove.apply(this);
},
play: function(event, context) {
window.player.startTrack(context.track.get('id'));
window.player.play();
}
});
var TrackListView = Backbone.View.extend({
initialize: function() {
this.listenTo(this.collection, 'reset', this.render);
},
render: function(collection, options) {
_(options.previousModels).each(function(model) {
model.view.remove();
});
this.$el.empty();
this.addAll();
return this;
},
addOne: function(track) {
track.view = new TrackView({model: track});
this.$el.append(track.view.el);
},
addAll: function() {
this.collection.each(this.addOne, this);
}
});