// Generated by CoffeeScript 1.12.7
/**
* Volume files
* @module
*/
'use strict';
var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
slice = [].slice,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
app.controller('volume/slot', [
'$scope', '$location', '$sce', '$timeout', 'constantService', 'modelService', 'displayService', 'messageService', 'tooltipService', 'styleService', 'storageService', 'Offset', 'Segment', 'uploadService', 'routerService', 'slot', 'edit', function($scope, $location, $sce, $timeout, constants, models, display, messages, tooltips, styles, storage, Offset, Segment, uploads, router, slot, editing) {
var $flow, Asset, Comment, Excerpt, Record, Tag, TagName, TimeBar, TimePoint, TimeSegment, asset, assetId, autoplay, blank, byId, byPosition, comment, done, ev, finite, fn, fullRange, getSelection, playerDropHeightStyle, playerHeight, playerImgHeightStyle, playerMinHeight, playerPDFHeightStyle, playerVideoHeightStyle, playrange, records, ref, ref1, resetRange, ruler, searchLocation, seekOffset, setPlayerHeight, stayDirty, tag, tagId, tagToggle, target, unchoose, updatePlayerHeight, updateRange, updateSelection, video, videoEvents, viewportMinHeight;
display.title = slot.displayName;
$scope.flowOptions = uploads.flowOptions();
$scope.slot = slot;
$scope.volume = slot.volume;
$scope.editing = editing;
$scope.form = {};
$scope.authorized = models.Login.isAuthorized();
$flow = $scope.$flow;
console.log(slot);
/**
* Represents a point on the timeline, which can be expressed as "o" (offset time in ms), "x" (pixel X position in client coordinates), or "p" (fractional position on the timeline, may escape [0,1])
* @interface slot/TimePoint
*/
TimePoint = (function() {
var tl;
function TimePoint(v, t) {
var x;
if (v instanceof TimePoint) {
for (t in v) {
x = v[t];
if (t.startsWith('_')) {
this[t] = x;
}
}
} else {
this['_' + (t != null ? t : 'o')] = v;
}
}
tl = document.getElementById('slot-timeline');
Object.defineProperties(TimePoint.prototype, {
o: {
get: function() {
var p;
if ('_o' in this) {
return this._o;
} else {
p = this.p;
return this._o = Math.round(ruler.range.l + p * (ruler.range.u - ruler.range.l));
}
},
set: function(o) {
if (o === this._o) {
return;
}
this._o = o;
delete this._p;
delete this._x;
}
},
p: {
get: function() {
var o, tlr, x;
if ('_p' in this) {
return this._p;
} else if ('_o' in this) {
o = this._o;
return this._p = (o - ruler.range.base) / (ruler.range.u - ruler.range.l);
} else if ('_x' in this) {
x = this._x;
tlr = tl.getBoundingClientRect();
return this._p = (x - tlr.left) / tlr.width;
}
},
set: function(p) {
if (p === this._p) {
return;
}
this._p = p;
delete this._o;
delete this._x;
}
},
x: {
get: function() {
var p, tlr;
if ('_x' in this) {
return this._x;
} else {
p = this.p;
tlr = tl.getBoundingClientRect();
return this._x = tlr.left + p * tlr.width;
}
},
set: function(x) {
if (x === this._x) {
return;
}
this._x = x;
delete this._o;
delete this._p;
}
}
});
TimePoint.prototype.reset = function() {
if ('_o' in this) {
delete this._p;
delete this._x;
} else if ('_x' in this) {
delete this._p;
}
};
TimePoint.prototype.clip = function() {
var p;
p = this.p;
if (p > 1) {
this.p = 2e308;
}
if (p < 0) {
this.p = -2e308;
}
return this;
};
TimePoint.prototype.defined = function() {
return isFinite(this.o);
};
TimePoint.prototype.minus = function(t) {
var r;
r = new TimePoint();
if ('_o' in this) {
r.o = this._o - t.o;
}
if ('_p' in this) {
r.p = this._p - t.p;
}
if ('_x' in this) {
r.x = this._x - t.x;
}
return r;
};
TimePoint.prototype.seek = function() {
var o;
if (isFinite(o = this.o)) {
seekOffset(o);
if (!(ruler.selection.contains(o) || ruler.selection.u === o)) {
ruler.selection = new TimeSegment(null);
updateSelection();
}
}
};
TimePoint.prototype.style = function() {
var p, style;
style = {};
p = this.p;
if (p >= 0 && p <= 1) {
style.left = 100 * p + '%';
}
return style;
};
return TimePoint;
})();
/**
* Elaboration on Segment that uses lt and ut TimePoints
* @interface slot/TimeSegment
*/
TimeSegment = (function(superClass) {
extend(TimeSegment, superClass);
function TimeSegment() {
return TimeSegment.__super__.constructor.apply(this, arguments);
}
TimeSegment.prototype.init = function(a, u) {
if (arguments.length >= 2) {
this.lt = new TimePoint(a);
return this.ut = new TimePoint(u);
} else if (a instanceof TimeSegment) {
this.lt = new TimePoint(a.lt);
return this.ut = new TimePoint(a.ut);
} else if (a instanceof TimePoint) {
this.lt = new TimePoint(a);
return this.ut = new TimePoint(a);
} else {
this.lt = new TimePoint();
this.ut = new TimePoint();
return TimeSegment.__super__.init.apply(this, arguments);
}
};
Object.defineProperties(TimeSegment.prototype, {
l: {
get: function() {
return this.lt.o;
},
set: function(o) {
this.lt.o = o;
}
},
u: {
get: function() {
return this.ut.o;
},
set: function(o) {
this.ut.o = o;
}
},
size: {
get: function() {
return this.ut.minus(this.lt);
}
}
});
TimeSegment.prototype.contains = function(t) {
if (t instanceof TimePoint) {
t = t.o;
}
return TimeSegment.__super__.contains.call(this, t);
};
TimeSegment.prototype.reset = function() {
this.lt.reset();
return this.ut.reset();
};
TimeSegment.prototype.style = function() {
var l, r, style;
style = {};
l = this.lt.p;
r = this.ut.p;
if (l < 0) {
style.left = '0px';
style['border-top-left-radius'] = '0px';
style['border-bottom-left-radius'] = '0px';
if (r < 0) {
style.border = '#f26363 3px solid';
} else {
style['border-left'] = '0px';
}
} else if (l < 1) {
style.left = 100 * l + '%';
}
if (r > 1) {
style.right = '0px';
style['border-top-right-radius'] = '0px';
style['border-bottom-right-radius'] = '0px';
if (l > 1) {
style.border = '#f26363 3px solid';
} else {
style['border-right'] = '0px';
}
} else if (r > 0) {
style.right = 100 * (1 - r) + '%';
}
return style;
};
TimeSegment.prototype.select = function(event) {
if (typeof $scope.editing === 'string') {
return false;
}
ruler.selection = new TimeSegment(this.full || !ruler.range.overlaps(this) ? null : this);
if (isFinite(this.l) && !this.contains(ruler.position)) {
seekOffset(this.l);
} else if (this.full) {
seekOffset(void 0);
}
updateSelection();
return event != null ? event.stopPropagation() : void 0;
};
return TimeSegment;
})(Segment);
/**
* Set the global state
* @interface slot/searchLocation
*/
target = $location.search();
video = void 0;
blank = void 0;
fullRange = new Segment(0, 0);
ruler = $scope.ruler = {
range: 'range' in target ? new Segment(target.range) : fullRange,
selection: new TimeSegment('select' in target ? target.select : null),
position: new TimePoint(Offset.parse(target.pos)),
zoomed: 'range' in target
};
playrange = void 0;
searchLocation = function(url) {
var ref, ref1;
return url.search('asset', void 0).search('record', void 0).search(((ref = $scope.current) != null ? ref.type : void 0) || '', (ref1 = $scope.current) != null ? ref1.id : void 0).search('select', !ruler.selection.empty ? ruler.selection.format() : void 0).search('range', ruler.zoomed ? ruler.range.format() : void 0);
};
$scope.toggleEdit = function() {
return searchLocation($location.url(editing ? slot.route() : slot.editRoute()));
};
byId = function(a, b) {
return a.id - b.id;
};
byPosition = function(a, b) {
return a.l - b.l;
};
finite = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return args.find(isFinite);
};
resetRange = function() {
var c, j, k, len, len1, ref, t;
ref = [$scope.assets, records, $scope.tags];
for (j = 0, len = ref.length; j < len; j++) {
c = ref[j];
for (k = 0, len1 = c.length; k < len1; k++) {
t = c[k];
t.reset();
}
}
ruler.selection.reset();
};
updateRange = function() {
var c, j, k, l, len, len1, ref, t, u;
l = 2e308;
u = -2e308;
ref = [$scope.assets, records];
for (j = 0, len = ref.length; j < len; j++) {
c = ref[j];
for (k = 0, len1 = c.length; k < len1; k++) {
t = c[k];
if (isFinite(t.l)) {
if (t.l < l) {
l = t.l;
}
if (t.l > u) {
u = t.l;
}
}
if (isFinite(t.u)) {
if (t.u < l) {
l = t.u;
}
if (t.u > u) {
u = t.u;
}
}
}
}
fullRange.l = finite(slot.segment.l, l, 0);
fullRange.u = finite(slot.segment.u, u, 0);
resetRange();
};
/**
* Video/playback controls
* @interface slot/updatePosition
*/
$scope.updatePosition = function() {
var ref, seg;
seg = ($scope.editing === 'asset' ? $scope.current : (ref = $scope.asset) != null ? ref.segment : void 0);
if (seg && video && seg.contains(ruler.position.o) && seg.lBounded) {
video[0].currentTime = (ruler.position.o - seg.l) / 1000;
}
};
seekOffset = function(o) {
ruler.position.o = Math.round(o);
$scope.updatePosition();
};
$scope.play = function() {
if (video) {
video[0].play();
} else {
$scope.playing = 1;
}
};
$scope.pause = function() {
if (video) {
video[0].pause();
} else {
$scope.playing = 0;
}
};
videoEvents = {
pause: function() {
$scope.playing = 0;
},
playing: function() {
$scope.playing = 1;
},
ratechange: function() {
$scope.playing = video[0].playbackRate;
},
timeupdate: function() {
var o;
if ($scope.asset && isFinite($scope.asset.segment.l)) {
o = Math.round(1000 * video[0].currentTime);
if ($scope.editing === 'asset' && $scope.asset === $scope.current.asset) {
$scope.current.setPosition(ruler.position.o - o);
} else {
ruler.position.o = $scope.asset.segment.l + o;
if ((playrange != null ? playrange.uBounded : void 0) && ruler.position.o >= playrange.u) {
video[0].pause();
seekOffset(playrange.l);
}
}
}
},
ended: function() {
var a, i, j, len, p, ref;
$scope.playing = 0;
if (!($scope.asset && isFinite(p = $scope.asset.segment.u))) {
return;
}
ref = $scope.assets;
for (j = 0, len = ref.length; j < len; j++) {
i = ref[j];
if (!(i.asset && i.asset.duration && !i.asset.pending && i.asset.checkPermission(constants.permission.VIEW) && i.lBounded && i.ut.o > p)) {
continue;
}
a = i;
break;
}
if (!a) {
return;
}
a.choose(true);
}
};
for (ev in videoEvents) {
fn = videoEvents[ev];
videoEvents[ev] = $scope.$lift(fn);
}
autoplay = void 0;
this.deregisterVideo = function(v) {
if (video !== v) {
return;
}
video = void 0;
v.off(videoEvents);
};
this.registerVideo = function(v) {
if (video) {
this.deregisterVideo(video);
}
video = v;
seekOffset(ruler.position.o);
v.on(videoEvents);
if (autoplay) {
autoplay = false;
video[0].play();
}
};
/**
* Video player display
* @interface slot/setPlayerHeight
*/
playerMinHeight = 200;
viewportMinHeight = 120;
playerHeight = parseInt(storage.getString('player-height'), 10) || 400;
if (!(playerHeight >= playerMinHeight)) {
playerHeight = playerMinHeight;
}
playerImgHeightStyle = void 0;
playerVideoHeightStyle = void 0;
playerDropHeightStyle = void 0;
playerPDFHeightStyle = void 0;
updatePlayerHeight = function() {
$timeout(function() {
var d, player, viewer;
player = document.getElementById('player-scroll');
if (!player) {
return;
}
viewer = document.getElementById('player-viewport');
d = player.offsetTop + playerHeight - viewer.offsetTop - 10;
if (d < viewportMinHeight) {
d = viewportMinHeight;
}
playerImgHeightStyle = styles.set('.player-viewport .asset-display img{max-height:' + d + 'px}', playerImgHeightStyle);
playerVideoHeightStyle = styles.set('.player-viewport .asset-display video{height:' + d + 'px}', playerVideoHeightStyle);
playerDropHeightStyle = styles.set('.file-drop{height:' + (d - 30) + 'px}', playerDropHeightStyle);
playerPDFHeightStyle = styles.set('.player-viewport .asset-display object{height:' + (d - 10) + 'px}', playerPDFHeightStyle);
});
};
setPlayerHeight = function() {
storage.setString('player-height', playerHeight);
$scope.playerHeight = playerHeight;
updatePlayerHeight();
};
setPlayerHeight();
$scope.updatePlayerHeight = updatePlayerHeight;
$scope.resizePlayer = function(down, up) {
var bar, frame, h, player;
frame = document.getElementById('slot-player');
frame.style.overflow = 'visible';
player = document.getElementById('player-scroll');
bar = down.currentTarget;
h = Math.max(player.offsetHeight + up.clientY - down.clientY, playerMinHeight);
if (up.type === 'mousemove') {
bar.style.top = h - player.offsetHeight + 'px';
bar.style.borderTop = "2px solid #f26363";
} else {
frame.style.overflow = 'hidden';
bar.style.top = '0px';
bar.style.borderTop = "none";
playerHeight = h;
setPlayerHeight();
}
};
/**
* Track management
* @interface slot/TimeBar
*/
stayDirty = function(global) {
if (global || editing && $scope.current && $scope.form.edit && ($scope.current.asset || $scope.current.record) && ($scope.current.dirty = $scope.form.edit.$dirty)) {
return !confirm(constants.message('navigation.confirmation'));
}
};
TimeBar = (function(superClass) {
extend(TimeBar, superClass);
function TimeBar() {
return TimeBar.__super__.constructor.apply(this, arguments);
}
TimeBar.prototype.choose = function(ap) {
if (stayDirty()) {
return false;
}
$scope.current = this;
if (!this || this.type === 'asset') {
$scope.asset = this != null ? this.asset : void 0;
}
searchLocation($location.replace());
delete target.asset;
delete target.record;
if ($scope.form.edit) {
if (this != null ? this.dirty : void 0) {
$scope.form.edit.$setDirty();
} else {
$scope.form.edit.$setPristine();
}
}
$scope.playing = 0;
updateSelection();
updatePlayerHeight();
autoplay = ap;
return true;
};
TimeBar.prototype.click = function(event) {
if (typeof $scope.editing === 'string') {
return false;
}
if (!this || $scope.current === this) {
new TimePoint(event.clientX, 'x').seek();
} else {
this.choose();
}
};
/**
* Generic function that takes in a time, then will determine if it's
* close enough to do a premiere-esque "snap" feature to the nearest
* object.
* @interface slot/TimeBar/snapping
*/
TimeBar.prototype.snapping = function(pos) {
var i, j, len, listOfAllPlacements, min, ref;
listOfAllPlacements = [];
ref = $scope.assets.concat(records);
for (j = 0, len = ref.length; j < len; j++) {
i = ref[j];
if (!(i !== this)) {
continue;
}
if (i.lt.defined()) {
listOfAllPlacements.push(i.lt);
}
if (i.ut.defined()) {
listOfAllPlacements.push(i.ut);
}
}
if (ruler.position.defined()) {
listOfAllPlacements.push(ruler.position);
}
if (!listOfAllPlacements.length) {
return pos;
}
min = _.min(listOfAllPlacements, function(i) {
return Math.abs(pos.x - i.x);
});
if (Math.abs(pos.x - min.x) <= 10) {
return min;
} else {
return pos;
}
};
return TimeBar;
})(TimeSegment);
unchoose = TimeBar.prototype.choose.bind(void 0);
$scope.click = TimeBar.prototype.click.bind(void 0);
/**
* Selection (temporal) management
* @interface slot/setSelectionEnd
*/
$scope.setSelectionEnd = function(u) {
var pos, sel;
pos = ruler.position.o;
if (u === void 0) {
ruler.selection = new TimeSegment(pos);
} else {
sel = ruler.selection;
if (sel.empty) {
sel = slot.segment;
}
ruler.selection = u ? new TimeSegment(Math.min(sel.l, pos), pos) : new TimeSegment(pos, Math.max(sel.u, pos));
}
updateSelection();
};
$scope.dragSelection = function(down, up, c) {
var endPos, startPos;
if (typeof $scope.editing === 'string' || c && $scope.current !== c) {
return false;
}
startPos = down.position != null ? down.position : down.position = new TimePoint(down.clientX, 'x');
endPos = new TimePoint(up.clientX, 'x');
endPos.clip();
ruler.selection = startPos.x < endPos.x ? new TimeSegment(startPos, endPos) : startPos.x > endPos.x ? new TimeSegment(endPos, startPos) : startPos.x === endPos.x ? new TimeSegment(startPos) : new TimeSegment(null);
if (up.type !== 'mousemove') {
updateSelection();
}
};
$scope.zoom = function(seg) {
if (seg) {
ruler.range = new Segment((seg.lBounded ? seg.l : fullRange.l), (seg.uBounded ? seg.u : fullRange.u));
ruler.zoomed = true;
} else {
ruler.range = fullRange;
ruler.zoomed = false;
}
resetRange();
searchLocation($location.replace());
};
$scope.updateSelection = updateSelection = function() {
var c, executed, j, k, len, len1, ref, ref1, ref2, ref3, t;
if (editing) {
if (typeof $scope.editing === 'string') {
return false;
}
$scope.editing = true;
if ((ref = $scope.current) != null ? ref.excerpts : void 0) {
$scope.current.updateExcerpt();
}
executed = false;
if (!executed) {
executed = true;
window.dataLayer.push({
'event': 'gtm.drag'
});
}
return;
}
playrange = (ref1 = $scope.asset) != null ? ref1.segment.intersect(ruler.selection) : void 0;
ref2 = $scope.tags;
for (j = 0, len = ref2.length; j < len; j++) {
t = ref2[j];
t.update();
}
ref3 = $scope.comments;
for (k = 0, len1 = ref3.length; k < len1; k++) {
c = ref3[k];
c.update();
}
};
getSelection = function() {
if (ruler.selection.empty) {
return new TimeSegment(ruler.position.defined() ? ruler.position : void 0);
} else {
return ruler.selection;
}
};
/**
* Track implementations
* @interface slot/Asset
*/
Asset = (function(superClass) {
extend(Asset, superClass);
function Asset(asset) {
var e;
this.excerpts = (asset != null ? asset.excerpts : void 0) ? (function() {
var j, len, ref, results;
ref = asset.excerpts;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
e = ref[j];
results.push(new Excerpt(e));
}
return results;
})() : [];
this.setAsset(asset);
return;
}
Asset.prototype.type = 'asset';
Asset.prototype.reset = function() {
var e, j, len, ref;
Asset.__super__.reset.call(this);
ref = this.excerpts;
for (j = 0, len = ref.length; j < len; j++) {
e = ref[j];
e.reset();
}
};
Asset.prototype.setAsset = function(asset1) {
this.asset = asset1;
this.fillData();
if (this.asset) {
this.init(this.asset.segment);
if (this.asset.id == target.asset) {
this.choose();
}
if ($scope.current === this) {
$scope.asset = this.asset;
}
this.updateExcerpt();
} else {
this.init(void 0);
}
};
Asset.prototype.fillData = function() {
this.data = this.asset ? {
name: this.asset.name,
classification: this.asset.classification
} : {};
};
Object.defineProperty(Asset.prototype, 'id', {
get: function() {
var ref;
return (ref = this.asset) != null ? ref.id : void 0;
}
});
Object.defineProperty(Asset.prototype, 'name', {
get: function() {
var ref, ref1, ref2, ref3, ref4;
if (!(this.file || this.asset)) {
return constants.message('asset.add');
}
return (ref = (ref1 = (ref2 = (ref3 = this.asset) != null ? ref3.name : void 0) != null ? ref2 : this.data.name) != null ? ref1 : (ref4 = this.file) != null ? ref4.file.name : void 0) != null ? ref : constants.message('file');
}
});
Asset.prototype.removed = function() {
if (this.asset || this.file) {
return;
}
if (this === $scope.current) {
unchoose();
}
if (this === blank) {
blank = void 0;
}
$scope.assets.remove(this);
};
Asset.prototype.remove = function() {
messages.clear(this);
if (this.pending) {
return;
}
if (!confirm(constants.message('asset.remove.confirm'))) {
return;
}
if (this.file) {
this.file.cancel();
delete this.file;
return this.removed();
}
if (!this.asset) {
return this.removed();
}
this.asset.remove().then((function(_this) {
return function(asset) {
uploads.removedAsset = asset;
messages.add({
type: 'green',
body: constants.message('asset.remove.success', _this.name),
owner: _this
});
delete _this.asset;
return _this.removed();
};
})(this), (function(_this) {
return function(res) {
messages.addError({
type: 'red',
body: constants.message('asset.remove.error', _this.name),
report: res,
owner: _this
});
};
})(this));
};
Asset.prototype.save = function() {
var file, ref;
if (this.pending) {
return;
}
this.pending = 1;
messages.clear(this);
if ((ref = this.file) != null ? ref.isComplete() : void 0) {
file = this.file;
}
(file ? (this.data.upload = file.uniqueIdentifier, this.asset ? this.asset.replace(this.data) : slot.createAsset(this.data)) : this.asset.save(this.data)).then((function(_this) {
return function(asset) {
var first;
delete _this.pending;
first = !_this.asset;
_this.setAsset(asset);
if (file) {
if (asset.creation == null) {
asset.creation = {
date: Date.now(),
name: file.file.name
};
}
file.cancel();
delete _this.file;
delete _this.progress;
}
delete _this.dirty;
if (_this === $scope.current) {
$scope.form.edit.$setPristine();
}
updateRange();
Asset.sort();
};
})(this), (function(_this) {
return function(res) {
delete _this.pending;
messages.addError({
type: 'red',
body: constants.message('asset.update.error', _this.name),
report: res,
owner: _this
});
if (file) {
file.cancel();
delete _this.file;
delete _this.progress;
delete _this.data.upload;
}
};
})(this));
};
Asset.prototype.upload = function(file) {
if (this === blank) {
blank = void 0;
}
messages.clear(this);
if (this.file) {
return;
}
this.file = file;
this.progress = 0;
file.store = this;
uploads.upload(slot.volume, file).then((function(_this) {
return function() {
var base;
(base = _this.data).name || (base.name = file.name);
};
})(this), (function(_this) {
return function(res) {
delete _this.file;
delete _this.progress;
if (!blank) {
blank = _this;
} else if ($.isEmptyObject(_this.data)) {
_this.removed();
}
};
})(this));
};
Asset.prototype.error = function(message) {
messages.addError({
type: 'red',
body: constants.message('asset.upload.error', this.name, message || 'unknown error'),
owner: this
});
this.file.cancel();
delete this.file;
delete this.progress;
};
Asset.prototype.rePosition = function() {
$scope.editing = 'asset';
};
Asset.prototype.updatePosition = function() {
this.u = this.l + (this.asset.duration || 0);
};
Asset.prototype.setPosition = function(p) {
if (p instanceof TimePoint) {
this.lt = p;
} else {
this.l = p;
}
this.updatePosition();
$scope.form.position.$setDirty();
};
Asset.prototype.finishPosition = function() {
$scope.form.position.$setPristine();
$scope.editing = true;
this.init(this.asset.segment);
};
Asset.prototype.savePosition = function() {
var ref, shift;
messages.clear(this);
shift = (ref = this.asset) != null ? ref.segment.base : void 0;
return this.asset.save({
container: slot.id,
position: Math.floor(this.l)
}).then((function(_this) {
return function(asset) {
var e, j, len, ref1;
_this.asset = asset;
shift -= _this.asset.segment.base;
if (isFinite(shift) && shift) {
ref1 = _this.excerpts;
for (j = 0, len = ref1.length; j < len; j++) {
e = ref1[j];
e.excerpt.segment.l -= shift;
e.excerpt.segment.u -= shift;
e.l -= shift;
e.u -= shift;
}
}
updateRange();
Asset.sort();
_this.finishPosition();
return _this.updateExcerpt();
};
})(this), (function(_this) {
return function(res) {
_this.finishPosition();
messages.addError({
type: 'red',
body: constants.message('asset.update.error', _this.name),
report: res,
owner: _this
});
};
})(this));
};
Asset.prototype.dragMove = function(down, up) {
var offset, pos;
offset = down.offset != null ? down.offset : down.offset = new TimePoint(down.clientX, 'x').minus(this.lt);
pos = new TimePoint(up.clientX, 'x').minus(offset);
if (!pos.defined()) {
return;
}
pos = this.snapping(pos);
this.setPosition(pos);
if (up.type !== 'mousemove') {
$scope.updatePosition();
}
};
Asset.prototype.updateExcerpt = function() {
var e, seg;
this.excerpt = void 0;
if (!(this.asset && this.excerpts)) {
return;
}
seg = this.full ? this.asset.assumedSegment : getSelection().intersect(this);
if (!this.asset || !seg) {
return;
}
e = this.excerpts.find(function(e) {
return seg.overlaps(e);
});
this.excerpt = !e ? this.overlaps(seg) ? {
target: this.asset.inSegment(seg),
on: false,
release: '',
full: seg.contains(this.asset.assumedSegment)
} : void 0 : e.equals(seg) ? {
current: e,
target: e.excerpt,
on: true,
release: e.excerpt.excerpt + '',
full: e.excerpt.full
} : null;
};
Asset.prototype.editExcerpt = function() {
this.updateExcerpt();
if (this.excerpt.full) {
this.saveExcerpt(this.excerpt.on ? null : true);
} else {
$scope.editing = 'excerpt';
}
};
Asset.prototype.excerptOptions = function() {
var c, i, j, l, len, r, ref, ref1;
r = ((ref = this.asset.classification) != null ? ref : this.asset.container.release) || 0;
l = {
"true": constants.message('release.UNRELEASED.select') + ' (' + constants.message('release.' + constants.release[r] + '.title') + ')'
};
ref1 = constants.release;
for (i = j = 0, len = ref1.length; j < len; i = ++j) {
c = ref1[i];
if (i > r) {
l[i] = constants.message('release.' + c + '.title') + ': ' + constants.message('release.' + c + '.select');
}
}
if (!(this.excerpt.release in l)) {
l[this.excerpt.release] = constants.message('release.prompt');
}
return l;
};
Asset.prototype.saveExcerpt = function(value) {
$scope.editing = true;
messages.clear(this);
if (value === void 0 || value === '') {
return;
}
if (value === 'true') {
value = true;
}
if ((this.asset.classification == null) && value !== true && value > (slot.release || 0) && !confirm(constants.message('release.excerpt.warning'))) {
return;
}
this.excerpt.target.setExcerpt(value).then((function(_this) {
return function(excerpt) {
_this.excerpts.remove(_this.excerpt.current);
if ('excerpt' in excerpt) {
_this.excerpts.push(new Excerpt(excerpt));
}
_this.updateExcerpt();
};
})(this), (function(_this) {
return function(res) {
messages.addError({
type: 'red',
body: constants.message('asset.update.error', _this.name),
report: res,
owner: _this
});
};
})(this));
};
Asset.prototype.canRestore = function() {
var ref;
if (editing && this === blank && ((ref = uploads.removedAsset) != null ? ref.volume.id : void 0) === slot.volume.id) {
return uploads.removedAsset != null;
}
};
Asset.prototype.restore = function() {
messages.clear(this);
uploads.removedAsset.link(slot).then((function(_this) {
return function(a) {
uploads.removedAsset = void 0;
_this.setAsset(a);
if (_this === blank) {
blank = void 0;
}
};
})(this), function(res) {
messages.addError({
type: 'red',
body: constants.message('asset.update.error', '[removed file]'),
report: res,
owner: this
});
});
};
Asset.sort = function() {
if (!$scope.assets) {
return;
}
$scope.assets.sort(function(a, b) {
if (a.asset && b.asset) {
return isFinite(b.asset.segment.l) - isFinite(a.asset.segment.l) || a.asset.segment.l - b.asset.segment.l || a.asset.segment.u - b.asset.segment.u || a.id - b.id;
} else {
return !a.asset - !b.asset || !a.file - !b.file;
}
});
};
return Asset;
})(TimeBar);
/**
* Excerpt in slot
* @interface slot/Excerpt
*/
Excerpt = (function(superClass) {
extend(Excerpt, superClass);
function Excerpt(e) {
Excerpt.__super__.constructor.call(this, e.segment);
this.excerpt = e;
return;
}
return Excerpt;
})(TimeBar);
$scope.addBlank = function() {
if (!blank) {
$scope.assets.push(blank = new Asset());
}
blank.choose();
return blank;
};
$scope.$on('$viewContentLoaded', function() {
if (target.file === 'open') {
$scope.addBlank();
}
});
$scope.fileAdded = function(file) {
var ref;
$flow = file.flowObj;
if (editing) {
(!((ref = $scope.current) != null ? ref.file : void 0) && $scope.current || $scope.addBlank()).upload(file);
}
};
$scope.fileSuccess = function(file) {
file.store.progress = 1;
return file.store.save();
};
$scope.fileProgress = function(file) {
return file.store.progress = file.progress();
};
$scope.fileError = function(file, message) {
return file.store.error(message);
};
/**
* Record in slot
* @interface slot/Record
*/
Record = (function(superClass) {
extend(Record, superClass);
function Record(r) {
var f, j, len, ref;
this.rec = r;
this.record = r.record || slot.volume.records[r.id];
ref = ['age'];
for (j = 0, len = ref.length; j < len; j++) {
f = ref[j];
if (f in r) {
this[f] = r[f];
}
}
Record.__super__.constructor.call(this, r.segment);
if (editing) {
this.fillData();
}
return;
}
Record.prototype.type = 'record';
Record.prototype.fillData = function() {
this.data = {
measures: angular.extend({}, this.record.measures),
add: ''
};
if (editing) {
this.sortMetrics();
}
};
Record.prototype.sortMetrics = function() {
var keys;
keys = _.keys(this.data.measures);
this.sortedMetrics = keys.sort(function(a, b) {
return a - b;
});
};
Object.defineProperty(Record.prototype, 'id', {
get: function() {
return this.rec.id;
}
});
Record.prototype.remove = function() {
messages.clear(this);
return slot.removeRecord(this.record, this).then((function(_this) {
return function(r) {
if (!r) {
return;
}
records.remove(_this);
if ($scope.current === _this) {
unchoose();
}
Record.place();
};
})(this), function(res) {
messages.addError({
type: 'red',
body: 'Unable to remove',
report: res,
owner: this
});
});
};
Record.prototype.metrics = function() {
var m;
return ((function() {
var results;
results = [];
for (m in this.record.measures) {
results.push(constants.metric[m]);
}
return results;
}).call(this)).sort(byId);
};
Record.prototype.rePosition = function() {
$scope.editing = 'record';
};
Record.prototype.updatePosition = function(u) {
$scope.form.position[u ? 'position-lower' : 'position-upper'].$validate();
};
Record.prototype.finishPosition = function() {
$scope.editing = true;
this.init(this.rec.segment);
$scope.form.position.$setPristine();
};
Record.prototype.savePosition = function() {
messages.clear(this);
return slot.moveRecord(this.record, this.rec.segment, this).then((function(_this) {
return function(r) {
if (r && _this.empty) {
records.remove(_this);
if (_this === $scope.current) {
unchoose();
}
}
_this.finishPosition();
if (r) {
Record.place();
updateRange();
}
};
})(this), (function(_this) {
return function(res) {
messages.addError({
type: 'red',
body: 'Error saving record',
report: res,
owner: _this
});
};
})(this));
};
Record.prototype.drag = function(event, which) {
var x;
x = new TimePoint(event.clientX, 'x');
this[which ? 'ut' : 'lt'] = which && x.p > 1 ? new TimePoint(2e308) : !which && x.p < 0 ? new TimePoint(-2e308) : this.snapping(x);
if (this.empty) {
if (which) {
this.lt = this.ut;
} else {
this.ut = this.lt;
}
}
if (event.type !== 'mousemove') {
$scope.form.position.$setDirty();
}
};
Record.place = function() {
var i, j, k, len, len1, len2, n, o, overlaps, r, ref, t;
t = [];
overlaps = function(rr) {
return rr.record.id !== r.record.id && r.overlaps(rr);
};
ref = records.sort(function(a, b) {
return a.record.category - b.record.category || a.rec.id - b.rec.id;
});
for (j = 0, len = ref.length; j < len; j++) {
r = ref[j];
for (i = k = 0, len1 = t.length; k < len1; i = ++k) {
o = t[i];
if (!(o[0].record.category !== r.record.category || o.some(overlaps))) {
break;
}
}
if (!(i in t)) {
t[i] = [];
}
t[i].push(r);
if (r.id == target.record) {
r.choose();
}
}
for (n = 0, len2 = t.length; n < len2; n++) {
r = t[n];
r.sort(byPosition);
}
$scope.records = t;
};
return Record;
})(TimeBar);
$scope.positionBackgroundStyle = function(l, i) {
if (l[i].lt.p > 1 || l[i].ut.p < 0) {
return {
visibility: "hidden"
};
} else {
return new TimeSegment(l[i].l, i + 1 in l ? l[i + 1].l : 2e308).style();
}
};
$scope.setCategory = function(c) {
var r, ref, ri, rs;
if (c != null) {
rs = {};
ref = $scope.addRecord.records;
for (ri in ref) {
r = ref[ri];
if (r.category == c) {
rs[ri] = r.displayName;
}
}
$scope.addRecord.options = rs;
} else {
$scope.addRecord.options = void 0;
}
};
$scope.addRecord = function(r) {
var j, len, rc, ref, ri, rs, seg, sr;
seg = getSelection();
if (r === void 0) {
$scope.editing = 'addrecord';
rs = {};
ref = slot.volume.records;
for (ri in ref) {
r = ref[ri];
rs[ri] = r;
}
for (j = 0, len = records.length; j < len; j++) {
sr = records[j];
if (sr.record.id in rs && sr.overlaps(seg)) {
delete rs[sr.record.id];
}
}
$scope.addRecord.records = rs;
rc = {};
for (ri in rs) {
r = rs[ri];
rc[r.category] = null;
}
$scope.addRecord.categories = rc;
$scope.addRecord.select = null;
$scope.setCategory($scope.addRecord.category);
} else {
$scope.addRecord.records = void 0;
if (r == null) {
$scope.editing = true;
return;
}
slot.addRecord(slot.volume.records[r], seg).then(function(r) {
$scope.editing = true;
r = new Record(r);
records.push(r);
Record.place();
r.choose();
}, function(res) {
$scope.editing = true;
messages.addError({
body: 'Error adding record',
report: res,
owner: $scope
});
});
}
};
/**
* TagName in slot
* @interface slot/TagName
*/
TagName = (function(superClass) {
extend(TagName, superClass);
function TagName(name) {
this.id = name;
TagName.__super__.constructor.call(this);
return;
}
TagName.prototype.save = function(vote) {
var seg, tag;
seg = getSelection();
tag = this;
return slot.setTag(this.id, vote, editing, seg).then(function(data) {
var ref, ref1;
if (!(tag instanceof Tag)) {
tag = $scope.tags.find(function(t) {
return t.id === data.id;
});
if (!tag) {
tag = new Tag(data);
tag.toggle(true);
$scope.tags.push(tag);
}
}
tag.fillData(data);
if ((editing ? (ref = tag.keyword) != null ? ref.length : void 0 : (ref1 = tag.coverage) != null ? ref1.length : void 0)) {
tag.update();
} else {
$scope.tags.remove(tag);
}
tooltips.clear();
}, (function(_this) {
return function(res) {
messages.addError({
body: constants.message('tags.vote.error', {
sce: $sce.HTML
}, _this.id),
report: res,
owner: $scope
});
};
})(this));
};
return TagName;
})(TimeBar);
$scope.vote = function(name, vote) {
return new TagName(name).save(vote);
};
tagToggle = (ref = (ref1 = storage.getString('tag-toggle')) != null ? ref1.split("\n") : void 0) != null ? ref : [];
/**
* Tag in slot
* @interface slot/Tag
*/
Tag = (function(superClass) {
extend(Tag, superClass);
function Tag(t) {
var ref2;
Tag.__super__.constructor.call(this, t.id);
this.active = (ref2 = t.id, indexOf.call(tagToggle, ref2) >= 0) || t.id === target.tag;
this.fillData(t);
return;
}
Tag.prototype.type = 'tag';
Tag.prototype.reset = function() {
var f, j, k, len, len1, ref2, ref3, t;
ref2 = (editing ? ['keyword'] : ['coverage', 'vote', 'keyword']);
for (j = 0, len = ref2.length; j < len; j++) {
f = ref2[j];
ref3 = this[f];
for (k = 0, len1 = ref3.length; k < len1; k++) {
t = ref3[k];
t.reset();
}
}
};
Tag.prototype.fillData = function(t) {
var f, j, k, len, len1, ref2, ref3, s;
this.weight = t.weight;
ref2 = (editing ? ['keyword'] : ['coverage', 'vote', 'keyword']);
for (j = 0, len = ref2.length; j < len; j++) {
f = ref2[j];
this[f] = [];
if (t[f]) {
ref3 = t[f];
for (k = 0, len1 = ref3.length; k < len1; k++) {
s = ref3[k];
this[f].push(new TimeSegment(s));
}
}
}
};
Tag.prototype.toggle = function(act) {
if (this.active = act != null ? act : !this.active) {
tagToggle.push(this.id);
} else {
tagToggle.remove(this.id);
}
return storage.setString('tag-toggle', tagToggle.join("\n"));
};
Tag.prototype.update = function() {
var j, len, ref2, s, sel, state;
state = false;
sel = getSelection();
ref2 = (editing ? this.keyword : this.vote);
for (j = 0, len = ref2.length; j < len; j++) {
s = ref2[j];
if (sel.contains(s)) {
state = true;
} else if (sel.overlaps(s)) {
state = void 0;
break;
}
}
return this.state = state;
};
return Tag;
})(TagName);
/**
* Comment in slot
* @interface slot/Comment
*/
Comment = (function(superClass) {
extend(Comment, superClass);
function Comment(c) {
this.comment = c;
Comment.__super__.constructor.call(this, c.segment);
}
Comment.prototype.type = 'comment';
Comment.prototype.update = function() {
this.classes = [];
if (this.comment.parents) {
this.classes.push('depth-' + Math.min(this.comment.parents.length, 5));
}
if (!(ruler.selection.empty || ruler.selection.overlaps(this) || this === $scope.replyTo)) {
return this.classes.push('notselected');
}
};
Comment.prototype.setReply = function(event) {
var ref2, ref3;
if ((ref2 = $scope.form.comment) != null) {
ref2.text = '';
}
if ((ref3 = $scope.form.comment) != null) {
ref3.reply = '';
}
$scope.commentReply = event ? (this.select(event), this) : void 0;
return updateSelection();
};
return Comment;
})(TimeBar);
$scope.addComment = function(message, replyTo) {
return slot.postComment({
text: message
}, getSelection(), replyTo != null ? replyTo.comment.id : void 0).then(function() {
return slot.getSlot(slot.segment, ['comments']).then(function(res) {
var comment, j, len, ref2;
$scope.form.comment.text = $scope.form.reply = '';
$scope.comments = (function() {
var j, len, ref2, results;
ref2 = res.comments;
results = [];
for (j = 0, len = ref2.length; j < len; j++) {
comment = ref2[j];
results.push(new Comment(comment));
}
return results;
})();
ref2 = $scope.comments;
for (j = 0, len = ref2.length; j < len; j++) {
comment = ref2[j];
comment.update();
}
}, function(res) {
return messages.addError({
body: constants.message('comments.update.error'),
report: res
});
});
}, function(e) {
return messages.addError({
body: constants.message('comments.add.error'),
report: e
});
});
};
$scope.tags = (function() {
var ref2, ref3, ref4, results;
ref2 = slot.tags;
results = [];
for (tagId in ref2) {
tag = ref2[tagId];
if ((editing ? (ref3 = tag.keyword) != null ? ref3.length : void 0 : (ref4 = tag.coverage) != null ? ref4.length : void 0)) {
results.push(new Tag(tag));
}
}
return results;
})();
$scope.comments = (function() {
var j, len, ref2, results;
ref2 = slot.comments;
results = [];
for (j = 0, len = ref2.length; j < len; j++) {
comment = ref2[j];
results.push(new Comment(comment));
}
return results;
})();
$scope.assets = (function() {
var ref2, results;
ref2 = slot.assets;
results = [];
for (assetId in ref2) {
asset = ref2[assetId];
results.push(new Asset(asset));
}
return results;
})();
Asset.sort();
records = slot.records.map(function(r) {
return new Record(r);
});
$scope.playing = 0;
Record.place();
updateRange();
updateSelection();
if (editing) {
done = $scope.$on('$locationChangeStart', function(event, url) {
var uploading;
if (url.includes(slot.editRoute())) {
return;
}
if ($flow) {
uploading = $flow.isUploading();
$flow.pause();
}
if (stayDirty(uploading)) {
if (uploading) {
$flow.resume();
}
display.cancelRouteChange(event);
} else {
done();
}
});
}
$scope.$on('$destroy', function() {
if ($flow != null) {
$flow.cancel();
}
});
}
]);
//# sourceMappingURL=slot.js.map