1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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()
|