diff options
Diffstat (limited to 'public/js/app.js')
| -rw-r--r-- | public/js/app.js | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/public/js/app.js b/public/js/app.js new file mode 100644 index 0000000..f194920 --- /dev/null +++ b/public/js/app.js @@ -0,0 +1,139 @@ +var dragging = false +var playing = [] +var rowTemplate = $("#row-template").html() +var controlsTemplate = $("#controls-template").html() +var pairs = [] + +function init(){ + $.getJSON('/api/list', build) +} +function build(data){ + $("#lists").empty() + pairs = data.order.pairs + var pair_lists = pairs.reduce((a,b) => { + for (var i = 0; i < b.length; i++) { + a[i] = a[i] || [] + a[i].push(b[i]) + } + return a + }, [[]]) + data.list.forEach((dir, i) => { + const pair_list = pair_lists[i] + var initial_pairs = pair_list.map(fn => { + var t = rowTemplate.replace(/{src}/g, fn).replace('{className}', 'row pair') + return t + }).join('') + var files = dir.files.map(f => { + var fn = '/data/' + dir.name + '/' + f + if (pair_list.indexOf(fn) !== -1) return + var t = rowTemplate.replace(/{src}/g, fn).replace('{className}', 'row') + return t + }).join('') + var $el = $("<div class='list'><h3>" + dir.name + "</h3><div class='sort'>" + initial_pairs + files + "</div></div>") + $('#lists').append($el) + }) + var buttons = [] + for (var i = 0, _len = data.list[0].files.length; i < _len; i++) { + buttons.push(controlsTemplate.replace('{className}', i < pairs.length ? 'pair' : '' )) + } + $("#lists").append("<div class='list row-controls'><h3> </h3><div>" + buttons.join('') + "</div>") + bind() +} +function bind(){ + window.addEventListener('keydown', keydown) + $('#save').click(save) + $("#lists .sort").sortable({ + start: drag_start, + stop: drag_stop + }) + $("#lists").disableSelection() + selectAll('audio').forEach((el) => { + el.addEventListener('loadedmetadata', () => { + // console.log('loaded', el.duration) + $(el).next('span').html(el.duration.toFixed(2)) + }) + el.parentNode.querySelector('.play').addEventListener('click', e => { + el.currentTime = 0 + el.play() + playing = [el] + }) + }) + selectAll('.play-row').forEach((button, i) => { + button.addEventListener('click', e => play_row(i)) + }) + selectAll('.save-pair').forEach((button, i) => { + button.addEventListener('click', e => save_pair(i)) + }) +} +function stop(){ + playing.forEach(tag => tag.pause()) +} +function play_row(i) { + stop() + playing = selectAll('.sort').map(col => { + var audio = col.children[i].querySelector('audio') + audio.currentTime = 0 + audio.play() + return audio + }) +} +function save_pair(i){ + const pair = selectAll('.sort').map(col => { + const el = col.children[i] + el.className = 'row pair' + col.removeChild(el) + $(col).prepend(el) + return $(el).data('src') + }) + var buttons = selectAll('.row-controls div div') + buttons[pairs.length].className = 'pair' + pairs.unshift(pair) + save() +} +function keydown(e){ + // console.log(e.keyCode) + const isMeta = (e.metaKey || e.altKey || e.ctrlKey) + switch(e.keyCode){ + case 32: // space + stop() + break + case 83: // S + if (isMeta) { + e.preventDefault() + save() + } + break + default: + break + } +} +function drag_start(){ + dragging = true + $(this).addClass("dragging") +} +function drag_stop(){ + dragging = false + $(".dragging").removeClass("dragging") +} +function selectAll(q) { + return toArray(document.querySelectorAll(q)) +} +function toArray(a){ + return Array.prototype.slice.apply(a) +} + +function save(){ + console.log('saving', pairs.length, 'pairs') + $.ajax({ + type: 'POST', + url: '/api/save', + contentType: "application/json", + dataType: "json", + data: JSON.stringify({ + date: Date.now(), + pairs: pairs, + }), + }) +} + +init() |
