1.8 display changes, folder picker
BIN
images/download_gd_9x12.png
Normal file
After Width: | Height: | Size: 210 B |
BIN
images/download_gl_9x12.png
Normal file
After Width: | Height: | Size: 201 B |
BIN
images/hash_gd_14x16.png
Normal file
After Width: | Height: | Size: 224 B |
Before Width: | Height: | Size: 276 B After Width: | Height: | Size: 276 B |
BIN
images/layers_alt_gd_12x12.png
Normal file
After Width: | Height: | Size: 159 B |
BIN
images/layers_alt_gl_12x12.png
Normal file
After Width: | Height: | Size: 159 B |
BIN
images/list_gd_16x14.png
Normal file
After Width: | Height: | Size: 137 B |
Before Width: | Height: | Size: 298 B |
BIN
images/play_alt_gd_16x16.png
Normal file
After Width: | Height: | Size: 300 B |
BIN
images/star_lgo_12x12.png
Normal file
After Width: | Height: | Size: 393 B |
580
index.html
|
@ -7,6 +7,7 @@
|
|||
<link rel="icon" href="images/subsonic_32x32.png" sizes="32x32"/>
|
||||
<link href="style/Style.css" rel="stylesheet" type="text/css" />
|
||||
<link href="js/fancybox/jquery.fancybox-1.3.4.css" rel="stylesheet" type="text/css" />
|
||||
<link href="js/contextMenu/jquery.contextMenu.css" rel="stylesheet" type="text/css" />
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="js/audiojs/audio.min.js" type="text/javascript"></script>
|
||||
<script src="js/jquery.scrollTo-1.4.2-min.js" type="text/javascript"></script>
|
||||
|
@ -19,542 +20,9 @@
|
|||
<script src="js/fancybox/jquery.fancybox-1.3.4.pack.js" type="text/javascript"></script>
|
||||
<script src="js/jquery.linkify-1.0-min.js" type="text/javascript"></script>
|
||||
<script src="js/app.js" type="text/javascript"></script>
|
||||
<script src="js/ui-load.js" type="text/javascript"></script>
|
||||
<script src="js/ui-ready.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
// Tabs
|
||||
$(".tabcontent").hide(); //Hide all content
|
||||
if ($.cookie('username') == null) {
|
||||
$('ul.tabs li a').each(function () {
|
||||
if ($(this).attr("href") == '#tabPreferences') {
|
||||
$(this).addClass("active"); //Add "active" class to selected tab
|
||||
}
|
||||
});
|
||||
$("#tabPreferences").show(); //Show first tab content
|
||||
loadTabContent('#tabPreferences');
|
||||
} else {
|
||||
if (window.location.hash) {
|
||||
var hash = window.location.hash;
|
||||
$('ul.tabs li a').each(function () {
|
||||
if ($(this).attr("href") == hash) {
|
||||
$(this).addClass("active"); //Add "active" class to selected tab
|
||||
}
|
||||
});
|
||||
$(hash).show(); //Fade in the active ID content
|
||||
loadTabContent(hash);
|
||||
} else {
|
||||
$("ul.tabs li:first a").addClass("active").show(); //Activate first tab
|
||||
$(".tabcontent:first").show(); //Show first tab content
|
||||
var firstTab = $("ul.tabs li:first a").attr("href");
|
||||
loadTabContent(firstTab);
|
||||
}
|
||||
}
|
||||
|
||||
// Tabs - Click Event
|
||||
$("ul.tabs li a").click(function () {
|
||||
$("ul.tabs li a").removeClass("active"); //Remove any "active" class
|
||||
$(this).addClass("active"); //Add "active" class to selected tab
|
||||
$(".tabcontent").hide(); //Hide all tab content
|
||||
|
||||
var activeTab = $(this).attr("href"); //Find the href attribute value to identify the active tab + content
|
||||
$(activeTab).show(); //Fade in the active ID content
|
||||
loadTabContent(activeTab);
|
||||
});
|
||||
|
||||
// Ajax Loading Screen
|
||||
$(".toploading").ajaxStart(function () {
|
||||
$(this).show();
|
||||
});
|
||||
$(".toploading").ajaxStop(function () {
|
||||
$(this).hide();
|
||||
});
|
||||
|
||||
// Keyboard shortcuts
|
||||
$(document).keydown(function (e) {
|
||||
var source = e.target.id;
|
||||
if (source != 'Search' && source != 'ChatMsg') {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
// a-z
|
||||
if (unicode >= 65 && unicode <= 90) {
|
||||
var key = findKeyForCode(unicode);
|
||||
var el = '#index_' + key.toUpperCase();
|
||||
$('#Artists').stop().scrollTo(el, 400);
|
||||
// right arrow
|
||||
} else if (unicode == 39 || unicode == 176) {
|
||||
var next = $('ul.songlist li.playing').next();
|
||||
if (!next.length) next = $('ul.songlist li').first();
|
||||
changeTrack(next);
|
||||
// back arrow
|
||||
} else if (unicode == 37 || unicode == 177) {
|
||||
var prev = $('ul.songlist li.playing').prev();
|
||||
if (!prev.length) prev = $('ul.songlist li').last();
|
||||
changeTrack(prev);
|
||||
// spacebar
|
||||
} else if (unicode == 32 || unicode == 179 || unicode == 0179) {
|
||||
playPauseSong();
|
||||
} else if (unicode == 36) {
|
||||
$('#Artists').stop().scrollTo('#auto', 400);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Main Click Events
|
||||
// Albums Click Event
|
||||
$('#ArtistContainer li.item').live('click', function () {
|
||||
$('#AutoAlbumContainer li').removeClass('selected');
|
||||
$('#ArtistContainer li').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
getAlbums($(this).attr("id"), '', '#AlbumRows');
|
||||
});
|
||||
$('#BottomIndex li a').live('click', function () {
|
||||
var el = '#index_' + $(this).text();
|
||||
$('#Artists').stop().scrollTo(el, 400);
|
||||
return false;
|
||||
});
|
||||
$('#AutoAlbumContainer li.item').live('click', function () {
|
||||
$('#AutoAlbumContainer li').removeClass('selected');
|
||||
$('#ArtistContainer li').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
getAlbumListBy($(this).attr("id"));
|
||||
});
|
||||
$('tr.album a.play').live('click', function (e) {
|
||||
var albumid = $(this).parent().parent().attr('childid');
|
||||
var artistid = $(this).parent().parent().attr('parentid');
|
||||
getAlbums(albumid, 'autoplay', '#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('tr.album a.add').live('click', function (e) {
|
||||
var albumid = $(this).parent().parent().attr('childid');
|
||||
var artistid = $(this).parent().parent().attr('parentid');
|
||||
getAlbums(albumid, 'add', '#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('tr.album a.rate').live('click', function (event) {
|
||||
var itemid = $(this).parent().parent().attr('childid');
|
||||
rateSong(itemid, 5);
|
||||
return false;
|
||||
});
|
||||
$('tr.album a.favorite').live('click', function (event) {
|
||||
var itemid = $(this).parent().parent().attr('childid');
|
||||
rateSong(itemid, 0);
|
||||
return false;
|
||||
});
|
||||
$('tr.album').live('click', function (e) {
|
||||
var albumid = $(this).attr('childid');
|
||||
var artistid = $(this).attr('parentid');
|
||||
getAlbums(albumid, '', '#AlbumRows');
|
||||
return false;
|
||||
});
|
||||
// Track - Click Events
|
||||
// Multiple Select
|
||||
$('.noselect').disableTextSelect();
|
||||
var lastChecked = null;
|
||||
$('table.songlist tr.song').live('click', function (event) {
|
||||
var checkboxclass = 'table.songlist tr.song';
|
||||
var songid = $(this).attr('childid');
|
||||
var albumid = $(this).attr('parentid');
|
||||
if (!event.ctrlKey) {
|
||||
$(checkboxclass).removeClass('selected');
|
||||
}
|
||||
if ($(this).hasClass('selected')) {
|
||||
$(this).removeClass('selected');
|
||||
} else {
|
||||
$(this).addClass('selected');
|
||||
}
|
||||
if (!lastChecked) {
|
||||
lastChecked = this;
|
||||
return;
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
var start = $(checkboxclass).index(this);
|
||||
var end = $(checkboxclass).index(lastChecked);
|
||||
for (i = Math.min(start, end); i <= Math.max(start, end); i++) {
|
||||
$(checkboxclass).eq(i).addClass('selected');
|
||||
}
|
||||
}
|
||||
lastChecked = this;
|
||||
});
|
||||
// Double Click
|
||||
$('table.songlist tr.song').live('dblclick', function (e) {
|
||||
e.preventDefault();
|
||||
//$(this).addClass('playing').siblings().removeClass('playing');
|
||||
var songid = $(this).attr('childid');
|
||||
var albumid = $(this).attr('parentid');
|
||||
playSong('', this, songid, albumid);
|
||||
});
|
||||
$('table.songlist tr.song a.play').live('click', function (event) {
|
||||
var songid = $(this).parent().parent().attr('childid');
|
||||
var albumid = $(this).parent().parent().attr('parentid');
|
||||
playSong($(this).parent().parent(), songid, albumid);
|
||||
return false;
|
||||
});
|
||||
$('table.songlist tr.song a.add').live('click', function (event) {
|
||||
var track = $(this).parent().parent();
|
||||
$(track).clone().appendTo('#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('table.songlist tr.song a.remove').live('click', function (event) {
|
||||
var track = $(this).parent().parent();
|
||||
$(track).remove();
|
||||
refreshRowColor();
|
||||
return false;
|
||||
});
|
||||
$('table.songlist tr.song a.rate').live('click', function (event) {
|
||||
var songid = $(this).parent().parent().attr('childid');
|
||||
rateSong(songid, 5);
|
||||
return false;
|
||||
});
|
||||
$('table.songlist tr.song a.favorite').live('click', function (event) {
|
||||
var songid = $(this).parent().parent().attr('childid');
|
||||
rateSong(songid, 0);
|
||||
return false;
|
||||
});
|
||||
$('li.index').live('click', function (e) {
|
||||
$('#Artists').stop().scrollTo('#auto', 400);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Music Library Click Events
|
||||
$('a#action_AddToPlaylist').click(function () {
|
||||
var submenu = $('div#submenu_AddToPlaylist');
|
||||
if (submenu.is(":visible")) {
|
||||
submenu.fadeOut();
|
||||
} else {
|
||||
loadPlaylistsForMenu('submenu_AddToPlaylist');
|
||||
//get the position of the placeholder element
|
||||
pos = $(this).offset();
|
||||
width = $(this).width();
|
||||
height = $(this).height();
|
||||
//show the menu directly over the placeholder
|
||||
submenu.css({ "left": (pos.left) + "px", "top": (pos.top + height + 14) + "px" }).fadeIn(400);
|
||||
}
|
||||
});
|
||||
var submenu_active = false;
|
||||
$('div.submenu').mouseenter(function () {
|
||||
submenu_active = true;
|
||||
});
|
||||
$('div.submenu').mouseleave(function () {
|
||||
submenu_active = false;
|
||||
setTimeout(function () { if (submenu_active == false) $('div.submenu').fadeOut(); }, 400);
|
||||
});
|
||||
$('a#action_AddToCurrent').click(function () {
|
||||
addToCurrent();
|
||||
});
|
||||
$('#action_RefreshArtists').click(function () {
|
||||
loadArtists(true);
|
||||
return false;
|
||||
});
|
||||
$('#action_IncreaseWidth').click(function () {
|
||||
resizeSMSection(50);
|
||||
return false;
|
||||
});
|
||||
$('#action_DecreaseWidth').click(function () {
|
||||
resizeSMSection(-50);
|
||||
return false;
|
||||
});
|
||||
$('#action_SelectAll').click(function () {
|
||||
$('#Albums tr.song').each(function () {
|
||||
$(this).addClass('selected');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('#action_SelectNone').click(function () {
|
||||
$('#Albums tr.song').each(function () {
|
||||
$(this).removeClass('selected');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('input#Search').keydown(function (e) {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
if (unicode == 13) {
|
||||
$('#action_Search').click();
|
||||
}
|
||||
});
|
||||
$('#action_Search').click(function () {
|
||||
var query = $('#Search').val();
|
||||
search('song', query);
|
||||
$('#Search').val("");
|
||||
return false;
|
||||
});
|
||||
// Current Playlist Click Events
|
||||
$('#action_Shuffle').live('click', function () {
|
||||
$('#CurrentPlaylistContainer tr.song').shuffle();
|
||||
refreshRowColor();
|
||||
return false;
|
||||
});
|
||||
$('#action_Empty').live('click', function () {
|
||||
$('#CurrentPlaylistContainer tbody').empty();
|
||||
return false;
|
||||
});
|
||||
$('a#action_AddCurrentToPlaylist').click(function () {
|
||||
var submenu = $('div#submenu_AddCurrentToPlaylist');
|
||||
if (submenu.is(":visible")) {
|
||||
submenu.fadeOut();
|
||||
} else {
|
||||
loadPlaylistsForMenu('submenu_AddCurrentToPlaylist');
|
||||
//get the position of the placeholder element
|
||||
pos = $(this).offset();
|
||||
width = $(this).width();
|
||||
height = $(this).height();
|
||||
//show the menu directly over the placeholder
|
||||
submenu.css({ "left": (pos.left) + "px", "top": (pos.top + height + 14) + "px" }).fadeIn(400);
|
||||
}
|
||||
});
|
||||
$('#action_CurrentSelectAll').click(function () {
|
||||
$('#CurrentPlaylist tr.song').each(function () {
|
||||
$(this).addClass('selected');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('#action_CurrentSelectNone').click(function () {
|
||||
$('#CurrentPlaylist tr.song').each(function () {
|
||||
$(this).removeClass('selected');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
// Playlist Click Events
|
||||
$('#AutoPlaylistContainer li.item').live('click', function () {
|
||||
$('#AutoPlaylistContainer li').removeClass('selected');
|
||||
$('#PlaylistContainer li').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
getRandomSongList('', '#TrackContainer');
|
||||
});
|
||||
$('#AutoPlaylistContainer li.item a.play').live('click', function () {
|
||||
getRandomSongList('autoplay', '#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('#AutoPlaylistContainer li.item a.add').live('click', function () {
|
||||
getRandomSongList('', '#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('#PlaylistContainer li.item').live('click', function () {
|
||||
$('#AutoPlaylistContainer li').removeClass('selected');
|
||||
$('#PlaylistContainer li').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
getPlaylist($(this).attr("id"), '', '#TrackContainer tbody');
|
||||
});
|
||||
$('#PlaylistContainer li.item a.play').live('click', function () {
|
||||
getPlaylist($(this).parent().parent().attr("id"), 'autoplay', '#CurrentPlaylistContainer tbody');
|
||||
return false;
|
||||
});
|
||||
$('#PlaylistContainer li.item a.add').live('click', function () {
|
||||
getPlaylist($(this).parent().parent().attr("id"), '', '#CurrentPlaylistContainer tbody');
|
||||
return false;
|
||||
});
|
||||
$('#action_DeletePlaylist').click(function () {
|
||||
if ($('#PlaylistContainer li.selected').length > 0) {
|
||||
if (confirmDelete()) {
|
||||
$('#PlaylistContainer li.selected').each(function () {
|
||||
deletePlaylist($(this).attr("id"));
|
||||
});
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#action_SavePlaylist').click(function () {
|
||||
if ($('#PlaylistContainer li.selected').length > 0) {
|
||||
$('#PlaylistContainer li.selected').each(function () {
|
||||
savePlaylist($(this).attr("id"));
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#action_RemoveSongs').click(function () {
|
||||
if ($('#TrackContainer tr.selected').length > 0) {
|
||||
$('#TrackContainer tr.selected').each(function () {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#action_ShufflePlaylist').live('click', function () {
|
||||
$('#TrackContainer tr.song').shuffle();
|
||||
refreshRowColor();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Player Click Events
|
||||
$('#PlayTrack').live('click', function () {
|
||||
playPauseSong();
|
||||
return false;
|
||||
});
|
||||
$('#NextTrack').live('click', function () {
|
||||
var next = $('#CurrentPlaylistContainer tr.playing').next();
|
||||
changeTrack(next);
|
||||
return false;
|
||||
});
|
||||
$('#PreviousTrack').live('click', function () {
|
||||
var prev = $('#CurrentPlaylistContainer tr.playing').prev();
|
||||
changeTrack(prev);
|
||||
return false;
|
||||
});
|
||||
$("a#coverartimage").fancybox({
|
||||
'hideOnContentClick': true,
|
||||
'type': 'image'
|
||||
});
|
||||
|
||||
// Side Bar Click Events
|
||||
$('#action_ToggleSideBar').live('click', function () {
|
||||
if ($.cookie('sidebar')) {
|
||||
$.cookie('sidebar', null);
|
||||
$('#SideBar').hide();
|
||||
stopUpdateChatMessages();
|
||||
stopUpdateNowPlaying();
|
||||
} else {
|
||||
$.cookie('sidebar', true, { expires: 365 });
|
||||
$('#SideBar').show();
|
||||
updateChatMessages();
|
||||
updateNowPlaying();
|
||||
}
|
||||
resizeContent();
|
||||
return false;
|
||||
});
|
||||
$('input#ChatMsg').keydown(function (e) {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
if (unicode == 13) {
|
||||
var msg = $('#ChatMsg').val();
|
||||
if (msg != '') {
|
||||
addChatMessage(msg);
|
||||
}
|
||||
$('#ChatMsg').val("");
|
||||
}
|
||||
});
|
||||
|
||||
// Preferences Click Events
|
||||
$('#SavePreferences').live('click', function () {
|
||||
var username = $('#Username').val();
|
||||
var password = $('#Password').val();
|
||||
$.cookie('username', username, { expires: 365 });
|
||||
$.cookie('password', password, { expires: 365 });
|
||||
var AutoAlbumSize = $('#AutoAlbumSize').val();
|
||||
var AutoPlaylistSize = $('#AutoPlaylistSize').val();
|
||||
$.cookie('AutoAlbumSize', AutoAlbumSize, { expires: 365 });
|
||||
$.cookie('AutoPlaylistSize', AutoPlaylistSize, { expires: 365 });
|
||||
var server = $('#Server').val();
|
||||
if (server != "") {
|
||||
$.cookie('Server', server, { expires: 365 });
|
||||
}
|
||||
var applicationname = $('#ApplicationName').val();
|
||||
if (applicationname != "") {
|
||||
$.cookie('ApplicationName', applicationname, { expires: 365 });
|
||||
}
|
||||
location.reload(true);
|
||||
});
|
||||
$('#HideAZ').live('click', function () {
|
||||
if ($('#HideAZ').is(':checked')) {
|
||||
$.cookie('HideAZ', '1', { expires: 365 });
|
||||
$('#BottomContainer').hide();
|
||||
}
|
||||
});
|
||||
$('#EnableNotifications').live('click', function () {
|
||||
if ($('#EnableNotifications').is(':checked')) {
|
||||
requestPermissionIfRequired();
|
||||
if (hasNotificationPermission()) {
|
||||
$.cookie('EnableNotifications', '1', { expires: 365 });
|
||||
}
|
||||
} else {
|
||||
$.cookie('EnableNotifications', null);
|
||||
}
|
||||
});
|
||||
$('#ScrollTitle').live('click', function () {
|
||||
if ($('#ScrollTitle').is(':checked')) {
|
||||
$.cookie('ScrollTitle', '1', { expires: 365 });
|
||||
}
|
||||
});
|
||||
$('input#Password').keydown(function (e) {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
if (unicode == 13) {
|
||||
$('#SavePreferences').click();
|
||||
}
|
||||
});
|
||||
$('#ResetPreferences').live('click', function () {
|
||||
$.cookie('username', null);
|
||||
$.cookie('password', null);
|
||||
$.cookie('AutoAlbumSize', null);
|
||||
$.cookie('AutoPlaylistSize', null);
|
||||
$.cookie('Server', null);
|
||||
$.cookie('ApplicationName', null);
|
||||
$.cookie('HideAZ', null);
|
||||
location.reload(true);
|
||||
});
|
||||
$('#ChangeLogShowMore').live('click', function () {
|
||||
$('ul#ChangeLog li.log').each(function (i, el) {
|
||||
$(el).show();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
}); // End document.ready
|
||||
|
||||
$(window).load(function () {
|
||||
if ($.cookie('defaultsmwidth')) {
|
||||
var width = $.cookie('defaultsmwidth');
|
||||
$('.smsection').css({ 'width': width + 'px' });
|
||||
$('#MainActions').css({ 'width': (width - 5) + 'px' });
|
||||
$('#BottomContainer').css({ 'width': (width - 16) + 'px' });
|
||||
var ulwidth = parseInt(width) + 6;
|
||||
$('#AlbumContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
$('#TrackContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
}
|
||||
if ($.cookie('sidebar') && $.cookie('username') && $.cookie('password')) {
|
||||
$('#SideBar').show();
|
||||
updateChatMessages();
|
||||
updateNowPlaying();
|
||||
}
|
||||
if ($.cookie('HideAZ')) {
|
||||
$('#BottomContainer').hide();
|
||||
}
|
||||
$('ul#ChangeLog li.log').each(function (i, el) {
|
||||
if (i > 3) {
|
||||
$(el).hide();
|
||||
}
|
||||
});
|
||||
resizeContent();
|
||||
});
|
||||
window.onbeforeunload = function() {
|
||||
closeAllNotifications();
|
||||
};
|
||||
$(window).resize(function () {
|
||||
resizeContent();
|
||||
});
|
||||
function resizeContent() {
|
||||
var screenwidth = $(window).width();
|
||||
$('.tabcontent').css({ 'height': (($(window).height() - 152)) + 'px' });
|
||||
$('.smsection').css({ 'height': (($(window).height() - 192)) + 'px' });
|
||||
var smheight = $('.smsection').height();
|
||||
var smwidth = $('.smsection').width();
|
||||
$('#BottomContainer').css({ 'top': smheight + 75 + 'px' });
|
||||
if ($.cookie('sidebar')) {
|
||||
var tabwidth = $(window).width() - 218;
|
||||
if (tabwidth >= 700) {
|
||||
$('.tabcontent').css({ 'width': tabwidth + 'px' });
|
||||
}
|
||||
var sbheight = $(window).height() - 152;
|
||||
$('#SideBar').css({ 'height': sbheight + 'px' });
|
||||
$('#ChatMsgs').css({ 'height': (sbheight - 270) + 'px' });
|
||||
} else {
|
||||
var tabwidth = $(window).width() - 11;
|
||||
if (tabwidth >= 700) {
|
||||
$('.tabcontent').css({ 'width': tabwidth + 'px' });
|
||||
}
|
||||
}
|
||||
var tabwidth = $('.tabcontent').width();
|
||||
$('#AlbumContainer, #TrackContainer, #CurrentPlaylistContainer').css({ 'width': (tabwidth - smwidth - 30) + 'px' });
|
||||
$('#CurrentPlaylistContainer').css({ 'width': (tabwidth - 30) + 'px' });
|
||||
}
|
||||
function resizeSMSection(x) {
|
||||
var smwidth = $('.smsection').width();
|
||||
var newsmwidth = smwidth + x;
|
||||
if (newsmwidth > 150 && newsmwidth < 500) {
|
||||
$('.smsection').css({ 'width': (newsmwidth) + 'px' });
|
||||
$('#MainActions').css({ 'width': (newsmwidth - 5) + 'px' });
|
||||
$('#BottomContainer').css({ 'width': (newsmwidth - 16) + 'px' });
|
||||
$.cookie('defaultsmwidth', newsmwidth, { expires: 365, path: '/' });
|
||||
var ulwidth = newsmwidth + 6;
|
||||
$('#AlbumContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
$('#TrackContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
}
|
||||
}
|
||||
|
||||
var a;
|
||||
var audio;
|
||||
audiojs.events.ready(function () {
|
||||
|
@ -598,24 +66,24 @@
|
|||
<body>
|
||||
|
||||
<div id="container">
|
||||
<div id="messages">This is a test!</div>
|
||||
<div id="nav">
|
||||
<ul class="tabs">
|
||||
<li><a href="#tabLibrary">Music Library</a></li>
|
||||
<li><a href="#tabCurrent">Current Playlist</a></li>
|
||||
<li><a href="#tabPlaylists">Playlists</a></li>
|
||||
<li><a href="#tabLibrary" class="first" title="Library"><img src="images/headphones_gd_16x14.png" /></a></li>
|
||||
<li><a href="#tabCurrent" title="Current Playlist"><img src="images/play_alt_gd_16x16.png" /></a></li>
|
||||
<li><a href="#tabPlaylists" title="Playlists"><img src="images/list_gd_16x14.png" /></a></li>
|
||||
<li><a href="#tabPreferences" class="last" title="Preferences"><img src="images/cog_16x16.png" /></a></li>
|
||||
</ul>
|
||||
<div class="toploading"></div>
|
||||
<div id="messages"></div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="tabLibrary" class="tabcontent">
|
||||
<div id="MainActions" class="actions floatleft">
|
||||
<div class="actions floatleft">
|
||||
<a href="#" class="button" id="action_RefreshArtists" title="Refresh Artist List"><img src="images/reload_9x11.png" /></a>
|
||||
<a href="#" class="button" id="action_DecreaseWidth" title="Decrease Width"><img src="images/minus_8x2.png" /></a>
|
||||
<a href="#" class="button" id="action_IncreaseWidth" title="Increase Width"><img src="images/plus_8x8.png" /></a>
|
||||
</div>
|
||||
<div class="actions floatleft">
|
||||
<div class="subactions floatleft">
|
||||
<a href="#" class="button" id="action_AddToPlaylist" title="Add Selected To Playlist">+ Playlist</a>
|
||||
<div id="submenu_AddToPlaylist" class="submenu shadow" style="display: none;"></div>
|
||||
<a href="#" class="button" id="action_AddToCurrent" title="Add Selected To Current Playlist">+ Current</a>
|
||||
|
@ -623,11 +91,14 @@
|
|||
<a href="#" class="button" id="action_SelectNone" title="Select None">None</a>
|
||||
<input type="text" id="Search" class="medium" /><a href="#" class="button" id="action_Search" title="Search"><img src="images/magnifying_glass_alt_12x12.png" /></a>
|
||||
</div>
|
||||
<div id="Albums" class="lgsection floatleft noselect">
|
||||
<div id="Albums" class="lgsection floatleft">
|
||||
<div class="loading"></div>
|
||||
<div id="Artists" class="smsection floatleft noselect" tabindex="0">
|
||||
<div id="Artists" class="smsection floatleft" tabindex="0">
|
||||
<div class="padder">
|
||||
<ul id="AutoAlbumContainer" class="simplelist mainlist">
|
||||
<select id="MusicFolders">
|
||||
<option value="All Folders">All Folders</option>
|
||||
</select>
|
||||
<ul id="AutoAlbumContainer" class="simplelist mainlist noselect">
|
||||
<li class="index" id="auto">Auto Albums</li>
|
||||
<li class="item" id="newest"><span>Recently Added</span></li>
|
||||
<li class="item" id="random"><span>Random</span></li>
|
||||
|
@ -635,20 +106,23 @@
|
|||
<li class="item" id="recent"><span>Recently Played</span></li>
|
||||
<li class="item" id="frequent"><span>Most Played</span></li>
|
||||
</ul>
|
||||
<ul id="ArtistContainer" class="simplelist mainlist"></ul>
|
||||
<ul id="ArtistContainer" class="simplelist mainlist noselect"></ul>
|
||||
</div>
|
||||
<div id="BottomContainer"><ul id="BottomIndex"></ul></div>
|
||||
</div>
|
||||
<table id="AlbumContainer" class="simplelist songlist" cellspacing="1">
|
||||
<table id="AlbumContainer" class="simplelist songlist noselect" cellspacing="1">
|
||||
<thead id="AlbumHeader"></thead>
|
||||
<tbody id="AlbumRows"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="tabCurrent" class="tabcontent">
|
||||
<div class="actions floatleft">
|
||||
<a href="#" class="button" id="action_Shuffle" title="Shuffle"><img src="images/fork_11x12.png" /></a>
|
||||
<a href="#" class="button" id="action_Empty" title="Remove All">Empty</a>
|
||||
</div>
|
||||
<div class="subactions floatleft">
|
||||
<a href="#" class="button" id="action_CurrentSelectAll" title="Select All">All</a>
|
||||
<a href="#" class="button" id="action_CurrentSelectNone" title="Select None">None</a>
|
||||
<a href="#" class="button" id="action_AddCurrentToPlaylist" title="Add Selected To Playlist">+ Playlist</a>
|
||||
|
@ -666,6 +140,8 @@
|
|||
<a href="#" class="button" id="action_NewPlaylist" onclick="newPlaylist(); return false;" title="New Playlist">+ New</a>
|
||||
<a href="#" class="button" id="action_DeletePlaylist" title="Delete Playlist">Delete</a>
|
||||
<a href="#" class="button" id="action_SavePlaylist" title="Save Playlist">Save</a>
|
||||
</div>
|
||||
<div class="subactions floatleft">
|
||||
<a href="#" class="button" id="action_ShufflePlaylist" title="Shuffle Playlist"><img src="images/fork_11x12.png" /></a>
|
||||
<a href="#" class="button" id="action_RemoveSongs" title="Remove selected song(s) from playlist">Remove Song(s)</a>
|
||||
</div>
|
||||
|
@ -766,7 +242,17 @@
|
|||
<div class="subsection floatleft">
|
||||
<h3 class="title">Change Log</h3>
|
||||
<ul id="ChangeLog" class="preferences">
|
||||
<!--<li class="log">- </li>-->
|
||||
<!--
|
||||
<li class="log"><span class="version"></span>
|
||||
<span class="changes"></span>
|
||||
</li>
|
||||
-->
|
||||
<li class="log"><span class="version">Current - 1.8</span>
|
||||
<span class="changes">Added Download link to Albums</span>
|
||||
<span class="changes">Fixed bug with Next/Previous keyboard shortcuts</span>
|
||||
<span class="changes">Moved navigation since most displays are widescreen</span>
|
||||
<span class="changes">Added folder picker, choice will be saved in cookie</span>
|
||||
</li>
|
||||
<li class="log"><span class="version">3/9/2012 - 1.7</span>
|
||||
<span class="changes">- Ability to hide A-Z bar on Artists list</span>
|
||||
<span class="changes">- Desktop Notifications on browsers that support <span class="code">webkitNotifications</span></span>
|
||||
|
|
114
js/app.js
|
@ -19,7 +19,12 @@ var version = '1.7.0';
|
|||
function loadTabContent(tab) {
|
||||
switch (tab) {
|
||||
case '#tabLibrary':
|
||||
if ($.cookie('MusicFolders')) {
|
||||
loadArtists($.cookie('MusicFolders'), false);
|
||||
} else {
|
||||
loadArtists();
|
||||
}
|
||||
getMusicFolders();
|
||||
break;
|
||||
case '#tabCurrent':
|
||||
var header = generateSongHeaderHTML();
|
||||
|
@ -35,22 +40,39 @@ function loadTabContent(tab) {
|
|||
}
|
||||
}
|
||||
|
||||
function loadArtists(refresh) {
|
||||
function loadArtists(id, refresh) {
|
||||
if (refresh) {
|
||||
$('#ArtistContainer').empty();
|
||||
}
|
||||
var url;
|
||||
if (id == "all") {
|
||||
url = baseURL + '/getIndexes.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp';
|
||||
} else if (id) {
|
||||
url = baseURL + '/getIndexes.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&musicFolderId=' + id;
|
||||
} else {
|
||||
url = baseURL + '/getIndexes.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp';
|
||||
}
|
||||
var content = $('#ArtistContainer').html();
|
||||
if (content === "") {
|
||||
// Load Artist List
|
||||
$.ajax({
|
||||
url: baseURL + '/getIndexes.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp',
|
||||
url: url,
|
||||
method: 'GET',
|
||||
dataType: 'jsonp',
|
||||
timeout: 10000,
|
||||
success: function (data) {
|
||||
if (data["subsonic-response"].status === 'ok') {
|
||||
var indexlist, indexname;
|
||||
$.each(data["subsonic-response"].indexes.index, function (i, index) {
|
||||
|
||||
// There is a bug in the API that doesn't return a JSON array for one artist
|
||||
var indexes = [];
|
||||
if (data["subsonic-response"].indexes.index.length > 0) {
|
||||
indexes = data["subsonic-response"].indexes.index;
|
||||
} else {
|
||||
indexes[0] = data["subsonic-response"].indexes.index;
|
||||
}
|
||||
|
||||
$.each(indexes, function (i, index) {
|
||||
if (index.name === '#') {
|
||||
indexname = '0-9';
|
||||
} else {
|
||||
|
@ -89,6 +111,41 @@ function loadArtists(refresh) {
|
|||
});
|
||||
}
|
||||
}
|
||||
function getMusicFolders() {
|
||||
$.ajax({
|
||||
url: baseURL + '/getMusicFolders.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp',
|
||||
method: 'GET',
|
||||
dataType: 'jsonp',
|
||||
timeout: 10000,
|
||||
beforeSend: function (req) {
|
||||
req.setRequestHeader('Authorization', auth);
|
||||
},
|
||||
success: function (data) {
|
||||
if (data["subsonic-response"].musicFolders.musicFolder !== undefined) {
|
||||
// There is a bug in the API that doesn't return a JSON array for one artist
|
||||
var folders = [];
|
||||
if (data["subsonic-response"].musicFolders.musicFolder.length > 0) {
|
||||
folders = data["subsonic-response"].musicFolders.musicFolder;
|
||||
} else {
|
||||
folders[0] = data["subsonic-response"].musicFolders.musicFolder;
|
||||
}
|
||||
|
||||
var savedMusicFolder = $.cookie('MusicFolders');
|
||||
var options = [];
|
||||
options.push('<option value="all">All Folders</option>');
|
||||
$.each(folders, function (i, folder) {
|
||||
if (savedMusicFolder == folder.id) {
|
||||
options.push('<option value="' + folder.id + '" selected>' + folder.name + '</option>');
|
||||
} else {
|
||||
options.push('<option value="' + folder.id + '">' + folder.name + '</option>');
|
||||
}
|
||||
});
|
||||
$('#MusicFolders').html(options.join(''));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function getAlbums(id, action, appendto) {
|
||||
$.ajax({
|
||||
url: baseURL + '/getMusicDirectory.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id,
|
||||
|
@ -135,6 +192,9 @@ function getAlbums(id, action, appendto) {
|
|||
}
|
||||
$(albumhtml).appendTo(appendto);
|
||||
});
|
||||
if (appendto === '#CurrentPlaylistContainer') {
|
||||
updateMessage(children.length + ' Song(s) Added');
|
||||
}
|
||||
if (appendto === '#AlbumRows' && isDir === true) {
|
||||
header = generateAlbumHeaderHTML();
|
||||
}
|
||||
|
@ -243,6 +303,9 @@ function getRandomSongList(action, appendto) {
|
|||
html = generateSongHTML(rowcolor, item.id, item.parent, track, item.title, item.artist, item.album, item.coverArt, item.userRating, time['m'], time['s']);
|
||||
$(html).appendTo(appendto);
|
||||
});
|
||||
if (appendto === '#CurrentPlaylistContainer') {
|
||||
updateMessage(items.length + ' Song(s) Added');
|
||||
}
|
||||
if (action === 'autoplay') {
|
||||
autoPlay();
|
||||
}
|
||||
|
@ -262,6 +325,7 @@ function generateAlbumHTML(rowcolor, childid, parentid, coverart, title, artist,
|
|||
html = '<tr class=\"album ' + rowcolor + '\" childid=\"' + childid + '\" parentid=\"' + parentid + '\" userrating=\"' + rating + '\">';
|
||||
html += '<td class=\"itemactions\"><a class=\"add\" href=\"\" title=\"Add To Current Playlist\"></a>';
|
||||
html += '<a class=\"play\" href=\"\" title=\"Play\"></a>';
|
||||
html += '<a class=\"download\" href=\"\" title=\"Download\"></a>';
|
||||
if (rating === 5) {
|
||||
html += '<a class=\"favorite\" href=\"\" title=\"Favorite\"></a>';
|
||||
} else {
|
||||
|
@ -358,9 +422,9 @@ function playSong(el, songid, albumid) {
|
|||
}
|
||||
if ($.cookie('ScrollTitle')) {
|
||||
//clearTimeout(timer);
|
||||
scrollTitle(artist + ' - ' + title);
|
||||
scrollTitle(toHTML.un(artist) + ' - ' + toHTML.un(title));
|
||||
} else {
|
||||
setTitle(artist + ' - ' + title);
|
||||
setTitle(toHTML.un(artist) + ' - ' + toHTML.un(title));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -781,11 +845,29 @@ function addToPlaylist(playlistid, from) {
|
|||
}
|
||||
}
|
||||
function addToCurrent() {
|
||||
var count = $('table.songlist tr.selected').length;
|
||||
$('table.songlist tr.selected').each(function (index) {
|
||||
var count = $('#AlbumContainer tr.selected').length;
|
||||
if (count > 0) {
|
||||
$('#AlbumContainer tr.selected').each(function (index) {
|
||||
$(this).clone().appendTo('#CurrentPlaylistContainer tbody');
|
||||
updateMessage(count + ' Song(s) Added');
|
||||
});
|
||||
}
|
||||
}
|
||||
function downloadItem(id) {
|
||||
var url;
|
||||
if (id) {
|
||||
url = baseURL + '/download.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id;
|
||||
window.location = url;
|
||||
}
|
||||
/*
|
||||
$('table.songlist tr.selected').each(function (index) {
|
||||
id = $(this).attr('childid');
|
||||
if (id) {
|
||||
url = baseURL + '/download.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id;
|
||||
window.location = url;
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
function savePlaylist(playlistid) {
|
||||
var songs = [];
|
||||
|
@ -851,6 +933,9 @@ function getPlaylist(id, action, appendto) {
|
|||
html = generateSongHTML(rowcolor, child.id, child.parent, track, child.title, child.artist, child.album, child.coverArt, child.userRating, time['m'], time['s']);
|
||||
$(html).appendTo(appendto);
|
||||
});
|
||||
if (appendto === '#CurrentPlaylistContainer tbody') {
|
||||
updateMessage(children.length + ' Song(s) Added');
|
||||
}
|
||||
if (action === 'autoplay') {
|
||||
autoPlay();
|
||||
}
|
||||
|
@ -951,6 +1036,21 @@ function updateMessage(msg) {
|
|||
$('#messages').fadeIn();
|
||||
setTimeout(function () { $('#messages').fadeOut(); }, 5000);
|
||||
}
|
||||
// Convert to unicode support
|
||||
var toHTML = {
|
||||
on: function(str) {
|
||||
var a = [],
|
||||
i = 0;
|
||||
for (; i < str.length;) a[i] = str.charCodeAt(i++);
|
||||
return "&#" + a.join(";&#") + ";"
|
||||
},
|
||||
un: function(str) {
|
||||
return str.replace(/&#(x)?([^&]{1,5});?/g,
|
||||
function(a, b, c) {
|
||||
return String.fromCharCode(parseInt(c, b ? 16 : 10))
|
||||
})
|
||||
}
|
||||
};
|
||||
function setTitle(text) {
|
||||
if (text != "") {
|
||||
document.title = text;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
// A cross-browser javascript shim for html5 audio
|
||||
(function(audiojs, audiojsInstance, container) {
|
||||
(function (audiojs, audiojsInstance, container) {
|
||||
// Use the path to the audio.js file to create relative paths to the swf and player graphics
|
||||
// Remember that some systems (e.g. ruby on rails) append strings like '?1301478336' to asset paths
|
||||
var path = (function() {
|
||||
var path = (function () {
|
||||
var re = new RegExp('audio(\.min)?\.js.*'),
|
||||
scripts = document.getElementsByTagName('script');
|
||||
for (var i = 0, ii = scripts.length; i < ii; i++) {
|
||||
var path = scripts[i].getAttribute('src');
|
||||
if(re.test(path)) return path.replace(re, '');
|
||||
if (re.test(path)) return path.replace(re, '');
|
||||
}
|
||||
})();
|
||||
|
||||
|
@ -23,9 +23,9 @@
|
|||
// `$3` Cache invalidation
|
||||
flashSource: '\
|
||||
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="$1" width="1" height="1" name="$1" style="position: absolute; left: -1px;"> \
|
||||
<param name="movie" value="$2?playerInstance='+audiojs+'.instances[\'$1\']&datetime=$3"> \
|
||||
<param name="movie" value="$2?playerInstance=' + audiojs + '.instances[\'$1\']&datetime=$3"> \
|
||||
<param name="allowscriptaccess" value="always"> \
|
||||
<embed name="$1" src="$2?playerInstance='+audiojs+'.instances[\'$1\']&datetime=$3" width="1" height="1" allowscriptaccess="always"> \
|
||||
<embed name="$1" src="$2?playerInstance=' + audiojs + '.instances[\'$1\']&datetime=$3" width="1" height="1" allowscriptaccess="always"> \
|
||||
</object>',
|
||||
|
||||
// ### The main settings object
|
||||
|
@ -36,11 +36,11 @@
|
|||
preload: true,
|
||||
imageLocation: path + 'player-graphics.gif',
|
||||
swfLocation: path + 'audiojs.swf',
|
||||
useFlash: (function() {
|
||||
useFlash: (function () {
|
||||
var a = document.createElement('audio');
|
||||
return !(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
|
||||
})(),
|
||||
hasFlash: (function() {
|
||||
hasFlash: (function () {
|
||||
if (navigator.plugins && navigator.plugins.length && navigator.plugins['Shockwave Flash']) {
|
||||
return true;
|
||||
} else if (navigator.mimeTypes && navigator.mimeTypes.length) {
|
||||
|
@ -50,7 +50,7 @@
|
|||
try {
|
||||
var ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
|
||||
return true;
|
||||
} catch (e) {}
|
||||
} catch (e) { }
|
||||
}
|
||||
return false;
|
||||
})(),
|
||||
|
@ -124,54 +124,55 @@
|
|||
.error .play-pause p { cursor: auto; } \
|
||||
.error .error-message { display: block; }',
|
||||
// The default event callbacks:
|
||||
trackEnded: function(e) {},
|
||||
flashError: function() {
|
||||
trackEnded: function (e) { },
|
||||
flashError: function () {
|
||||
var player = this.settings.createPlayer,
|
||||
errorMessage = getByClass(player.errorMessageClass, this.wrapper),
|
||||
html = 'Missing <a href="http://get.adobe.com/flashplayer/">flash player</a> plugin.';
|
||||
if (this.mp3) html += ' <a href="'+this.mp3+'">Download audio file</a>.';
|
||||
if (this.mp3) html += ' <a href="' + this.mp3 + '">Download audio file</a>.';
|
||||
container[audiojs].helpers.removeClass(this.wrapper, player.loadingClass);
|
||||
container[audiojs].helpers.addClass(this.wrapper, player.errorClass);
|
||||
errorMessage.innerHTML = html;
|
||||
},
|
||||
loadError: function(e) {
|
||||
loadError: function (e) {
|
||||
var player = this.settings.createPlayer,
|
||||
errorMessage = getByClass(player.errorMessageClass, this.wrapper);
|
||||
container[audiojs].helpers.removeClass(this.wrapper, player.loadingClass);
|
||||
container[audiojs].helpers.addClass(this.wrapper, player.errorClass);
|
||||
errorMessage.innerHTML = 'Error loading: "'+this.mp3+'"';
|
||||
errorMessage.innerHTML = 'Error loading: "' + this.mp3 + '"';
|
||||
},
|
||||
init: function() {
|
||||
init: function () {
|
||||
var player = this.settings.createPlayer;
|
||||
container[audiojs].helpers.addClass(this.wrapper, player.loadingClass);
|
||||
},
|
||||
loadStarted: function() {
|
||||
loadStarted: function () {
|
||||
var player = this.settings.createPlayer,
|
||||
duration = getByClass(player.durationClass, this.wrapper),
|
||||
m = Math.floor(this.duration / 60),
|
||||
s = Math.floor(this.duration % 60);
|
||||
container[audiojs].helpers.removeClass(this.wrapper, player.loadingClass);
|
||||
duration.innerHTML = ((m<10?'0':'')+m+':'+(s<10?'0':'')+s);
|
||||
duration.innerHTML = ((m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s);
|
||||
},
|
||||
loadProgress: function(percent) {
|
||||
loadProgress: function (percent) {
|
||||
var player = this.settings.createPlayer,
|
||||
scrubber = getByClass(player.scrubberClass, this.wrapper),
|
||||
loaded = getByClass(player.loaderClass, this.wrapper);
|
||||
loaded.style.width = (scrubber.offsetWidth * percent) + 'px';
|
||||
|
||||
},
|
||||
playPause: function() {
|
||||
playPause: function () {
|
||||
if (this.playing) this.settings.play();
|
||||
else this.settings.pause();
|
||||
},
|
||||
play: function() {
|
||||
play: function () {
|
||||
var player = this.settings.createPlayer;
|
||||
container[audiojs].helpers.addClass(this.wrapper, player.playingClass);
|
||||
},
|
||||
pause: function() {
|
||||
pause: function () {
|
||||
var player = this.settings.createPlayer;
|
||||
container[audiojs].helpers.removeClass(this.wrapper, player.playingClass);
|
||||
},
|
||||
updatePlayhead: function(percent) {
|
||||
updatePlayhead: function (percent) {
|
||||
var player = this.settings.createPlayer,
|
||||
scrubber = getByClass(player.scrubberClass, this.wrapper),
|
||||
progress = getByClass(player.progressClass, this.wrapper);
|
||||
|
@ -181,7 +182,7 @@
|
|||
p = this.duration * percent,
|
||||
m = Math.floor(p / 60),
|
||||
s = Math.floor(p % 60);
|
||||
played.innerHTML = ((m<10?'0':'')+m+':'+(s<10?'0':'')+s);
|
||||
played.innerHTML = ((m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -191,7 +192,7 @@
|
|||
// Used to create a single `audiojs` instance.
|
||||
// If an array is passed then it calls back to `createAll()`.
|
||||
// Otherwise, it creates a single instance and returns it.
|
||||
create: function(element, options) {
|
||||
create: function (element, options) {
|
||||
var options = options || {}
|
||||
if (element.length) {
|
||||
return this.createAll(options, element);
|
||||
|
@ -203,7 +204,7 @@
|
|||
// `createAll()`
|
||||
// Creates multiple `audiojs` instances.
|
||||
// If `elements` is `null`, then automatically find any `<audio>` tags on the page and create `audiojs` instances for them.
|
||||
createAll: function(options, elements) {
|
||||
createAll: function (options, elements) {
|
||||
var audioElements = elements || document.getElementsByTagName('audio'),
|
||||
instances = []
|
||||
options = options || {};
|
||||
|
@ -215,11 +216,11 @@
|
|||
|
||||
// ### Creating and returning a new instance
|
||||
// This goes through all the steps required to build out a usable `audiojs` instance.
|
||||
newInstance: function(element, options) {
|
||||
newInstance: function (element, options) {
|
||||
var element = element,
|
||||
s = this.helpers.clone(this.settings),
|
||||
id = 'audiojs'+this.instanceCount,
|
||||
wrapperId = 'audiojs_wrapper'+this.instanceCount,
|
||||
id = 'audiojs' + this.instanceCount,
|
||||
wrapperId = 'audiojs_wrapper' + this.instanceCount,
|
||||
instanceCount = this.instanceCount++;
|
||||
|
||||
// Check for `autoplay`, `loop` and `preload` attributes and write them into the settings.
|
||||
|
@ -257,7 +258,7 @@
|
|||
|
||||
// ### Helper methods for constructing a working player
|
||||
// Inject a wrapping div and the markup for the html player.
|
||||
createPlayer: function(element, player, id) {
|
||||
createPlayer: function (element, player, id) {
|
||||
var wrapper = document.createElement('div'),
|
||||
newElement = element.cloneNode(true);
|
||||
wrapper.setAttribute('class', 'audiojs');
|
||||
|
@ -280,12 +281,12 @@
|
|||
},
|
||||
|
||||
// Attaches useful event callbacks to an `audiojs` instance.
|
||||
attachEvents: function(wrapper, audio) {
|
||||
attachEvents: function (wrapper, audio) {
|
||||
if (!audio.settings.createPlayer) return;
|
||||
var player = audio.settings.createPlayer,
|
||||
playPause = getByClass(player.playPauseClass, wrapper),
|
||||
scrubber = getByClass(player.scrubberClass, wrapper),
|
||||
leftPos = function(elem) {
|
||||
leftPos = function (elem) {
|
||||
var curleft = 0;
|
||||
if (elem.offsetParent) {
|
||||
do { curleft += elem.offsetLeft; } while (elem = elem.offsetParent);
|
||||
|
@ -293,11 +294,11 @@
|
|||
return curleft;
|
||||
};
|
||||
|
||||
container[audiojs].events.addListener(playPause, 'click', function(e) {
|
||||
container[audiojs].events.addListener(playPause, 'click', function (e) {
|
||||
audio.playPause.apply(audio);
|
||||
});
|
||||
|
||||
container[audiojs].events.addListener(scrubber, 'click', function(e) {
|
||||
container[audiojs].events.addListener(scrubber, 'click', function (e) {
|
||||
var relativeLeft = e.clientX - leftPos(this);
|
||||
audio.skipTo(relativeLeft / scrubber.offsetWidth);
|
||||
});
|
||||
|
@ -308,15 +309,15 @@
|
|||
// Start tracking the load progress of the track.
|
||||
container[audiojs].events.trackLoadProgress(audio);
|
||||
|
||||
container[audiojs].events.addListener(audio.element, 'timeupdate', function(e) {
|
||||
container[audiojs].events.addListener(audio.element, 'timeupdate', function (e) {
|
||||
audio.updatePlayhead.apply(audio);
|
||||
});
|
||||
|
||||
container[audiojs].events.addListener(audio.element, 'ended', function(e) {
|
||||
container[audiojs].events.addListener(audio.element, 'ended', function (e) {
|
||||
audio.trackEnded.apply(audio);
|
||||
});
|
||||
|
||||
container[audiojs].events.addListener(audio.source, 'error', function(e) {
|
||||
container[audiojs].events.addListener(audio.source, 'error', function (e) {
|
||||
// on error, cancel any load timers that are running.
|
||||
clearInterval(audio.readyTimer);
|
||||
clearInterval(audio.loadTimer);
|
||||
|
@ -326,28 +327,28 @@
|
|||
},
|
||||
|
||||
// Flash requires a slightly different API to the `<audio>` element, so this method is used to overwrite the standard event handlers.
|
||||
attachFlashEvents: function(element, audio) {
|
||||
attachFlashEvents: function (element, audio) {
|
||||
audio['swfReady'] = false;
|
||||
audio['load'] = function(mp3) {
|
||||
audio['load'] = function (mp3) {
|
||||
// If the swf isn't ready yet then just set `audio.mp3`. `init()` will load it in once the swf is ready.
|
||||
audio.mp3 = mp3;
|
||||
if (audio.swfReady) audio.element.load(mp3);
|
||||
}
|
||||
audio['loadProgress'] = function(percent, duration) {
|
||||
audio['loadProgress'] = function (percent, duration) {
|
||||
audio.loadedPercent = percent;
|
||||
audio.duration = duration;
|
||||
audio.settings.loadStarted.apply(audio);
|
||||
audio.settings.loadProgress.apply(audio, [percent]);
|
||||
}
|
||||
audio['skipTo'] = function(percent) {
|
||||
audio['skipTo'] = function (percent) {
|
||||
if (percent > audio.loadedPercent) return;
|
||||
audio.updatePlayhead.call(audio, [percent])
|
||||
audio.element.skipTo(percent);
|
||||
}
|
||||
audio['updatePlayhead'] = function(percent) {
|
||||
audio['updatePlayhead'] = function (percent) {
|
||||
audio.settings.updatePlayhead.apply(audio, [percent]);
|
||||
}
|
||||
audio['play'] = function() {
|
||||
audio['play'] = function () {
|
||||
// If the audio hasn't started preloading, then start it now.
|
||||
// Then set `preload` to `true`, so that any tracks loaded in subsequently are loaded straight away.
|
||||
if (!audio.settings.preload) {
|
||||
|
@ -360,16 +361,16 @@
|
|||
audio.element.pplay();
|
||||
audio.settings.play.apply(audio);
|
||||
}
|
||||
audio['pause'] = function() {
|
||||
audio['pause'] = function () {
|
||||
audio.playing = false;
|
||||
// Use `ppause()` for consistency with `pplay()`, even though it isn't really required.
|
||||
audio.element.ppause();
|
||||
audio.settings.pause.apply(audio);
|
||||
}
|
||||
audio['setVolume'] = function(v) {
|
||||
audio['setVolume'] = function (v) {
|
||||
audio.element.setVolume(v);
|
||||
}
|
||||
audio['loadStarted'] = function() {
|
||||
audio['loadStarted'] = function () {
|
||||
// Load the mp3 specified by the audio element into the swf.
|
||||
audio.swfReady = true;
|
||||
if (audio.settings.preload) audio.element.init(audio.mp3);
|
||||
|
@ -379,7 +380,7 @@
|
|||
|
||||
// ### Injecting an swf from a string
|
||||
// Build up the swf source by replacing the `$keys` and then inject the markup into the page.
|
||||
injectFlash: function(audio, id) {
|
||||
injectFlash: function (audio, id) {
|
||||
var flashSource = this.flashSource.replace(/\$1/g, id);
|
||||
flashSource = flashSource.replace(/\$2/g, audio.settings.swfLocation);
|
||||
// `(+new Date)` ensures the swf is not pulled out of cache. The fixes an issue with Firefox running multiple players on the same page.
|
||||
|
@ -396,7 +397,7 @@
|
|||
helpers: {
|
||||
// **Merge two objects, with `obj2` overwriting `obj1`**
|
||||
// The merge is shallow, but that's all that is required for our purposes.
|
||||
merge: function(obj1, obj2) {
|
||||
merge: function (obj1, obj2) {
|
||||
for (attr in obj2) {
|
||||
if (obj1.hasOwnProperty(attr) || obj2.hasOwnProperty(attr)) {
|
||||
obj1[attr] = obj2[attr];
|
||||
|
@ -404,25 +405,25 @@
|
|||
}
|
||||
},
|
||||
// **Clone a javascript object (recursively)**
|
||||
clone: function(obj){
|
||||
if (obj == null || typeof(obj) !== 'object') return obj;
|
||||
clone: function (obj) {
|
||||
if (obj == null || typeof (obj) !== 'object') return obj;
|
||||
var temp = new obj.constructor();
|
||||
for (var key in obj) temp[key] = arguments.callee(obj[key]);
|
||||
return temp;
|
||||
},
|
||||
// **Adding/removing classnames from elements**
|
||||
addClass: function(element, className) {
|
||||
var re = new RegExp('(\\s|^)'+className+'(\\s|$)');
|
||||
addClass: function (element, className) {
|
||||
var re = new RegExp('(\\s|^)' + className + '(\\s|$)');
|
||||
if (re.test(element.className)) return;
|
||||
element.className += ' ' + className;
|
||||
},
|
||||
removeClass: function(element, className) {
|
||||
var re = new RegExp('(\\s|^)'+className+'(\\s|$)');
|
||||
element.className = element.className.replace(re,' ');
|
||||
removeClass: function (element, className) {
|
||||
var re = new RegExp('(\\s|^)' + className + '(\\s|$)');
|
||||
element.className = element.className.replace(re, ' ');
|
||||
},
|
||||
// **Dynamic CSS injection**
|
||||
// Takes a string of css, inserts it into a `<style>`, then injects it in at the very top of the `<head>`. This ensures any user-defined styles will take precedence.
|
||||
injectCss: function(audio, string) {
|
||||
injectCss: function (audio, string) {
|
||||
|
||||
// If an `audiojs` `<style>` tag already exists, then append to it rather than creating a whole new `<style>`.
|
||||
var prepend = '',
|
||||
|
@ -456,7 +457,7 @@
|
|||
},
|
||||
// **Handle all the IE6+7 requirements for cloning `<audio>` nodes**
|
||||
// Create a html5-safe document fragment by injecting an `<audio>` element into the document fragment.
|
||||
cloneHtml5Node: function(audioTag) {
|
||||
cloneHtml5Node: function (audioTag) {
|
||||
var fragment = document.createDocumentFragment();
|
||||
fragment.createElement('audio');
|
||||
var div = fragment.createElement('div');
|
||||
|
@ -465,7 +466,7 @@
|
|||
return div.firstChild;
|
||||
},
|
||||
// **Cross-browser `<object>` / `<embed>` element selection**
|
||||
getSwf: function(name) {
|
||||
getSwf: function (name) {
|
||||
var swf = document[name] || window[name];
|
||||
return swf.length > 1 ? swf[swf.length - 1] : swf;
|
||||
}
|
||||
|
@ -475,7 +476,7 @@
|
|||
memoryLeaking: false,
|
||||
listeners: [],
|
||||
// **A simple cross-browser event handler abstraction**
|
||||
addListener: function(element, eventName, func) {
|
||||
addListener: function (element, eventName, func) {
|
||||
// For modern browsers use the standard DOM-compliant `addEventListener`.
|
||||
if (element.addEventListener) {
|
||||
element.addEventListener(eventName, func, false);
|
||||
|
@ -484,8 +485,8 @@
|
|||
} else if (element.attachEvent) {
|
||||
this.listeners.push(element);
|
||||
if (!this.memoryLeaking) {
|
||||
window.attachEvent('onunload', function() {
|
||||
if(this.listeners) {
|
||||
window.attachEvent('onunload', function () {
|
||||
if (this.listeners) {
|
||||
for (var i = 0, ii = this.listeners.length; i < ii; i++) {
|
||||
container[audiojs].events.purge(this.listeners[i]);
|
||||
}
|
||||
|
@ -493,13 +494,13 @@
|
|||
});
|
||||
this.memoryLeaking = true;
|
||||
}
|
||||
element.attachEvent('on' + eventName, function() {
|
||||
element.attachEvent('on' + eventName, function () {
|
||||
func.call(element, window.event);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
trackLoadProgress: function(audio) {
|
||||
trackLoadProgress: function (audio) {
|
||||
// If `preload` has been set to `none`, then we don't want to start loading the track yet.
|
||||
if (!audio.settings.preload) return;
|
||||
|
||||
|
@ -509,7 +510,7 @@
|
|||
ios = (/(ipod|iphone|ipad)/i).test(navigator.userAgent);
|
||||
|
||||
// Use timers here rather than the official `progress` event, as Chrome has issues calling `progress` when loading mp3 files from cache.
|
||||
readyTimer = setInterval(function() {
|
||||
readyTimer = setInterval(function () {
|
||||
if (audio.element.readyState > -1) {
|
||||
// iOS doesn't start preloading the mp3 until the user interacts manually, so this stops the loader being displayed prematurely.
|
||||
if (!ios) audio.init.apply(audio);
|
||||
|
@ -518,7 +519,7 @@
|
|||
if (audio.settings.autoplay) audio.play.apply(audio);
|
||||
clearInterval(readyTimer);
|
||||
// Once we have data, start tracking the load progress.
|
||||
loadTimer = setInterval(function() {
|
||||
loadTimer = setInterval(function () {
|
||||
audio.loadProgress.apply(audio);
|
||||
if (audio.loadedPercent >= 1) clearInterval(loadTimer);
|
||||
});
|
||||
|
@ -531,7 +532,7 @@
|
|||
// **Douglas Crockford's IE6 memory leak fix**
|
||||
// <http://javascript.crockford.com/memory/leak.html>
|
||||
// This is used to release the memory leak created by the circular references created when fixing `this` scoping for IE. It is called on page unload.
|
||||
purge: function(d) {
|
||||
purge: function (d) {
|
||||
var a = d.attributes, i;
|
||||
if (a) {
|
||||
for (i = 0; i < a.length; i += 1) {
|
||||
|
@ -546,25 +547,26 @@
|
|||
|
||||
// **DOMready function**
|
||||
// As seen here: <https://github.com/dperini/ContentLoaded/>.
|
||||
ready: (function() { return function(fn) {
|
||||
ready: (function () {
|
||||
return function (fn) {
|
||||
var win = window, done = false, top = true,
|
||||
doc = win.document, root = doc.documentElement,
|
||||
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
|
||||
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
|
||||
pre = doc.addEventListener ? '' : 'on',
|
||||
init = function(e) {
|
||||
init = function (e) {
|
||||
if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
|
||||
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
|
||||
if (!done && (done = true)) fn.call(win, e.type || e);
|
||||
},
|
||||
poll = function() {
|
||||
try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }
|
||||
poll = function () {
|
||||
try { root.doScroll('left'); } catch (e) { setTimeout(poll, 50); return; }
|
||||
init('poll');
|
||||
};
|
||||
if (doc.readyState == 'complete') fn.call(win, 'lazy');
|
||||
else {
|
||||
if (doc.createEventObject && root.doScroll) {
|
||||
try { top = !win.frameElement; } catch(e) { }
|
||||
try { top = !win.frameElement; } catch (e) { }
|
||||
if (top) poll();
|
||||
}
|
||||
doc[add](pre + 'DOMContentLoaded', init, false);
|
||||
|
@ -579,13 +581,13 @@
|
|||
|
||||
// ## The audiojs class
|
||||
// We create one of these per `<audio>` and then push them into `audiojs['instances']`.
|
||||
container[audiojsInstance] = function(element, settings) {
|
||||
container[audiojsInstance] = function (element, settings) {
|
||||
// Each audio instance returns an object which contains an API back into the `<audio>` element.
|
||||
this.element = element;
|
||||
this.wrapper = element.parentNode;
|
||||
this.source = element.getElementsByTagName('source')[0] || element;
|
||||
// First check the `<audio>` element directly for a src and if one is not found, look for a `<source>` element.
|
||||
this.mp3 = (function(element) {
|
||||
this.mp3 = (function (element) {
|
||||
var source = element.getElementsByTagName('source')[0];
|
||||
return element.getAttribute('src') || (source ? source.getAttribute('src') : null);
|
||||
})(element);
|
||||
|
@ -599,16 +601,16 @@
|
|||
container[audiojsInstance].prototype = {
|
||||
// API access events:
|
||||
// Each of these do what they need do and then call the matching methods defined in the settings object.
|
||||
updatePlayhead: function() {
|
||||
updatePlayhead: function () {
|
||||
var percent = this.element.currentTime / this.duration;
|
||||
this.settings.updatePlayhead.apply(this, [percent]);
|
||||
},
|
||||
skipTo: function(percent) {
|
||||
skipTo: function (percent) {
|
||||
if (percent > this.loadedPercent) return;
|
||||
this.element.currentTime = this.duration * percent;
|
||||
this.updatePlayhead();
|
||||
},
|
||||
load: function(mp3) {
|
||||
load: function (mp3) {
|
||||
this.loadStartedCalled = false;
|
||||
this.source.setAttribute('src', mp3);
|
||||
// The now outdated `load()` method is required for Safari 4
|
||||
|
@ -616,13 +618,13 @@
|
|||
this.mp3 = mp3;
|
||||
container[audiojs].events.trackLoadProgress(this);
|
||||
},
|
||||
loadError: function() {
|
||||
loadError: function () {
|
||||
this.settings.loadError.apply(this);
|
||||
},
|
||||
init: function() {
|
||||
init: function () {
|
||||
this.settings.init.apply(this);
|
||||
},
|
||||
loadStarted: function() {
|
||||
loadStarted: function () {
|
||||
// Wait until `element.duration` exists before setting up the audio player.
|
||||
if (!this.element.duration) return false;
|
||||
|
||||
|
@ -630,7 +632,7 @@
|
|||
this.updatePlayhead();
|
||||
this.settings.loadStarted.apply(this);
|
||||
},
|
||||
loadProgress: function() {
|
||||
loadProgress: function () {
|
||||
if (this.element.buffered != null && this.element.buffered.length) {
|
||||
// Ensure `loadStarted()` is only called once.
|
||||
if (!this.loadStartedCalled) {
|
||||
|
@ -642,11 +644,11 @@
|
|||
this.settings.loadProgress.apply(this, [this.loadedPercent]);
|
||||
}
|
||||
},
|
||||
playPause: function() {
|
||||
playPause: function () {
|
||||
if (this.playing) this.pause();
|
||||
else this.play();
|
||||
},
|
||||
play: function() {
|
||||
play: function () {
|
||||
var ios = (/(ipod|iphone|ipad)/i).test(navigator.userAgent);
|
||||
// On iOS this interaction will trigger loading the mp3, so run `init()`.
|
||||
if (ios && this.element.readyState == 0) this.init.apply(this);
|
||||
|
@ -661,15 +663,15 @@
|
|||
this.element.play();
|
||||
this.settings.play.apply(this);
|
||||
},
|
||||
pause: function() {
|
||||
pause: function () {
|
||||
this.playing = false;
|
||||
this.element.pause();
|
||||
this.settings.pause.apply(this);
|
||||
},
|
||||
setVolume: function(v) {
|
||||
setVolume: function (v) {
|
||||
this.element.volume = v;
|
||||
},
|
||||
trackEnded: function(e) {
|
||||
trackEnded: function (e) {
|
||||
this.skipTo.apply(this, [0]);
|
||||
if (!this.settings.loop) this.pause.apply(this);
|
||||
this.settings.trackEnded.apply(this);
|
||||
|
@ -679,7 +681,7 @@
|
|||
// **getElementsByClassName**
|
||||
// Having to rely on `getElementsByTagName` is pretty inflexible internally, so a modified version of Dustin Diaz's `getElementsByClassName` has been included.
|
||||
// This version cleans things up and prefers the native DOM method if it's available.
|
||||
var getByClass = function(searchClass, node, tag) {
|
||||
var getByClass = function (searchClass, node, tag) {
|
||||
var matches = [];
|
||||
if (document.getElementsByClassName) {
|
||||
matches = node.getElementsByClassName(searchClass);
|
||||
|
@ -687,7 +689,7 @@
|
|||
var node = node || document,
|
||||
tag = tag || '*',
|
||||
els = node.getElementsByTagName(tag),
|
||||
pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
|
||||
pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
|
||||
|
||||
for (i = 0, j = 0, l = els.length; i < l; i++) {
|
||||
if (pattern.test(els[i].className)) {
|
||||
|
@ -698,5 +700,5 @@
|
|||
}
|
||||
return matches.length > 1 ? matches : matches[0];
|
||||
}
|
||||
// The global variable names are passed in here and can be changed if they conflict with anything else.
|
||||
// The global variable names are passed in here and can be changed if they conflict with anything else.
|
||||
})('audiojs', 'audiojsInstance', this);
|
59
js/contextMenu/jquery.contextMenu.css
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Generic context menu styles */
|
||||
.contextMenu {
|
||||
position: absolute;
|
||||
width: 115px;
|
||||
z-index: 99999;
|
||||
border: solid 1px #DEDEDE;
|
||||
background: #fff;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.contextMenu LI {
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.contextMenu A {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
height: 20px;
|
||||
background-position: 9px center;
|
||||
background-repeat: no-repeat;
|
||||
outline: none;
|
||||
padding: 3px 5px;
|
||||
padding-left: 32px;
|
||||
font-size: 16px;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.contextMenu LI.hover A {
|
||||
color: #FFF;
|
||||
background-color: #3399FF;
|
||||
}
|
||||
|
||||
.contextMenu LI.disabled A {
|
||||
color: #AAA;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.contextMenu LI.hover.disabled A {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.contextMenu LI.separator {
|
||||
border-top: solid 1px #CCC;
|
||||
}
|
||||
|
||||
/*
|
||||
Adding Icons
|
||||
|
||||
You can add icons to the context menu by adding
|
||||
classes to the respective LI element(s)
|
||||
*/
|
||||
|
||||
.contextMenu LI.download A { background-image: url(../../images/download_gd_12x16.png); }
|
209
js/contextMenu/jquery.contextMenu.js
Normal file
|
@ -0,0 +1,209 @@
|
|||
// jQuery Context Menu Plugin
|
||||
//
|
||||
// Version 1.01
|
||||
//
|
||||
// Cory S.N. LaViska
|
||||
// A Beautiful Site (http://abeautifulsite.net/)
|
||||
//
|
||||
// More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/
|
||||
//
|
||||
// Terms of Use
|
||||
//
|
||||
// This plugin is dual-licensed under the GNU General Public License
|
||||
// and the MIT License and is copyright A Beautiful Site, LLC.
|
||||
//
|
||||
if (jQuery) (function () {
|
||||
$.extend($.fn, {
|
||||
|
||||
contextMenu: function (o, callback) {
|
||||
// Defaults
|
||||
if (o.menu == undefined) return false;
|
||||
if (o.inSpeed == undefined) o.inSpeed = 150;
|
||||
if (o.outSpeed == undefined) o.outSpeed = 75;
|
||||
// 0 needs to be -1 for expected results (no fade)
|
||||
if (o.inSpeed == 0) o.inSpeed = -1;
|
||||
if (o.outSpeed == 0) o.outSpeed = -1;
|
||||
// Loop each context menu
|
||||
$(this).live("mousedown", function (e) {
|
||||
var el = $(this);
|
||||
var offset = $(el).offset();
|
||||
// Add contextMenu class
|
||||
$('#' + o.menu).addClass('contextMenu');
|
||||
|
||||
var evt = e;
|
||||
evt.stopPropagation();
|
||||
$(this).mouseup(function (e) {
|
||||
e.stopPropagation();
|
||||
var srcElement = $(this);
|
||||
$(this).unbind('mouseup');
|
||||
if (evt.button == 2) {
|
||||
// Hide context menus that may be showing
|
||||
$(".contextMenu").hide();
|
||||
// Get this context menu
|
||||
var menu = $('#' + o.menu);
|
||||
|
||||
if ($(el).hasClass('disabled')) return false;
|
||||
|
||||
// Detect mouse position
|
||||
var d = {}, x, y;
|
||||
if (self.innerHeight) {
|
||||
d.pageYOffset = self.pageYOffset;
|
||||
d.pageXOffset = self.pageXOffset;
|
||||
d.innerHeight = self.innerHeight;
|
||||
d.innerWidth = self.innerWidth;
|
||||
} else if (document.documentElement &&
|
||||
document.documentElement.clientHeight) {
|
||||
d.pageYOffset = document.documentElement.scrollTop;
|
||||
d.pageXOffset = document.documentElement.scrollLeft;
|
||||
d.innerHeight = document.documentElement.clientHeight;
|
||||
d.innerWidth = document.documentElement.clientWidth;
|
||||
} else if (document.body) {
|
||||
d.pageYOffset = document.body.scrollTop;
|
||||
d.pageXOffset = document.body.scrollLeft;
|
||||
d.innerHeight = document.body.clientHeight;
|
||||
d.innerWidth = document.body.clientWidth;
|
||||
}
|
||||
(e.pageX) ? x = e.pageX : x = e.clientX + d.scrollLeft;
|
||||
(e.pageY) ? y = e.pageY : y = e.clientY + d.scrollTop;
|
||||
|
||||
// Show the menu
|
||||
//$(document).unbind('click');
|
||||
$(menu).css({ top: y, left: x }).fadeIn(o.inSpeed);
|
||||
// Hover events
|
||||
$(menu).find('A').mouseover(function () {
|
||||
$(menu).find('LI.hover').removeClass('hover');
|
||||
$(this).parent().addClass('hover');
|
||||
}).mouseout(function () {
|
||||
$(menu).find('LI.hover').removeClass('hover');
|
||||
});
|
||||
|
||||
// Keyboard
|
||||
$(document).keypress(function (e) {
|
||||
switch (e.keyCode) {
|
||||
case 38: // up
|
||||
if ($(menu).find('LI.hover').size() == 0) {
|
||||
$(menu).find('LI:last').addClass('hover');
|
||||
} else {
|
||||
$(menu).find('LI.hover').removeClass('hover').prevAll('LI:not(.disabled)').eq(0).addClass('hover');
|
||||
if ($(menu).find('LI.hover').size() == 0) $(menu).find('LI:last').addClass('hover');
|
||||
}
|
||||
break;
|
||||
case 40: // down
|
||||
if ($(menu).find('LI.hover').size() == 0) {
|
||||
$(menu).find('LI:first').addClass('hover');
|
||||
} else {
|
||||
$(menu).find('LI.hover').removeClass('hover').nextAll('LI:not(.disabled)').eq(0).addClass('hover');
|
||||
if ($(menu).find('LI.hover').size() == 0) $(menu).find('LI:first').addClass('hover');
|
||||
}
|
||||
break;
|
||||
case 13: // enter
|
||||
$(menu).find('LI.hover A').trigger('click');
|
||||
break;
|
||||
case 27: // esc
|
||||
$(document).trigger('click');
|
||||
break
|
||||
}
|
||||
});
|
||||
|
||||
// When items are selected
|
||||
$('#' + o.menu).find('A').unbind('click');
|
||||
$('#' + o.menu).find('LI:not(.disabled) A').click(function () {
|
||||
//$(document).unbind('click').unbind('keypress');
|
||||
$(".contextMenu").hide();
|
||||
// Callback
|
||||
if (callback) callback($(this).attr('href').substr(1), $(srcElement), { x: x - offset.left, y: y - offset.top, docX: x, docY: y });
|
||||
return false;
|
||||
});
|
||||
|
||||
// Hide bindings
|
||||
setTimeout(function () { // Delay for Mozilla
|
||||
$(document).click(function () {
|
||||
//$(document).unbind('click').unbind('keypress');
|
||||
$(menu).fadeOut(o.outSpeed);
|
||||
return false;
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
|
||||
// Disable text selection
|
||||
if ($.browser.mozilla) {
|
||||
$('#' + o.menu).each(function () { $(this).css({ 'MozUserSelect': 'none' }); });
|
||||
} else if ($.browser.msie) {
|
||||
$('#' + o.menu).each(function () { $(this).bind('selectstart.disableTextSelect', function () { return false; }); });
|
||||
} else {
|
||||
$('#' + o.menu).each(function () { $(this).bind('mousedown.disableTextSelect', function () { return false; }); });
|
||||
}
|
||||
// Disable browser context menu (requires both selectors to work in IE/Safari + FF/Chrome)
|
||||
$(el).add($('UL.contextMenu')).bind('contextmenu', function () { return false; });
|
||||
|
||||
});
|
||||
return $(this);
|
||||
},
|
||||
|
||||
// Disable context menu items on the fly
|
||||
disableContextMenuItems: function (o) {
|
||||
if (o == undefined) {
|
||||
// Disable all
|
||||
$(this).find('LI').addClass('disabled');
|
||||
return ($(this));
|
||||
}
|
||||
$(this).each(function () {
|
||||
if (o != undefined) {
|
||||
var d = o.split(',');
|
||||
for (var i = 0; i < d.length; i++) {
|
||||
$(this).find('A[href="' + d[i] + '"]').parent().addClass('disabled');
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
return ($(this));
|
||||
},
|
||||
|
||||
// Enable context menu items on the fly
|
||||
enableContextMenuItems: function (o) {
|
||||
if (o == undefined) {
|
||||
// Enable all
|
||||
$(this).find('LI.disabled').removeClass('disabled');
|
||||
return ($(this));
|
||||
}
|
||||
$(this).each(function () {
|
||||
if (o != undefined) {
|
||||
var d = o.split(',');
|
||||
for (var i = 0; i < d.length; i++) {
|
||||
$(this).find('A[href="' + d[i] + '"]').parent().removeClass('disabled');
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
return ($(this));
|
||||
},
|
||||
|
||||
// Disable context menu(s)
|
||||
disableContextMenu: function () {
|
||||
$(this).each(function () {
|
||||
$(this).addClass('disabled');
|
||||
});
|
||||
return ($(this));
|
||||
},
|
||||
|
||||
// Enable context menu(s)
|
||||
enableContextMenu: function () {
|
||||
$(this).each(function () {
|
||||
$(this).removeClass('disabled');
|
||||
});
|
||||
return ($(this));
|
||||
},
|
||||
|
||||
// Destroy context menu(s)
|
||||
destroyContextMenu: function () {
|
||||
// Destroy specified context menus
|
||||
$(this).each(function () {
|
||||
// Disable action
|
||||
$(this).unbind('mousedown').unbind('mouseup');
|
||||
});
|
||||
return ($(this));
|
||||
}
|
||||
|
||||
});
|
||||
})(jQuery);
|
67
js/ui-load.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
$(window).load(function () {
|
||||
if ($.cookie('defaultsmwidth')) {
|
||||
var width = $.cookie('defaultsmwidth');
|
||||
resizeSMSection(width);
|
||||
}
|
||||
if ($.cookie('sidebar') && $.cookie('username') && $.cookie('password')) {
|
||||
$('#SideBar').show();
|
||||
updateChatMessages();
|
||||
updateNowPlaying();
|
||||
}
|
||||
if ($.cookie('HideAZ')) {
|
||||
$('#BottomContainer').hide();
|
||||
}
|
||||
$('ul#ChangeLog li.log').each(function (i, el) {
|
||||
if (i > 3) {
|
||||
$(el).hide();
|
||||
}
|
||||
});
|
||||
resizeContent();
|
||||
});
|
||||
window.onbeforeunload = function () {
|
||||
closeAllNotifications();
|
||||
};
|
||||
$(window).resize(function () {
|
||||
resizeContent();
|
||||
});
|
||||
function resizeContent() {
|
||||
var screenwidth = $(window).width();
|
||||
$('.tabcontent').css({ 'height': (($(window).height() - 112)) + 'px' });
|
||||
$('.smsection').css({ 'height': (($(window).height() - 152)) + 'px' });
|
||||
var smheight = $('.smsection').height();
|
||||
var smwidth = $('.smsection').width();
|
||||
$('#BottomContainer').css({ 'top': smheight + 34 + 'px' });
|
||||
if ($.cookie('sidebar')) {
|
||||
var tabwidth = $(window).width() - 268;
|
||||
if (tabwidth >= 700) {
|
||||
$('.tabcontent').css({ 'width': tabwidth + 'px' });
|
||||
}
|
||||
var sbheight = $(window).height() - 152;
|
||||
$('#SideBar').css({ 'height': (sbheight + 108) + 'px' });
|
||||
$('#ChatMsgs').css({ 'height': (sbheight - 166) + 'px' });
|
||||
} else {
|
||||
var tabwidth = $(window).width() - 61;
|
||||
if (tabwidth >= 700) {
|
||||
$('.tabcontent').css({ 'width': tabwidth + 'px' });
|
||||
}
|
||||
}
|
||||
var tabwidth = $('.tabcontent').width();
|
||||
$('#AlbumContainer, #TrackContainer, #CurrentPlaylistContainer').css({ 'width': (tabwidth - smwidth - 30) + 'px' });
|
||||
$('#CurrentPlaylistContainer').css({ 'width': (tabwidth - 30) + 'px' });
|
||||
$('#player').css({ 'width': tabwidth + 'px' });
|
||||
}
|
||||
function resizeSMSection(x) {
|
||||
var defwidth = 200;
|
||||
var smwidth = $('.smsection').width();
|
||||
var newsmwidth = smwidth + parseInt(x);
|
||||
var newwidth = newsmwidth - defwidth;
|
||||
if (smwidth != newsmwidth && newsmwidth > 150 && newsmwidth < 500) {
|
||||
$('.smsection').css({ 'width': (newsmwidth) + 'px' });
|
||||
$('.actions').css({ 'width': (newsmwidth - 5) + 'px' });
|
||||
$('#BottomContainer').css({ 'width': (newsmwidth - 16) + 'px' });
|
||||
$.cookie('defaultsmwidth', newwidth, { expires: 365, path: '/' });
|
||||
var ulwidth = newsmwidth + 6;
|
||||
$('#AlbumContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
$('#TrackContainer').css({ 'margin-left': ulwidth + 'px' });
|
||||
}
|
||||
}
|
488
js/ui-ready.js
Normal file
|
@ -0,0 +1,488 @@
|
|||
$(document).ready(function () {
|
||||
// Tabs
|
||||
$(".tabcontent").hide(); //Hide all content
|
||||
if ($.cookie('username') == null) {
|
||||
$('ul.tabs li a').each(function () {
|
||||
if ($(this).attr("href") == '#tabPreferences') {
|
||||
$(this).addClass("active"); //Add "active" class to selected tab
|
||||
}
|
||||
});
|
||||
$("#tabPreferences").show(); //Show first tab content
|
||||
loadTabContent('#tabPreferences');
|
||||
} else {
|
||||
if (window.location.hash) {
|
||||
var hash = window.location.hash;
|
||||
$('ul.tabs li a').each(function () {
|
||||
if ($(this).attr("href") == hash) {
|
||||
$(this).addClass("active"); //Add "active" class to selected tab
|
||||
}
|
||||
});
|
||||
$(hash).show(); //Fade in the active ID content
|
||||
loadTabContent(hash);
|
||||
} else {
|
||||
$("ul.tabs li:first a").addClass("active").show(); //Activate first tab
|
||||
$(".tabcontent:first").show(); //Show first tab content
|
||||
var firstTab = $("ul.tabs li:first a").attr("href");
|
||||
loadTabContent(firstTab);
|
||||
}
|
||||
}
|
||||
|
||||
// Tabs - Click Event
|
||||
$("ul.tabs li a").click(function () {
|
||||
$("ul.tabs li a").removeClass("active"); //Remove any "active" class
|
||||
$(this).addClass("active"); //Add "active" class to selected tab
|
||||
$(".tabcontent").hide(); //Hide all tab content
|
||||
|
||||
var activeTab = $(this).attr("href"); //Find the href attribute value to identify the active tab + content
|
||||
$(activeTab).show(); //Fade in the active ID content
|
||||
loadTabContent(activeTab);
|
||||
});
|
||||
|
||||
// Ajax Loading Screen
|
||||
$(".toploading").ajaxStart(function () {
|
||||
$(this).show();
|
||||
});
|
||||
$(".toploading").ajaxStop(function () {
|
||||
$(this).hide();
|
||||
});
|
||||
|
||||
// Keyboard shortcuts
|
||||
$(document).keydown(function (e) {
|
||||
var source = e.target.id;
|
||||
if (source != 'Search' && source != 'ChatMsg') {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
// a-z
|
||||
if (unicode >= 65 && unicode <= 90) {
|
||||
var key = findKeyForCode(unicode);
|
||||
var el = '#index_' + key.toUpperCase();
|
||||
$('#Artists').stop().scrollTo(el, 400);
|
||||
// right arrow
|
||||
} else if (unicode == 39 || unicode == 176) {
|
||||
var next = $('#CurrentPlaylistContainer tr.playing').next();
|
||||
if (!next.length) next = $('#CurrentPlaylistContainer li').first();
|
||||
changeTrack(next);
|
||||
// back arrow
|
||||
} else if (unicode == 37 || unicode == 177) {
|
||||
var prev = $('#CurrentPlaylistContainer tr.playing').prev();
|
||||
if (!prev.length) prev = $('#CurrentPlaylistContainer tr').last();
|
||||
changeTrack(prev);
|
||||
// spacebar
|
||||
} else if (unicode == 32 || unicode == 179 || unicode == 0179) {
|
||||
playPauseSong();
|
||||
} else if (unicode == 36) {
|
||||
$('#Artists').stop().scrollTo('#auto', 400);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Main Click Events
|
||||
// Albums Click Event
|
||||
$('#MusicFolders').live('change', function () {
|
||||
var folder = $(this).val();
|
||||
loadArtists(folder, true);
|
||||
$.cookie('MusicFolders', folder, { expires: 365 });
|
||||
});
|
||||
$('#ArtistContainer li.item').live('click', function () {
|
||||
$('#AutoAlbumContainer li').removeClass('selected');
|
||||
$('#ArtistContainer li').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
getAlbums($(this).attr("id"), '', '#AlbumRows');
|
||||
});
|
||||
$('#BottomIndex li a').live('click', function () {
|
||||
var el = '#index_' + $(this).text();
|
||||
$('#Artists').stop().scrollTo(el, 400);
|
||||
return false;
|
||||
});
|
||||
$('#AutoAlbumContainer li.item').live('click', function () {
|
||||
$('#AutoAlbumContainer li').removeClass('selected');
|
||||
$('#ArtistContainer li').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
getAlbumListBy($(this).attr("id"));
|
||||
});
|
||||
$('tr.album a.play').live('click', function (e) {
|
||||
var albumid = $(this).parent().parent().attr('childid');
|
||||
var artistid = $(this).parent().parent().attr('parentid');
|
||||
getAlbums(albumid, 'autoplay', '#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('tr.album a.add').live('click', function (e) {
|
||||
var albumid = $(this).parent().parent().attr('childid');
|
||||
var artistid = $(this).parent().parent().attr('parentid');
|
||||
getAlbums(albumid, 'add', '#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('tr.album a.download').live('click', function (event) {
|
||||
var itemid = $(this).parent().parent().attr('childid');
|
||||
downloadItem(itemid);
|
||||
return false;
|
||||
});
|
||||
$('tr.album a.rate').live('click', function (event) {
|
||||
var itemid = $(this).parent().parent().attr('childid');
|
||||
rateSong(itemid, 5);
|
||||
$(this).removeClass('rate');
|
||||
$(this).addClass('favorite');
|
||||
return false;
|
||||
});
|
||||
$('tr.album a.favorite').live('click', function (event) {
|
||||
var itemid = $(this).parent().parent().attr('childid');
|
||||
rateSong(itemid, 0);
|
||||
$(this).removeClass('favorite');
|
||||
$(this).addClass('rate');
|
||||
return false;
|
||||
});
|
||||
$('tr.album').live('click', function (e) {
|
||||
var albumid = $(this).attr('childid');
|
||||
var artistid = $(this).attr('parentid');
|
||||
getAlbums(albumid, '', '#AlbumRows');
|
||||
return false;
|
||||
});
|
||||
|
||||
// Track - Click Events
|
||||
// Multiple Select
|
||||
$('.noselect').disableTextSelect();
|
||||
var lastChecked = null;
|
||||
$('table.songlist tr.song').live('click', function (event) {
|
||||
var checkboxclass = 'table.songlist tr.song';
|
||||
var songid = $(this).attr('childid');
|
||||
var albumid = $(this).attr('parentid');
|
||||
if (!event.ctrlKey) {
|
||||
$(checkboxclass).removeClass('selected');
|
||||
}
|
||||
if ($(this).hasClass('selected')) {
|
||||
$(this).removeClass('selected');
|
||||
} else {
|
||||
$(this).addClass('selected');
|
||||
}
|
||||
if (!lastChecked) {
|
||||
lastChecked = this;
|
||||
return;
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
var start = $(checkboxclass).index(this);
|
||||
var end = $(checkboxclass).index(lastChecked);
|
||||
for (i = Math.min(start, end); i <= Math.max(start, end); i++) {
|
||||
$(checkboxclass).eq(i).addClass('selected');
|
||||
}
|
||||
}
|
||||
lastChecked = this;
|
||||
});
|
||||
// Double Click
|
||||
$('table.songlist tr.song').live('dblclick', function (e) {
|
||||
e.preventDefault();
|
||||
//$(this).addClass('playing').siblings().removeClass('playing');
|
||||
var songid = $(this).attr('childid');
|
||||
var albumid = $(this).attr('parentid');
|
||||
playSong('', this, songid, albumid);
|
||||
});
|
||||
$('table.songlist tr.song a.play').live('click', function (event) {
|
||||
var songid = $(this).parent().parent().attr('childid');
|
||||
var albumid = $(this).parent().parent().attr('parentid');
|
||||
playSong($(this).parent().parent(), songid, albumid);
|
||||
return false;
|
||||
});
|
||||
$('table.songlist tr.song a.add').live('click', function (event) {
|
||||
var track = $(this).parent().parent();
|
||||
$(track).clone().appendTo('#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('table.songlist tr.song a.remove').live('click', function (event) {
|
||||
var track = $(this).parent().parent();
|
||||
$(track).remove();
|
||||
refreshRowColor();
|
||||
return false;
|
||||
});
|
||||
$('table.songlist tr.song a.rate').live('click', function (event) {
|
||||
var songid = $(this).parent().parent().attr('childid');
|
||||
rateSong(songid, 5);
|
||||
$(this).removeClass('rate');
|
||||
$(this).addClass('favorite');
|
||||
return false;
|
||||
});
|
||||
$('table.songlist tr.song a.favorite').live('click', function (event) {
|
||||
var songid = $(this).parent().parent().attr('childid');
|
||||
rateSong(songid, 0);
|
||||
$(this).removeClass('favorite');
|
||||
$(this).addClass('rate');
|
||||
return false;
|
||||
});
|
||||
$('li.index').live('click', function (e) {
|
||||
$('#Artists').stop().scrollTo('#auto', 400);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Music Library Click Events
|
||||
$('a#action_AddToPlaylist').click(function () {
|
||||
var submenu = $('div#submenu_AddToPlaylist');
|
||||
if (submenu.is(":visible")) {
|
||||
submenu.fadeOut();
|
||||
} else {
|
||||
loadPlaylistsForMenu('submenu_AddToPlaylist');
|
||||
//get the position of the placeholder element
|
||||
pos = $(this).offset();
|
||||
width = $(this).width();
|
||||
height = $(this).height();
|
||||
//show the menu directly over the placeholder
|
||||
submenu.css({ "left": (pos.left) + "px", "top": (pos.top + height + 14) + "px" }).fadeIn(400);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
var submenu_active = false;
|
||||
$('div.submenu').mouseenter(function () {
|
||||
submenu_active = true;
|
||||
});
|
||||
$('div.submenu').mouseleave(function () {
|
||||
submenu_active = false;
|
||||
setTimeout(function () { if (submenu_active == false) $('div.submenu').fadeOut(); }, 400);
|
||||
});
|
||||
$('a#action_AddToCurrent').click(function () {
|
||||
addToCurrent();
|
||||
return false;
|
||||
});
|
||||
$('#action_RefreshArtists').click(function () {
|
||||
loadArtists("", true);
|
||||
return false;
|
||||
});
|
||||
$('#action_IncreaseWidth').click(function () {
|
||||
resizeSMSection(50);
|
||||
return false;
|
||||
});
|
||||
$('#action_DecreaseWidth').click(function () {
|
||||
resizeSMSection(-50);
|
||||
return false;
|
||||
});
|
||||
$('#action_SelectAll').click(function () {
|
||||
$('#Albums tr.song').each(function () {
|
||||
$(this).addClass('selected');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('#action_SelectNone').click(function () {
|
||||
$('#Albums tr.song').each(function () {
|
||||
$(this).removeClass('selected');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('input#Search').keydown(function (e) {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
if (unicode == 13) {
|
||||
$('#action_Search').click();
|
||||
}
|
||||
});
|
||||
$('#action_Search').click(function () {
|
||||
var query = $('#Search').val();
|
||||
search('song', query);
|
||||
$('#Search').val("");
|
||||
return false;
|
||||
});
|
||||
// Current Playlist Click Events
|
||||
$('#action_Shuffle').live('click', function () {
|
||||
$('#CurrentPlaylistContainer tr.song').shuffle();
|
||||
refreshRowColor();
|
||||
return false;
|
||||
});
|
||||
$('#action_Empty').live('click', function () {
|
||||
$('#CurrentPlaylistContainer tbody').empty();
|
||||
return false;
|
||||
});
|
||||
$('a#action_AddCurrentToPlaylist').click(function () {
|
||||
var submenu = $('div#submenu_AddCurrentToPlaylist');
|
||||
if (submenu.is(":visible")) {
|
||||
submenu.fadeOut();
|
||||
} else {
|
||||
loadPlaylistsForMenu('submenu_AddCurrentToPlaylist');
|
||||
//get the position of the placeholder element
|
||||
pos = $(this).offset();
|
||||
width = $(this).width();
|
||||
height = $(this).height();
|
||||
//show the menu directly over the placeholder
|
||||
submenu.css({ "left": (pos.left) + "px", "top": (pos.top + height + 14) + "px" }).fadeIn(400);
|
||||
}
|
||||
});
|
||||
$('#action_CurrentSelectAll').click(function () {
|
||||
$('#CurrentPlaylist tr.song').each(function () {
|
||||
$(this).addClass('selected');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('#action_CurrentSelectNone').click(function () {
|
||||
$('#CurrentPlaylist tr.song').each(function () {
|
||||
$(this).removeClass('selected');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
// Playlist Click Events
|
||||
$('#AutoPlaylistContainer li.item').live('click', function () {
|
||||
$('#AutoPlaylistContainer li').removeClass('selected');
|
||||
$('#PlaylistContainer li').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
getRandomSongList('', '#TrackContainer');
|
||||
});
|
||||
$('#AutoPlaylistContainer li.item a.play').live('click', function () {
|
||||
getRandomSongList('autoplay', '#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('#AutoPlaylistContainer li.item a.add').live('click', function () {
|
||||
getRandomSongList('', '#CurrentPlaylistContainer');
|
||||
return false;
|
||||
});
|
||||
$('#PlaylistContainer li.item').live('click', function () {
|
||||
$('#AutoPlaylistContainer li').removeClass('selected');
|
||||
$('#PlaylistContainer li').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
getPlaylist($(this).attr("id"), '', '#TrackContainer tbody');
|
||||
});
|
||||
$('#PlaylistContainer li.item a.play').live('click', function () {
|
||||
getPlaylist($(this).parent().parent().attr("id"), 'autoplay', '#CurrentPlaylistContainer tbody');
|
||||
return false;
|
||||
});
|
||||
$('#PlaylistContainer li.item a.add').live('click', function () {
|
||||
getPlaylist($(this).parent().parent().attr("id"), '', '#CurrentPlaylistContainer tbody');
|
||||
return false;
|
||||
});
|
||||
$('#action_DeletePlaylist').click(function () {
|
||||
if ($('#PlaylistContainer li.selected').length > 0) {
|
||||
if (confirmDelete()) {
|
||||
$('#PlaylistContainer li.selected').each(function () {
|
||||
deletePlaylist($(this).attr("id"));
|
||||
});
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#action_SavePlaylist').click(function () {
|
||||
if ($('#PlaylistContainer li.selected').length > 0) {
|
||||
$('#PlaylistContainer li.selected').each(function () {
|
||||
savePlaylist($(this).attr("id"));
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#action_RemoveSongs').click(function () {
|
||||
if ($('#TrackContainer tr.selected').length > 0) {
|
||||
$('#TrackContainer tr.selected').each(function () {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#action_ShufflePlaylist').live('click', function () {
|
||||
$('#TrackContainer tr.song').shuffle();
|
||||
refreshRowColor();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Player Click Events
|
||||
$('#PlayTrack').live('click', function () {
|
||||
playPauseSong();
|
||||
return false;
|
||||
});
|
||||
$('#NextTrack').live('click', function () {
|
||||
var next = $('#CurrentPlaylistContainer tr.playing').next();
|
||||
changeTrack(next);
|
||||
return false;
|
||||
});
|
||||
$('#PreviousTrack').live('click', function () {
|
||||
var prev = $('#CurrentPlaylistContainer tr.playing').prev();
|
||||
changeTrack(prev);
|
||||
return false;
|
||||
});
|
||||
$("a#coverartimage").fancybox({
|
||||
'hideOnContentClick': true,
|
||||
'type': 'image'
|
||||
});
|
||||
|
||||
// Side Bar Click Events
|
||||
$('#action_ToggleSideBar').live('click', function () {
|
||||
if ($.cookie('sidebar')) {
|
||||
$.cookie('sidebar', null);
|
||||
$('#SideBar').hide();
|
||||
stopUpdateChatMessages();
|
||||
stopUpdateNowPlaying();
|
||||
} else {
|
||||
$.cookie('sidebar', true, { expires: 365 });
|
||||
$('#SideBar').show();
|
||||
updateChatMessages();
|
||||
updateNowPlaying();
|
||||
}
|
||||
resizeContent();
|
||||
return false;
|
||||
});
|
||||
$('input#ChatMsg').keydown(function (e) {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
if (unicode == 13) {
|
||||
var msg = $('#ChatMsg').val();
|
||||
if (msg != '') {
|
||||
addChatMessage(msg);
|
||||
}
|
||||
$('#ChatMsg').val("");
|
||||
}
|
||||
});
|
||||
|
||||
// Preferences Click Events
|
||||
$('#SavePreferences').live('click', function () {
|
||||
var username = $('#Username').val();
|
||||
var password = $('#Password').val();
|
||||
$.cookie('username', username, { expires: 365 });
|
||||
$.cookie('password', password, { expires: 365 });
|
||||
var AutoAlbumSize = $('#AutoAlbumSize').val();
|
||||
var AutoPlaylistSize = $('#AutoPlaylistSize').val();
|
||||
$.cookie('AutoAlbumSize', AutoAlbumSize, { expires: 365 });
|
||||
$.cookie('AutoPlaylistSize', AutoPlaylistSize, { expires: 365 });
|
||||
var server = $('#Server').val();
|
||||
if (server != "") {
|
||||
$.cookie('Server', server, { expires: 365 });
|
||||
}
|
||||
var applicationname = $('#ApplicationName').val();
|
||||
if (applicationname != "") {
|
||||
$.cookie('ApplicationName', applicationname, { expires: 365 });
|
||||
}
|
||||
location.reload(true);
|
||||
});
|
||||
$('#HideAZ').live('click', function () {
|
||||
if ($('#HideAZ').is(':checked')) {
|
||||
$.cookie('HideAZ', '1', { expires: 365 });
|
||||
$('#BottomContainer').hide();
|
||||
} else {
|
||||
$.cookie('HideAZ', null);
|
||||
$('#BottomContainer').show();
|
||||
}
|
||||
});
|
||||
$('#EnableNotifications').live('click', function () {
|
||||
if ($('#EnableNotifications').is(':checked')) {
|
||||
requestPermissionIfRequired();
|
||||
if (hasNotificationPermission()) {
|
||||
$.cookie('EnableNotifications', '1', { expires: 365 });
|
||||
}
|
||||
} else {
|
||||
$.cookie('EnableNotifications', null);
|
||||
}
|
||||
});
|
||||
$('#ScrollTitle').live('click', function () {
|
||||
if ($('#ScrollTitle').is(':checked')) {
|
||||
$.cookie('ScrollTitle', '1', { expires: 365 });
|
||||
}
|
||||
});
|
||||
$('input#Password').keydown(function (e) {
|
||||
var unicode = e.charCode ? e.charCode : e.keyCode;
|
||||
if (unicode == 13) {
|
||||
$('#SavePreferences').click();
|
||||
}
|
||||
});
|
||||
$('#ResetPreferences').live('click', function () {
|
||||
$.cookie('username', null);
|
||||
$.cookie('password', null);
|
||||
$.cookie('AutoAlbumSize', null);
|
||||
$.cookie('AutoPlaylistSize', null);
|
||||
$.cookie('Server', null);
|
||||
$.cookie('ApplicationName', null);
|
||||
$.cookie('HideAZ', null);
|
||||
location.reload(true);
|
||||
});
|
||||
$('#ChangeLogShowMore').live('click', function () {
|
||||
$('ul#ChangeLog li.log').each(function (i, el) {
|
||||
$(el).show();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
}); // End document.ready
|
149
style/Style.css
|
@ -43,69 +43,91 @@ h3.title
|
|||
}
|
||||
#nav
|
||||
{
|
||||
height: 36px;
|
||||
padding: 4px 0 0 52px;
|
||||
background: url('../images/subsonic-36.png') no-repeat 6px 2px;
|
||||
height: 127px;
|
||||
padding: 44px 0 0 0;
|
||||
background: url('../images/subsonic-36.png') no-repeat 6px 4px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 99;
|
||||
}
|
||||
#nav ul
|
||||
{
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0 0 0 5px;
|
||||
margin: 0 0 0 4px;
|
||||
}
|
||||
#nav li
|
||||
{
|
||||
width: 50px;
|
||||
}
|
||||
#nav a
|
||||
{
|
||||
display: block;
|
||||
padding: 6px 15px 5px 15px;
|
||||
margin: 0 2px -1px 0;
|
||||
float: left;
|
||||
padding: 13px 9px 13px 15px;
|
||||
color: #7C7C7C;
|
||||
letter-spacing: -1px;
|
||||
font-weight: bold;
|
||||
font-size: 17px;
|
||||
text-decoration: none;
|
||||
background: #f4f4f4;
|
||||
border-top: 1px solid #E4E4E4;
|
||||
border-left: 1px solid #E4E4E4;
|
||||
border-right: 1px solid #E4E4E4;
|
||||
}
|
||||
#nav a.active
|
||||
{
|
||||
color: #545454;
|
||||
background: #EDEDED;
|
||||
padding: 6px 15px 6px 15px;
|
||||
border-top: 1px solid #CBCBCB;
|
||||
border-left: 1px solid #CBCBCB;
|
||||
border-right: 1px solid #CBCBCB;
|
||||
border: 1px solid #E4E4E4;
|
||||
border-right: 1px solid #D5D5D5;
|
||||
border-bottom: none;
|
||||
}
|
||||
#nav a:hover
|
||||
{
|
||||
color: #545454;
|
||||
border-top: 1px solid #CBCBCB;
|
||||
border-left: 1px solid #CBCBCB;
|
||||
border-right: 1px solid #CBCBCB;
|
||||
border: 1px solid #D5D5D5;
|
||||
border-bottom: none;
|
||||
}
|
||||
#nav a.first
|
||||
{
|
||||
border-top: 1px solid #E4E4E4;
|
||||
}
|
||||
#nav a.first:hover
|
||||
{
|
||||
color: #545454;
|
||||
border: 1px solid #D5D5D5;
|
||||
border-bottom: none;
|
||||
}
|
||||
#nav a.last
|
||||
{
|
||||
border-bottom: 1px solid #E4E4E4;
|
||||
}
|
||||
#nav a.last:hover
|
||||
{
|
||||
color: #545454;
|
||||
border: 1px solid #D5D5D5;
|
||||
}
|
||||
#nav a.active
|
||||
{
|
||||
color: #545454;
|
||||
background: #ffffff;
|
||||
border: 1px solid #CBCBCB;
|
||||
border-right: none;
|
||||
}
|
||||
#nav a.active:hover
|
||||
{
|
||||
color: #545454;
|
||||
border: 1px solid #CBCBCB;
|
||||
border-right: none;
|
||||
}
|
||||
#nav a img
|
||||
{
|
||||
display: block;
|
||||
margin: 3px 0 4px 0;
|
||||
margin: 3px 0 4px 1px;
|
||||
}
|
||||
#nav a.active img
|
||||
{
|
||||
display: block;
|
||||
margin: 3px 0 4px 0;
|
||||
margin: 3px 0 4px 1px;
|
||||
}
|
||||
|
||||
#content
|
||||
{
|
||||
border-top: 1px solid #cbcbcb;
|
||||
background: #EDEDED;
|
||||
overflow: hidden;
|
||||
margin-top: -1px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
#content h2
|
||||
{
|
||||
|
@ -117,6 +139,7 @@ h3.title
|
|||
{
|
||||
min-height: 400px;
|
||||
min-width: 700px;
|
||||
margin-left: 53px;
|
||||
}
|
||||
.smsection
|
||||
{
|
||||
|
@ -129,8 +152,8 @@ h3.title
|
|||
background: #fff;
|
||||
border-right: 1px solid #cbcbcb;
|
||||
position: absolute;
|
||||
top: 79px;
|
||||
left: 6px;
|
||||
top: 39px;
|
||||
left: 60px;
|
||||
}
|
||||
.lgsection
|
||||
{
|
||||
|
@ -178,17 +201,24 @@ h3.title
|
|||
display: none;
|
||||
height: 35px;
|
||||
width: 40px;
|
||||
margin: 0 0 0 10px;
|
||||
margin: 0 0 0 7px;
|
||||
background: url('../images/ajax-loader.gif') no-repeat center center;
|
||||
float: left;
|
||||
}
|
||||
#messages
|
||||
{
|
||||
display: none;
|
||||
color: #A6CBF3;
|
||||
float: left;
|
||||
color: #4B95E5;
|
||||
float: right;
|
||||
font-size: 12px;
|
||||
padding: 9px 0 0 10px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
top: 0;
|
||||
right: 58px;
|
||||
background: #fff;
|
||||
border: 1px solid #A6CBF3;
|
||||
border-top: none;
|
||||
}
|
||||
/* Library Style */
|
||||
ul.simplelist
|
||||
|
@ -313,7 +343,7 @@ table.songlist tr.album
|
|||
}
|
||||
table.songlist tr.album td
|
||||
{
|
||||
padding: 4px;
|
||||
padding: 4px 0 0 2px;
|
||||
}
|
||||
table.songlist tr.album td.title
|
||||
{
|
||||
|
@ -323,7 +353,8 @@ table.songlist tr.album td.artist
|
|||
}
|
||||
table.songlist tr.album td.itemactions
|
||||
{
|
||||
width: 80px;
|
||||
width: 85px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
table.songlist tr.album td.albumart
|
||||
{
|
||||
|
@ -342,12 +373,11 @@ table.songlist tr.album a.play
|
|||
width: 20px;
|
||||
height: 50px;
|
||||
display: block;
|
||||
margin: 0 5px 0 0;
|
||||
background: url('../images/play_gl_6x8.png') no-repeat 6px center;
|
||||
background: url('../images/play_gl_6x8.png') no-repeat 7px center;
|
||||
}
|
||||
table.songlist tr.album a.play:hover
|
||||
{
|
||||
background: url('../images/play_6x8.png') no-repeat 6px center #DEECFB;
|
||||
background: url('../images/play_6x8.png') no-repeat 7px center #DEECFB;
|
||||
}
|
||||
table.songlist tr.album a.add
|
||||
{
|
||||
|
@ -355,13 +385,24 @@ table.songlist tr.album a.add
|
|||
width: 20px;
|
||||
height: 50px;
|
||||
display: block;
|
||||
margin: 0 5px 0 0;
|
||||
background: url('../images/plus_gl_8x8.png') no-repeat 6px center;
|
||||
}
|
||||
table.songlist tr.album a.add:hover
|
||||
{
|
||||
background: url('../images/plus_8x8.png') no-repeat 6px center #DEECFB;
|
||||
}
|
||||
table.songlist tr.album a.download
|
||||
{
|
||||
float: left;
|
||||
width: 20px;
|
||||
height: 50px;
|
||||
display: block;
|
||||
background: url('../images/download_gl_9x12.png') no-repeat 5px center;
|
||||
}
|
||||
table.songlist tr.album a.download:hover
|
||||
{
|
||||
background: url('../images/download_gd_9x12.png') no-repeat 5px center #DEECFB;
|
||||
}
|
||||
table.songlist tr.album a.remove
|
||||
{
|
||||
display: none;
|
||||
|
@ -371,13 +412,12 @@ table.songlist tr.album a.rate
|
|||
float: left;
|
||||
height: 50px;
|
||||
width: 20px;
|
||||
margin: 0 5px 0 0;
|
||||
display: block;
|
||||
background: url('../images/star_w_12x12.png') 2px center no-repeat;
|
||||
background: url('../images/star_wo_12x12.png') 2px center no-repeat;
|
||||
}
|
||||
table.songlist tr.album a.rate:hover
|
||||
{
|
||||
background: url('../images/star_wo_12x12.png') 2px center no-repeat;
|
||||
background: url('../images/star_lgo_12x12.png') 2px center no-repeat;
|
||||
}
|
||||
table.songlist tr.album a.favorite
|
||||
{
|
||||
|
@ -401,7 +441,7 @@ table.songlist tr.song td
|
|||
table.songlist tr.song td.itemactions
|
||||
{
|
||||
width: 80px;
|
||||
padding-left: 25px;
|
||||
padding-left: 22px;
|
||||
}
|
||||
table.songlist tr.song td.track
|
||||
{
|
||||
|
@ -438,11 +478,11 @@ table.songlist tr.song a.play
|
|||
height: 20px;
|
||||
display: block;
|
||||
margin: 0;
|
||||
background: url('../images/play_gl_6x8.png') no-repeat 6px center;
|
||||
background: url('../images/play_gl_6x8.png') no-repeat 7px center;
|
||||
}
|
||||
table.songlist tr.song a.play:hover
|
||||
{
|
||||
background: url('../images/play_6x8.png') no-repeat 6px center #DEECFB;
|
||||
background: url('../images/play_6x8.png') no-repeat 7px center #DEECFB;
|
||||
}
|
||||
table.songlist tr.song a.add
|
||||
{
|
||||
|
@ -464,11 +504,11 @@ table.songlist tr.song a.rate
|
|||
width: 20px;
|
||||
margin: 0;
|
||||
display: block;
|
||||
background: url('../images/star_w_12x12.png') center 3px no-repeat;
|
||||
background: url('../images/star_wo_12x12.png') center 3px no-repeat;
|
||||
}
|
||||
table.songlist tr.song a.rate:hover
|
||||
{
|
||||
background: url('../images/star_wo_12x12.png') center 3px no-repeat;
|
||||
background: url('../images/star_lgo_12x12.png') center 3px no-repeat;
|
||||
}
|
||||
table.songlist tr.song a.favorite
|
||||
{
|
||||
|
@ -572,6 +612,13 @@ background-color: #8dbdd8;
|
|||
text-decoration: underline;
|
||||
}
|
||||
.actions
|
||||
{
|
||||
width: 195px;
|
||||
height: 29px;
|
||||
margin: 4px 0 0 0;
|
||||
padding: 0 0 0 5px;
|
||||
}
|
||||
.subactions
|
||||
{
|
||||
height: 29px;
|
||||
margin: 4px 0 0 0;
|
||||
|
@ -612,7 +659,7 @@ background-color: #8dbdd8;
|
|||
display: none;
|
||||
width: 200px;
|
||||
position: fixed;
|
||||
top: 78px;
|
||||
top: 38px;
|
||||
right: 4px;
|
||||
background: none repeat scroll 0 0 #FFFFFF;
|
||||
border: 1px solid #CBCBCB;
|
||||
|
@ -700,10 +747,10 @@ background-color: #8dbdd8;
|
|||
/* Player Style */
|
||||
#player
|
||||
{
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border: 1px solid #cbcbcb;
|
||||
margin: 5px 0;
|
||||
margin-left: 55px;
|
||||
}
|
||||
#audiocontainer
|
||||
{
|
||||
|
@ -948,6 +995,10 @@ select
|
|||
margin: 5px;
|
||||
border: 1px solid #d6d6d6;
|
||||
}
|
||||
select#MusicFolders
|
||||
{
|
||||
width: 94%;
|
||||
}
|
||||
.submit
|
||||
{
|
||||
margin: 0 5px;
|
||||
|
|