]>
Commit | Line | Data |
---|---|---|
1 | // Written by Mike Frysinger <vapier@gmail.com>. Released into the public domain. Suck it. | |
2 | ||
3 | /* Globals to allow easy manipulation via javascript console */ | |
4 | var mpc; | |
5 | var tcpclient; | |
6 | ||
7 | function TcpClientSender(tcpclient) { | |
8 | this.tcpclient = tcpclient; | |
9 | } | |
10 | TcpClientSender.prototype.send = function(data, cb) { | |
11 | this.tcpclient.sendMessage(data, cb); | |
12 | } | |
13 | ||
14 | function tramp_mpc_recv(data) { | |
15 | mpc.recv(data); | |
16 | } | |
17 | ||
18 | function sync_storage(sync) { | |
19 | return sync ? chrome.storage.sync : chrome.storage.local; | |
20 | } | |
21 | ||
22 | window.onload = function() { | |
23 | var local_keys = [ | |
24 | 'sync', | |
25 | ]; | |
26 | var sync_keys = [ | |
27 | 'host', 'port', | |
28 | ]; | |
29 | var options = { | |
30 | 'host': '192.168.0.2', | |
31 | 'port': 6600, | |
32 | 'sync': true, | |
33 | }; | |
34 | ||
35 | chrome.storage.local.get(local_keys, function(settings) { | |
36 | local_keys.forEach(function(key) { | |
37 | if (key in settings) | |
38 | options[key] = settings[key] | |
39 | }); | |
40 | ||
41 | var storage = sync_storage(options['sync']); | |
42 | storage.get(sync_keys, function(settings) { | |
43 | sync_keys.forEach(function(key) { | |
44 | if (key in settings) | |
45 | options[key] = settings[key]; | |
46 | }); | |
47 | ||
48 | init_ui(local_keys, sync_keys, options); | |
49 | mpc_connect(); | |
50 | }); | |
51 | }); | |
52 | }; | |
53 | ||
54 | function mpc_refresh() { | |
55 | mpc.status(); | |
56 | mpc.currentsong(); | |
57 | } | |
58 | ||
59 | function mpc_connect(host, port) { | |
60 | if (typeof(host) != 'string') { | |
61 | host = window['opts_host'].value; | |
62 | port = parseInt(window['opts_port'].value); | |
63 | } | |
64 | ||
65 | if (mpc != undefined) { | |
66 | console.log('disconnecting'); | |
67 | update_ui('disconnect'); | |
68 | delete mpc; | |
69 | tcpclient.disconnect(); | |
70 | delete tcpclient; | |
71 | } | |
72 | ||
73 | update_ui('init'); | |
74 | tcpclient = new TcpClient(host, port); | |
75 | tcpclient.connect(function() { | |
76 | var mpc_sender = new TcpClientSender(tcpclient); | |
77 | tcpclient.addResponseListener(tramp_mpc_recv); | |
78 | mpc = new Mpc(mpc_sender, update_ui); | |
79 | console.log('connected to ' + host + ':' + port); | |
80 | mpc_refresh(); | |
81 | }); | |
82 | } | |
83 | ||
84 | function tramp_mpc_consume() { | |
85 | var val = zo(!getToggleButton(this)); | |
86 | mpc.consume(val); | |
87 | setToggleButton(this, val); | |
88 | } | |
89 | function tramp_mpc_next() { mpc.next(); } | |
90 | function tramp_mpc_pause() { mpc.pause(); } | |
91 | function tramp_mpc_play() { mpc.play(); } | |
92 | function tramp_mpc_previous() { mpc.previous(); } | |
93 | function tramp_mpc_random() { | |
94 | var val = zo(!getToggleButton(this)); | |
95 | mpc.random(val); | |
96 | setToggleButton(this, val); | |
97 | } | |
98 | function tramp_mpc_repeat() { | |
99 | var val = zo(!getToggleButton(this)); | |
100 | mpc.repeat(val); | |
101 | setToggleButton(this, val); | |
102 | } | |
103 | function tramp_mpc_seekcur() { mpc.seekcur(this.value); } | |
104 | function tramp_mpc_setvol() { mpc.setvol(this.value); } | |
105 | function tramp_mpc_single() { | |
106 | var val = zo(!getToggleButton(this)); | |
107 | mpc.single(val); | |
108 | setToggleButton(this, val); | |
109 | } | |
110 | function tramp_mpc_stop() { mpc.stop(); } | |
111 | ||
112 | function zo(val) { | |
113 | return val ? 1 : 0; | |
114 | } | |
115 | function szo(val) { | |
116 | return val == '0' ? 0 : 1; | |
117 | } | |
118 | function getToggleButton(btn) { | |
119 | return btn.style.borderStyle == 'inset'; | |
120 | } | |
121 | function setToggleButton(btn, val) { | |
122 | if (val === undefined) | |
123 | val = !getToggleButton(btn); | |
124 | btn.style.borderStyle = val ? 'inset' : ''; | |
125 | } | |
126 | ||
127 | function show_page(page) { | |
128 | if (typeof(page) != 'string') | |
129 | page = this.id.split('.')[1]; | |
130 | ||
131 | var eles = document.getElementsByClassName('main'); | |
132 | for (var i = 0; i < eles.length; ++i) { | |
133 | var ele = eles[i]; | |
134 | var dis = 'none'; | |
135 | var cls = ''; | |
136 | if (ele.id == 'main.' + page) { | |
137 | dis = ''; | |
138 | cls = 'selected'; | |
139 | } | |
140 | ele.style.display = dis; | |
141 | document.getElementById('tab.' + ele.id.split('.')[1]).className = cls; | |
142 | } | |
143 | } | |
144 | ||
145 | function update_local_settings() { | |
146 | var setting = {}; | |
147 | setting[this.id] = this.checked; | |
148 | chrome.storage.local.set(setting); | |
149 | } | |
150 | ||
151 | function update_sync_settings() { | |
152 | var setting = {}; | |
153 | setting[this.id] = this.value; | |
154 | var storage = sync_storage(window['opts_sync'].checked); | |
155 | storage.set(setting); | |
156 | } | |
157 | ||
158 | function init_ui(local_keys, sync_keys, options) { | |
159 | /* Setup footer */ | |
160 | [ | |
161 | 'controls', 'metadata', 'options', | |
162 | ].forEach(function(id) { | |
163 | document.getElementById('tab.' + id).onclick = show_page; | |
164 | }); | |
165 | ||
166 | /* Setup control tab */ | |
167 | ui_mpc_status = document.getElementById('status'); | |
168 | ui_mpc_metadata = document.getElementById('metadata'); | |
169 | [ | |
170 | 'consume', 'next', 'pause', 'play', 'previous', 'random', 'repeat', | |
171 | 'seekcur', 'setvol', 'single', 'stop', | |
172 | ].forEach(function(id) { | |
173 | var ele = window['ui_mpc_' + id] = document.getElementById(id); | |
174 | ele.onclick = window['tramp_mpc_' + id]; | |
175 | ele.title = id; | |
176 | }); | |
177 | ||
178 | /* Setup options tab */ | |
179 | document.getElementById('connect').onclick = mpc_connect; | |
180 | local_keys.forEach(function(id) { | |
181 | var ele = window['opts_' + id] = document.getElementById(id); | |
182 | ele.checked = options[id]; | |
183 | ele.onchange = update_local_settings; | |
184 | }); | |
185 | sync_keys.forEach(function(id) { | |
186 | var ele = window['opts_' + id] = document.getElementById(id); | |
187 | ele.value = options[id]; | |
188 | ele.oninput = update_sync_settings; | |
189 | }); | |
190 | } | |
191 | ||
192 | function update_ui(state, cmd) { | |
193 | if (typeof(state) == 'string') { | |
194 | ui_mpc_status.innerText = ({ | |
195 | 'disconnect': 'Disconnecting...', | |
196 | 'init': 'Connecting...', | |
197 | })[state]; | |
198 | return; | |
199 | } | |
200 | ||
201 | if (Array.isArray(state)) { | |
202 | /* | |
203 | switch (cmd[0]) { | |
204 | case 'setvol': | |
205 | case 'seekcur': | |
206 | break; | |
207 | default: | |
208 | mpc_refresh(); | |
209 | } | |
210 | */ | |
211 | return; | |
212 | } | |
213 | ||
214 | if ('file' in state) { | |
215 | // Hack: should be a real object. | |
216 | ui_mpc_metadata.innerText = state['file']; | |
217 | return; | |
218 | } | |
219 | ||
220 | var time = state.time.split(':'); | |
221 | window['ui_mpc_seekcur'].max = time[1]; | |
222 | window['ui_mpc_seekcur'].value = time[0]; | |
223 | ||
224 | window['ui_mpc_setvol'].value = state.volume; | |
225 | [ | |
226 | 'consume', 'random', 'repeat', 'single', | |
227 | ].forEach(function(id) { | |
228 | setToggleButton(window['ui_mpc_' + id], szo(state[id])); | |
229 | }); | |
230 | ||
231 | ui_mpc_status.innerText = ({ | |
232 | 'play': 'Playing', | |
233 | 'pause': 'Paused', | |
234 | 'stop': 'Stopped', | |
235 | })[state.state]; | |
236 | } |