collection.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. var initScanned = false;
  2. Collection={
  3. artists:[],
  4. albums:[],
  5. songs:[],
  6. artistsById:{},
  7. albumsById:{},
  8. loaded:false,
  9. loading:false,
  10. loadedListeners:[],
  11. load:function(ready){
  12. if(ready){
  13. Collection.loadedListeners.push(ready);
  14. }
  15. if(!Collection.loading){
  16. Collection.loading=true;
  17. Collection.artists=[];
  18. Collection.albums=[];
  19. Collection.songs=[];
  20. Collection.artistsById={};
  21. Collection.albumsById={};
  22. $.ajax({
  23. url: OC.linkTo('media','ajax/api.php')+'?action=get_collection',
  24. dataType: 'json',
  25. success: function(data){
  26. //normalize the data
  27. for(var i=0;i<data.artists.length;i++){
  28. var artist=data.artists[i];
  29. var artistData={name:artist.artist_name,songs:[],albums:[]};
  30. Collection.artistsById[artist.artist_id]=artistData;
  31. Collection.artists.push(artistData);
  32. }
  33. for(var i=0;i<data.albums.length;i++){
  34. var album=data.albums[i];
  35. if(Collection.artistsById[album.album_artist]){
  36. var artistName=Collection.artistsById[album.album_artist].name;
  37. }else{
  38. var artistName='unknown';
  39. }
  40. var albumData={name:album.album_name,artist:artistName,songs:[]};
  41. Collection.albumsById[album.album_id]=albumData;
  42. Collection.albums.push(albumData);
  43. if(Collection.artistsById[album.album_artist]){
  44. Collection.artistsById[album.album_artist].albums.push(albumData);
  45. }
  46. }
  47. for(var i=0;i<data.songs.length;i++){
  48. var song=data.songs[i];
  49. if(Collection.artistsById[song.song_artist] && Collection.albumsById[song.song_album]){
  50. var songData={
  51. name:song.song_name,
  52. artist:Collection.artistsById[song.song_artist].name,
  53. album:Collection.albumsById[song.song_album].name,
  54. lastPlayed:song.song_lastplayed,
  55. length:song.song_length,
  56. path:song.song_path,
  57. playCount:song.song_playcount,
  58. };
  59. Collection.songs.push(songData);
  60. Collection.artistsById[song.song_artist].songs.push(songData);
  61. Collection.albumsById[song.song_album].songs.push(songData);
  62. }
  63. }
  64. Collection.artists.sort(function(a,b){
  65. if(!a.name){
  66. return -1;
  67. }
  68. return a.name.localeCompare(b.name);
  69. });
  70. Collection.loaded=true;
  71. Collection.loading=false;
  72. for(var i=0;i<Collection.loadedListeners.length;i++){
  73. Collection.loadedListeners[i]();
  74. }
  75. if(data.songs.length==0 && initScanned == false){
  76. $('#scan input.start').click();
  77. initScanned = true;
  78. }
  79. }
  80. });
  81. }
  82. },
  83. display:function(){
  84. if(Collection.parent){
  85. Collection.parent.show();
  86. }
  87. if(!Collection.loaded){
  88. Collection.load(Collection.display);
  89. }else{
  90. if(Collection.parent){
  91. Collection.parent.find('tr:not(.template)').remove();
  92. var template=Collection.parent.find('tr.template');
  93. $.each(Collection.artists,function(i,artist){
  94. if(artist.name && artist.songs.length>0){
  95. var tr=template.clone().removeClass('template');
  96. if(artist.songs.length>1){
  97. tr.find('td.title a').html(artist.songs.length+' '+t('media','songs'));
  98. tr.find('td.album a').html(artist.albums.length+' '+t('media','albums'));
  99. }else{
  100. tr.find('td.title a').html(artist.songs[0].name);
  101. tr.find('td.album a').html(artist.albums[0].name);
  102. }
  103. tr.find('td.artist a').html(artist.name);
  104. tr.data('artistData',artist);
  105. tr.find('td.artist a').click(function(event){
  106. event.preventDefault();
  107. PlayList.add(artist);
  108. PlayList.play(0);
  109. Collection.parent.find('tr').removeClass('active');
  110. $('tr[data-artist="'+artist.name+'"]').addClass('active');
  111. });
  112. var expander='';
  113. if(artist.songs.length>1){
  114. expander=$('<a class="expander">&gt;</a>');
  115. expander.data('expanded',false);
  116. expander.click(function(event){
  117. var tr=$(this).parent().parent();
  118. if(expander.data('expanded')){
  119. Collection.hideArtist(tr.data('artist'));
  120. }else{
  121. Collection.showArtist(tr.data('artist'));
  122. }
  123. });
  124. }
  125. tr.find('td.artist').addClass('buttons');
  126. Collection.addButtons(tr,artist);
  127. tr.children('td.artist-expander').append(expander);
  128. tr.attr('data-artist',artist.name);
  129. Collection.parent.find('tbody').append(tr);
  130. }
  131. });
  132. }
  133. }
  134. },
  135. showArtist:function(artist){
  136. var tr=Collection.parent.find('tr[data-artist="'+artist+'"]');
  137. var lastRow=tr;
  138. var artist=tr.data('artistData');
  139. var first=true;
  140. $.each(artist.albums,function(j,album){
  141. $.each(album.songs,function(i,song){
  142. var newRow;
  143. if(first){
  144. newRow=tr;
  145. }else{
  146. newRow=tr.clone();
  147. newRow.find('td.artist').text('');
  148. newRow.find('.expander').remove();
  149. }
  150. newRow.find('td.album-expander .expander').remove();
  151. if(i==0){
  152. newRow.find('td.album a').text(album.name);
  153. newRow.find('td.album a').click(function(event){
  154. event.preventDefault();
  155. PlayList.add(album);
  156. PlayList.play(0);
  157. Collection.parent.find('tr').removeClass('active');
  158. $('tr[data-album="'+album.name+'"]').addClass('active');
  159. });
  160. if(album.songs.length>1){
  161. var expander=$('<a class="expander">v </a>');
  162. expander.data('expanded',true);
  163. expander.click(function(event){
  164. var tr=$(this).parent().parent();
  165. if(expander.data('expanded')) {
  166. Collection.hideAlbum(tr.data('artist'),tr.data('album'));
  167. } else {
  168. Collection.showAlbum(tr.data('artist'),tr.data('album'));
  169. }
  170. });
  171. newRow.children('td.album-expander').append(expander);
  172. }
  173. Collection.addButtons(newRow,album);
  174. } else {
  175. newRow.find('td.album a').text('');
  176. Collection.addButtons(newRow,song);
  177. }
  178. newRow.find('td.title a').text(song.name);
  179. newRow.find('td.title a').click(function(event){
  180. event.preventDefault();
  181. PlayList.add(song);
  182. PlayList.play(0);
  183. Collection.parent.find('tr').removeClass('active');
  184. $('tr[data-title="'+song.name+'"]').addClass('active');
  185. });
  186. newRow.attr('data-album',album.name);
  187. newRow.attr('data-title',song.name);
  188. newRow.attr('data-artist',artist.name);
  189. newRow.data('albumData',album);
  190. if(!first){
  191. lastRow.after(newRow);
  192. }
  193. first=false;
  194. lastRow=newRow;
  195. });
  196. });
  197. tr.removeClass('collapsed');
  198. tr.find('td.artist-expander a.expander').data('expanded',true);
  199. tr.find('td.artist-expander a.expander').addClass('expanded');
  200. tr.find('td.artist-expander a.expander').text('v');
  201. },
  202. hideArtist:function(artist){
  203. var tr=Collection.parent.find('tr[data-artist="'+artist+'"]');
  204. var artist=tr.first().data('artistData');
  205. tr.first().find('td.album a').first().text(artist.albums.length+' '+t('media','albums'));
  206. tr.first().find('td.album-expander a.expander').remove();
  207. tr.first().find('td.title a').text(artist.songs.length+' '+t('media','songs'));
  208. tr.first().find('td.album a').unbind('click');
  209. tr.first().find('td.title a').unbind('click');
  210. tr.each(function(i,row){
  211. if(i>0){
  212. $(row).remove();
  213. }
  214. });
  215. tr.find('td.artist-expander a.expander').data('expanded',false);
  216. tr.find('td.artist-expander a.expander').removeClass('expanded');
  217. tr.find('td.artist-expander a.expander').text('>');
  218. Collection.addButtons(tr,artist);
  219. },
  220. showAlbum:function(artist,album){
  221. var tr = Collection.parent.find('tr[data-artist="'+artist+'"][data-album="'+album+'"]');
  222. var lastRow=tr;
  223. var albumData=tr.data('albumData');
  224. tr.find('td.album-expander a.expander').data('expanded',true);
  225. tr.find('td.album-expander a.expander').addClass('expanded');
  226. tr.find('td.album-expander a.expander').text('v');
  227. $.each(albumData.songs,function(i,song){
  228. var newRow;
  229. if(i>0){
  230. newRow=tr.clone();
  231. newRow.find('a.expander').remove();
  232. newRow.find('td.album a').text('');
  233. newRow.find('td.artist a').text('');
  234. }else{
  235. newRow=tr;
  236. }
  237. newRow.find('td.title a').text(song.name);
  238. newRow.find('td.title a').click(function(event){
  239. event.preventDefault();
  240. PlayList.add(song);
  241. PlayList.play(0);
  242. Collection.parent.find('tr').removeClass('active');
  243. $('tr[data-title="'+song.name+'"]').addClass('active');
  244. });
  245. if(i>0){
  246. lastRow.after(newRow);
  247. }
  248. lastRow=newRow;
  249. });
  250. },
  251. hideAlbum:function(artist,album){
  252. var tr = Collection.parent.find('tr[data-artist="'+artist+'"][data-album="'+album+'"]');
  253. var albumData=tr.data('albumData');
  254. tr.first().find('td.title a').text(albumData.songs.length+' '+t('media','songs'));
  255. tr.find('td.album-expander a.expander').data('expanded',false);
  256. tr.find('td.album-expander a.expander').removeClass('expanded');
  257. tr.find('td.album-expander a.expander').text('> ');
  258. tr.each(function(i,row){
  259. if(i>0){
  260. $(row).remove();
  261. }
  262. });
  263. },
  264. parent:null,
  265. hide:function(){
  266. if(Collection.parent){
  267. Collection.parent.hide();
  268. }
  269. },
  270. registerPlay:function(item){
  271. if(item){
  272. var song=Collection.findSong(item.artist,item.album,item.name);
  273. song.song_playcount++;
  274. }
  275. },
  276. addButtons:function(parent,data){
  277. buttons = parent.find('.buttons');
  278. if(buttons.find('.add').length<=0) {
  279. buttons.prepend('<img class="add action" src="'+OC.imagePath('core','actions/play-add')+'" title="Add to playlist" />');
  280. }
  281. buttons.find('.add').unbind('click');
  282. buttons.find('.add').click(function(event){
  283. event.preventDefault();
  284. PlayList.add(data,true);
  285. PlayList.render();
  286. });
  287. },
  288. find:function(artistName,albumName,songName){
  289. if(songName){
  290. return Collection.findSong(artistName,albumName,songName);
  291. }else if(albumName){
  292. return Collection.findAlbum(artistName,albumName);
  293. }else{
  294. return Collection.findArtist(artistName);
  295. }
  296. },
  297. findArtist:function(name){
  298. for(var i=0;i<Collection.artists.length;i++){
  299. if(Collection.artists[i].name==name){
  300. return Collection.artists[i];
  301. }
  302. }
  303. },
  304. findAlbum:function(artistName,albumName){
  305. var artist=Collection.findArtist(artistName);
  306. if(artist){
  307. for(var i=0;i<artist.albums.length;i++){
  308. if(artist.albums[i].name==albumName){
  309. return artist.albums[i];
  310. }
  311. }
  312. }
  313. },
  314. findSong:function(artistName,albumName,songName){
  315. var album=Collection.findAlbum(artistName,albumName);
  316. if(album){
  317. for(var i=0;i<album.songs.length;i++){
  318. if(album.songs[i].name==songName){
  319. return album.songs[i];
  320. }
  321. }
  322. }
  323. },
  324. addSong:function(song){
  325. var artist=Collection.findArtist(song.artist);
  326. if(!artist){
  327. artist={name:song.artist,albums:[],songs:[]};
  328. Collection.artists.push(artist);
  329. Collection.artistsById[song.song_artist]=artist;
  330. }
  331. var album=Collection.findAlbum(song.artist,song.album);
  332. if(!album){
  333. album={name:song.album,artist:song.song_artist,songs:[]};
  334. artist.albums.push(album);
  335. Collection.albums.push(album);
  336. Collection.albumsById[song.song_album]=album;
  337. }
  338. var songData={
  339. name:song.song_name,
  340. artist:Collection.artistsById[song.song_artist].name,
  341. album:Collection.albumsById[song.song_album].name,
  342. lastPlayed:song.song_lastplayed,
  343. length:song.song_length,
  344. path:song.song_path,
  345. playCount:song.song_playcount,
  346. };
  347. album.songs.push(songData);
  348. artist.songs.push(songData);
  349. Collection.songs.push(songData);
  350. }
  351. };
  352. $(document).ready(function(){
  353. Collection.parent=$('#collection');
  354. Collection.load();
  355. Collection.parent.hide();
  356. $('#scan input.start').click(function(){
  357. $('#scan input.start').hide();
  358. $('#scan input.stop').show();
  359. $('#scan input.stop').click(function(){
  360. Scanner.toggle();
  361. });
  362. Scanner.scanCollection();
  363. });
  364. });