2 Pitchfork Music Player Daemon Client
3 Copyright (C) 2007 Roger Bystrøm
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 var ALBUMART_NO_COVER = "../images/gmpc-no-cover.png";
20 var ALBUMART_NO_COVER_THUMB = "../images/gmpc-no-cover-thumb.png";
22 function metadata_open_default() {
23 sidebar_open("metadata");
24 metadata_open_lyrics(); // default opening is lyrics
27 function metadata_init() {
29 var elem = document.getElementById('metadata_open');
31 add_listener(elem, "click", metadata_open_default);
32 elem = document.getElementById("metadata_close");
34 add_listener(elem, "click", sidebar_close);
36 elem = document.getElementById("metadata_open_lyrics");
38 add_listener(elem, "click", metadata_open_lyrics);
39 elem = document.getElementById('metadata_open_review');
41 add_listener(elem, "click", metadata_open_review);
42 elem = document.getElementById('metadata_open_description');
44 add_listener(elem, "click", metadata_open_description);
46 add_listener(sidebar.display, "click", metadata_lyrics_refetch);
47 elem = document.getElementById("recommendation_open");
49 add_listener(elem, "click", recommend_open);
52 function parse_html_tags(txt) {
53 txt = txt.replace(/<i>/gi, "<i>");
54 txt = txt.replace(/<\/i>/gi, "</i>");
55 txt = txt.replace(/\n/g, "<br/>\n");
56 txt = txt.replace(/<p>/gi, "<br/><br/>\n");
57 txt = txt.replace(/<\/p>/gi, "");
61 function metadata_set_content(content) {
62 /* don't display the content if right view is not open */
63 if(sidebar.open_view=="metadata")
64 sidebar.set_content(content);
67 function metadata_open_lyrics(e, force) {
68 sidebar.say_loading();
69 sidebar.last_metadata_request = "lyrics";
70 if(playing.title&&playing.artist&&playing.title.length>0&&playing.artist.length>0) {
71 var http = new XMLHttpRequest();
72 http.open("GET", "metadata.php?lyric" + (force?"&force":""), true);
73 http.onreadystatechange = function() {
74 if(http.readyState==4&&sidebar.last_metadata_request=="lyrics") {
75 var lyrics = create_fragment();
76 if(http.responseText=="nocachedir") {
77 lyrics.appendChild(create_txt(LANG.E_MISSING_CACHE));
80 if(http.responseXML) {
81 var result = get_tag(http.responseXML, "result");
82 if(result=="failed") {
83 lyrics.appendChild(create_txt(LANG.E_LYRICS_FAILURE));
85 else if(result=="notfound") {
86 lyrics.appendChild(create_txt(LANG.E_LYRICS_NOT_FOUND));
87 var url = get_tag(http.responseXML, "url");
89 lyrics.appendChild(metadata_build_lyricwiki_url(url, LANG.ADD));
93 var refetch = create_node("p");
94 refetch.appendChild(create_txt("["+LANG.REFETCH+"]"));
95 refetch.className = "fakelink";
96 refetch.id = "lyrics_refetch_button";
97 lyrics.appendChild(refetch);
98 var title = create_node("span");
99 title.style.fontSize = "larger";
100 title.style.marginRight = "60px";
101 title.appendChild(create_txt(get_tag(http.responseXML, "title")));
102 var artist = create_node("span");
103 artist.style.fontSize = "100%";
104 artist.appendChild(create_txt(get_tag(http.responseXML, "artist")));
106 lyrics.appendChild(title);
107 lyrics.appendChild(create_node("br"));
108 lyrics.appendChild(artist);
109 lyrics.appendChild(create_node("br"));
110 lyrics.appendChild(create_node("br"));
112 var song = get_tag(http.responseXML, "lyric");
113 if(song&&song.length) {
114 add_string_with_br(lyrics, song);
117 lyrics.appendChild(create_txt(LANG.E_MISSING_LYRICS));
119 var url = get_tag(http.responseXML, "url");
121 lyrics.appendChild(metadata_build_lyricwiki_url(url, LANG.EDIT));
126 lyrics.appendChild(create_txt(LANG.E_COMM_PROBLEM));
128 metadata_set_content(lyrics);
134 metadata_set_content(create_txt(LANG.E_MISSING_AS_NAME));
138 function metadata_build_lyricwiki_url(url, txt) {
139 var a = create_node("a");
140 a.href = url.replace(/&/i, "&");
141 a.title = sprintf(LANG.LYRICWIKI_LYRIC, txt);
143 a.appendChild(create_txt("[" + txt + "]"));
144 a.style.display = "block";
145 a.style.marginTop = "10px";
149 function metadata_lyrics_refetch(e) {
150 if(e&&e.target&&e.target.id=="lyrics_refetch_button") {
152 metadata_open_lyrics(e, true);
156 function metadata_open_review() {
157 request_review_desc(0);
159 function metadata_open_description() {
160 request_review_desc(1);
163 function request_review_desc(type) {
164 sidebar.say_loading();
165 sidebar.last_metadata_request = "review";
166 if(playing.album&&playing.artist&&playing.album.length>0&&playing.artist.length>0) {
167 var http = new XMLHttpRequest()
168 var album = playing.album;
169 var artist = playing.artist;
170 http.open("GET", "metadata.php?review&artist=" + encodeURIComponent(playing.artist) +
171 "&album=" + encodeURIComponent(playing.album), true);
172 http.onreadystatechange = function() {
173 if(http.readyState==4&&sidebar.last_metadata_request=="review") {
174 if(get_tag(http.responseXML, "result")) {
175 metadata_set_content(LANG.E_GET_INFO);
179 var content = create_fragment();
183 tmp = LANG.ALBUM_REVIEW;
184 stuff = get_tag(http.responseXML, "review");
187 tmp = LANG.ALBUM_DESC;
188 stuff = get_tag(http.responseXML, "desc");
192 var asin = get_tag(http.responseXML, "asin");
196 tmp+=sprintf(LANG.ALBUM_AA_NAME, album, artist);
197 tmp = create_node("span", null, tmp);
198 tmp.style.fontSize = "larger";
199 content.appendChild(tmp);
200 content.appendChild(create_node("br"));
201 content.appendChild(create_node("br"));
202 tmp = create_node("span");
203 tmp.innerHTML = parse_html_tags(stuff);
204 content.appendChild(tmp);
205 tmp = create_node("a");
206 tmp.appendChild(create_txt(LANG.NT_AMAZON));
207 if(build_amazon_link(tmp)) {
208 content.appendChild(create_node("br"));
209 content.appendChild(create_node("br"));
210 content.appendChild(tmp);
214 content.appendChild(create_txt(sprintf(LANG.E_NOT_FOUND, tmp.toLowerCase())));
216 metadata_set_content(content);
222 metadata_set_content(create_txt(LANG.E_MISSING_AA_NAME));
228 function request_thumbnail() {
229 var albumart = document.getElementById("albumart");
230 var rartist = playing.artist;
231 var ralbum = playing.album;
233 remove_children(albumart);
234 if(playing.album&&playing.artist&&ralbum.length>0&&rartist.length>0) {
235 var http = new XMLHttpRequest()
236 http.open("GET", "metadata.php?cover&artist=" + encodeURIComponent(rartist) +
237 "&album=" + encodeURIComponent(ralbum), true);
238 http.onreadystatechange = function() {
239 if(http.readyState==4) {
241 if(http.responseText=="nocachedir") {
242 debug(LANG.E_MISSING_CACHE); // TODO
245 if(get_tag(http.responseXML, "result")) {
246 // something's not okay.... TODO
250 /* test if we're still wanted */
251 if(rartist != playing.artist || ralbum != playing.album)
254 var thumb = get_tag(http.responseXML, "thumbnail");
258 url = ALBUMART_NO_COVER_THUMB;
261 url = ALBUMART_URL + encodeURIComponent(thumb);
264 playing.image = get_tag(http.responseXML, "image");
266 var img = create_node("img");
268 add_listener(img, "click", show_big_albumart);
269 img.className = "thumbnailart";
270 if(albumart.hasChildNodes()) {
271 /* probably just one, but... */
272 var imgs = albumart.getElementsByTagName("img");
273 for(var i=0; i<imgs.length; i++) {
274 remove_listener(imgs[i], "click", show_big_albumart);
276 remove_children(albumart);
278 albumart.appendChild(img);
280 var asin = get_tag(http.responseXML, "asin");
283 else playing.asin = false;
285 if(albumart_is_open())
290 //debug("request_thumbmail error: " + e.message);
298 function show_big_albumart() {
300 var div = document.getElementById("albumart_show");
303 div = create_node("div", "albumart_show");
304 div.className = "big_albumart";
305 document.body.appendChild(div);
306 close = create_node("p");
307 close.style.color = "white";
308 close.style.position = "absolute";
309 close.style.right = "5px";
310 close.style.bottom = "0px";
311 close.style.margin = "0px 5px 5px 0px";
312 close.className = "fakelink";
313 close.appendChild(create_txt("[" + LANG.CLOSE + "]"));
316 /* if it hadn't been for opera we could have used the old one */
317 var oimg = document.getElementById("albumart_img");
318 var img = create_node("img", "albumart_img");
319 img.className = "big_albumart";
320 img.style.display = "none";
322 replace_node(img, oimg);
324 div.appendChild(img);
326 add_listener(img, "load", albumart_loaded);
328 var node = document.getElementById("albumart_txt");
330 node = create_node("p", "albumart_txt");
331 div.appendChild(node);
333 remove_children(node);
334 node.appendChild(create_txt(LANG.WAIT_LOADING));
336 add_listener(div, "click", albumart_big_remove);
337 div.style.display = "";
339 if(playing.image&&playing.image.length)
340 url = ALBUMART_URL + encodeURIComponent(playing.image);
341 else url = ALBUMART_NO_COVER;
344 div.appendChild(close);
350 function albumart_is_open() {
351 var aa = document.getElementById("albumart_show");
352 if(aa&&aa.style.display != "none")
357 function albumart_big_remove() {
358 var aa = document.getElementById("albumart_show");
359 var img = document.getElementById("albumart_img");
360 img.style.display = "none";
361 remove_listener(aa, "click", albumart_big_remove);
362 aa.style.display = "none";
363 aa.style.height = "";
367 function albumart_loaded() {
368 var img = document.getElementById("albumart_img");
369 var disp = document.getElementById("albumart_show");
370 var txt = document.getElementById("albumart_txt");
371 remove_listener(img, "load", albumart_loaded);
372 img.style.opacity = "0.1";
373 albumart_resize(disp, img);
374 adjust_opacity_timer(img, 0.0, 1.0);
375 remove_children(txt);
376 if(playing.asin&&playing.asin.length>0) {
377 var a = create_node("a");
378 build_amazon_link(a);
379 a.appendChild(create_txt(LANG.NT_AMAZON));
380 a.style.color = "white";
381 a.style.textTransform = "none";
382 a.title = LANG.ALBUM_AMAZON;
387 function albumart_resize(disp, img) {
390 img.style.visibility = "hidden";
391 img.style.display = "inline";
395 else got_real = false;
398 else got_real = false;
399 disp.style.height = (height+ 30) + "px";
400 disp.style.width = (width + 0) + "px";
401 img.style.visibility = "visible";
405 function build_amazon_link(a) {
406 if(playing.asin&&playing.asin.length>0) {
407 a.href = "http://www.amazon.com/gp/product/" + playing.asin + "?ie=UTF8&tag=httppitchfork-20" +
408 "&linkCode=as2&camp=1789&creative=9325&creativeASIN=" + playing.asin;
417 function recommend_init() {
418 var tmp = create_node("p");
419 tmp.className = "nomargin";
420 tmp.appendChild(create_txt(LANG.RECOMMEND_RECOMMENDATIONS));
421 var close = create_node("span", null, " ["+LANG.CLOSE+"]");
422 add_listener(close, "click", sidebar_close);
423 close.className = "fakelink";
424 tmp.appendChild(close);
425 sidebar.add_view("recommend", tmp, 20);
428 function recommend_open() {
429 sidebar_open("recommend");
430 sidebar.set_content(create_txt(LANG.WAIT_LOADING));
431 recommend_fetch_data();
434 function recommend_set_content(c) {
435 if(sidebar.open_view == "recommend")
436 sidebar.set_content(c);
439 function recommend_fetch_data() {
440 if(!playing.pl_size) {
441 recommend_set_content(LANG.RECOMMEND_EMPTY_PLAYLIST);
444 var http = new XMLHttpRequest()
445 http.open("GET", "metadata.php?plrecommend", true);
446 http.onreadystatechange = function() {
447 if(http.readyState==4) {
449 var result = http.responseXML.getElementsByTagName("result")[0];
450 if(!result || result.textContent=="failed" || !result.hasChildNodes()) {
451 recommend_set_content(create_txt(LANG.E_COMM_PROBLEM));
454 var exists = create_node("ul");
455 var others = create_node("ul");
456 exists.className = "recommended";
457 others.style.paddingLeft = "10px";
459 add_listener(exists, "click", recommend_toggle_open);
460 add_listener(exists, "mousedown", stop_event);
462 result = result.childNodes;
463 for(var i=0; i < result.length; i++) {
465 var artist = get_tag(a, "name");
466 var albums = a.getElementsByTagName( "album")[0];
468 if(albums&&albums.hasChildNodes()) {
469 var list = create_node("li", null, artist);
470 var slist = create_node("ul");
471 add_listener(slist, "click", recommend_add_to_playlist);
472 var node = albums.firstChild;
474 var tmp = create_node("li", null, node.textContent);
475 tmp.title = LANG.RECOMMEND_ADDTOPLAYLIST;
476 tmp.setAttribute("artist", artist);
477 slist.appendChild(tmp);
478 node = node.nextSibling;
480 list.appendChild(slist);
481 exists.appendChild(list);
484 var li = create_node("li", null, artist);
485 others.appendChild(li);
488 var tmp = create_fragment();
490 tmp.appendChild(create_txt(LANG.RECOMMEND_SIMILAR));
491 tmp.appendChild(exists);
493 tmp.appendChild(create_txt(LANG.RECOMMEND_ARTISTS));
494 tmp.appendChild(others);
495 recommend_set_content(tmp);
501 function recommend_toggle_open(e) {
502 if(e.target.parentNode.className != "recommended")
504 if(e.target.hasAttribute("open"))
505 e.target.removeAttribute("open");
506 else e.target.setAttribute("open", "k");
509 function recommend_add_to_playlist(e) {
510 if(!e.target.hasAttribute("artist"))
512 send_command("searchadd&artist=" + encodeURIComponent(e.target.getAttribute("artist")) +
513 "&album=" + encodeURIComponent(e.target.textContent), browser_add_cb, LANG.WAIT_ADDING);