summaryrefslogtreecommitdiff
path: root/public/js/app.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/js/app.js')
-rw-r--r--public/js/app.js139
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>&nbsp;</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()