|
@@ -30,9 +30,9 @@
|
|
<button class="ui right item icon AMmenu noBorder button" onClick="enterSearchMode();"><i class="search icon"></i></button>
|
|
<button class="ui right item icon AMmenu noBorder button" onClick="enterSearchMode();"><i class="search icon"></i></button>
|
|
<!-- <button class="ui right item icon AMmenu noBorder button"><i class="ellipsis vertical icon"></i></button> -->
|
|
<!-- <button class="ui right item icon AMmenu noBorder button"><i class="ellipsis vertical icon"></i></button> -->
|
|
</div>
|
|
</div>
|
|
-<div id="searchModeMenu" class="ui basic fluid AMmenu menu bottomBlue" style="z-index:85;position:fixed;top:0px;left:0px;width:100%;height:51px;display:none;">
|
|
|
|
|
|
+<div id="searchModeMenu" class="ui basic fluid AMmenu menu bottomBlue" style="z-index:85;position:fixed;top:0px;left:0px;width:100%;height:51px;display:none;margin-top: 0px;">
|
|
<button class="ui item icon noBorder AMmenu button" onClick="exitSearchMode();"><i class="arrow left icon"></i></button>
|
|
<button class="ui item icon noBorder AMmenu button" onClick="exitSearchMode();"><i class="arrow left icon"></i></button>
|
|
- <div class="ui fluid input" >
|
|
|
|
|
|
+ <div class="ui input" style="flex-grow: 1;">
|
|
<input id="searchInputBar" onkeypress="//handleSearchInputEnter(event);" type="text" style="background-color:rgb(48, 48, 48);border:0px !important;border-bottom:2px solid rgb(60, 60, 60) !important;margin-bottom:3px;color:white;" placeholder="Search Music">
|
|
<input id="searchInputBar" onkeypress="//handleSearchInputEnter(event);" type="text" style="background-color:rgb(48, 48, 48);border:0px !important;border-bottom:2px solid rgb(60, 60, 60) !important;margin-bottom:3px;color:white;" placeholder="Search Music">
|
|
</div>
|
|
</div>
|
|
<button class="ui right item icon AMmenu noBorder button" onClick="searchSong();"><i class="search icon"></i></button>
|
|
<button class="ui right item icon AMmenu noBorder button" onClick="searchSong();"><i class="search icon"></i></button>
|
|
@@ -372,6 +372,9 @@
|
|
var playingFileDetail = []; //[id, filepath]
|
|
var playingFileDetail = []; //[id, filepath]
|
|
var displayList = []; //This is the list where the current UI is displaying.
|
|
var displayList = []; //This is the list where the current UI is displaying.
|
|
var playingList = []; //This is the list where the player last clicked on an item to play
|
|
var playingList = []; //This is the list where the player last clicked on an item to play
|
|
|
|
+ var pagingEnabled = false; //Enable this when there are too many songs in list
|
|
|
|
+ var pagingCutoffCount = 100; //No. of songs to start paging
|
|
|
|
+ var currentPage = 0;
|
|
var randomMode = false;
|
|
var randomMode = false;
|
|
var repeatMode = 0; //Repeat mode 0 -> No repeat, 1 -> Repeat all 2 -> Repeat one
|
|
var repeatMode = 0; //Repeat mode 0 -> No repeat, 1 -> Repeat all 2 -> Repeat one
|
|
var updateSystemVolume = true;
|
|
var updateSystemVolume = true;
|
|
@@ -469,6 +472,14 @@
|
|
|
|
|
|
function loadNetworkView(){
|
|
function loadNetworkView(){
|
|
currentMode = "network";
|
|
currentMode = "network";
|
|
|
|
+ togglePagingMode(false);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function togglePagingMode(enabled=false){
|
|
|
|
+ if (pagingEnabled != enabled){
|
|
|
|
+ currentPage = 0;
|
|
|
|
+ }
|
|
|
|
+ pagingEnabled = enabled;
|
|
}
|
|
}
|
|
|
|
|
|
function initAudioListeners(){
|
|
function initAudioListeners(){
|
|
@@ -609,7 +620,7 @@
|
|
listSong: "search:" + keyword
|
|
listSong: "search:" + keyword
|
|
}, function(data){
|
|
}, function(data){
|
|
currentPath = "";
|
|
currentPath = "";
|
|
- var template = '<div class="mainList item" filepath={filepath} id={id} rawname={rawname}>\
|
|
|
|
|
|
+ var template = '<div class="mainList file item" filepath={filepath} id={id} rawname={rawname}>\
|
|
<div class="ui header selectable" style="margin:0px !important;" onClick="playSong(this);">\
|
|
<div class="ui header selectable" style="margin:0px !important;" onClick="playSong(this);">\
|
|
<img class="ui small image" src="img/eq.svg" style="margin-right: 0.2em;"></img>\
|
|
<img class="ui small image" src="img/eq.svg" style="margin-right: 0.2em;"></img>\
|
|
<div class="content whiteFont" style="padding-top:5px;line-height:1em;width : 80%;">\
|
|
<div class="content whiteFont" style="padding-top:5px;line-height:1em;width : 80%;">\
|
|
@@ -647,6 +658,7 @@
|
|
</div>');
|
|
</div>');
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
|
|
$("#interfaceTitle").text("Search");
|
|
$("#interfaceTitle").text("Search");
|
|
$("#AMmenuIcon").attr("class","search icon large whiteFont")
|
|
$("#AMmenuIcon").attr("class","search icon large whiteFont")
|
|
@@ -675,7 +687,9 @@
|
|
$("#mainList").append("<br><br><br><br><br><br><br>");
|
|
$("#mainList").append("<br><br><br><br><br><br><br>");
|
|
$("#interfaceDetails").text("[" + i + " songs]");
|
|
$("#interfaceDetails").text("[" + i + " songs]");
|
|
highLightPlayingMusic();
|
|
highLightPlayingMusic();
|
|
|
|
+ loadThumbnailToMusicList(".mainList.file.item");
|
|
});
|
|
});
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
function enterRemotePlayID(object){
|
|
function enterRemotePlayID(object){
|
|
@@ -1146,6 +1160,12 @@
|
|
|
|
|
|
updateMiniPlayerUI(displayName,info,id);
|
|
updateMiniPlayerUI(displayName,info,id);
|
|
|
|
|
|
|
|
+ //Check if page mode is enabled. If yes, do auto tab switch
|
|
|
|
+ if (pagingEnabled){
|
|
|
|
+ var targetPageNumber = getPageNumberByPlaybackId(parseInt(id));
|
|
|
|
+ switchToPage(targetPageNumber);
|
|
|
|
+ }
|
|
|
|
+
|
|
//Seperate out the filepath without media server path
|
|
//Seperate out the filepath without media server path
|
|
var fileVpath = filepath.split("=")[1];
|
|
var fileVpath = filepath.split("=")[1];
|
|
updateMainPlayerUI(displayName,info,id, fileVpath);
|
|
updateMainPlayerUI(displayName,info,id, fileVpath);
|
|
@@ -1195,6 +1215,12 @@
|
|
|
|
|
|
}else{
|
|
}else{
|
|
$("#" + thisFileItemID).find("img").attr("src","data:image/jpg;base64," + data);
|
|
$("#" + thisFileItemID).find("img").attr("src","data:image/jpg;base64," + data);
|
|
|
|
+ $(".dropdownList.file.item").each(function(){
|
|
|
|
+ var thisFilepath = JSON.parse(decodeURIComponent($(this).attr("filepath")));
|
|
|
|
+ if ($(this).attr("listid") == thisFileItemID && thisFilepath == filepath){
|
|
|
|
+ $(this).find("img").attr("src","data:image/jpg;base64," + data);
|
|
|
|
+ }
|
|
|
|
+ })
|
|
}
|
|
}
|
|
});
|
|
});
|
|
})
|
|
})
|
|
@@ -1273,7 +1299,17 @@
|
|
}
|
|
}
|
|
playingFileDetail = [id,filepath];
|
|
playingFileDetail = [id,filepath];
|
|
//Need not to update the playlist because it is the same
|
|
//Need not to update the playlist because it is the same
|
|
- highLightPlayingMusic();
|
|
|
|
|
|
+ if (pagingEnabled){
|
|
|
|
+ var targetPageNumber = getPageNumberByPlaybackId(parseInt(id));
|
|
|
|
+ switchToPage(targetPageNumber, function(){
|
|
|
|
+ highLightPlayingMusic();
|
|
|
|
+ parsePlayingSongList();
|
|
|
|
+ });
|
|
|
|
+ }else{
|
|
|
|
+ highLightPlayingMusic();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
}else{
|
|
}else{
|
|
//This is the only song in playlist. Play again from start
|
|
//This is the only song in playlist. Play again from start
|
|
audioElement[0].pause();
|
|
audioElement[0].pause();
|
|
@@ -1313,7 +1349,15 @@
|
|
}
|
|
}
|
|
playingFileDetail = [id,filepath];
|
|
playingFileDetail = [id,filepath];
|
|
//Need not to update the playlist because it is the same
|
|
//Need not to update the playlist because it is the same
|
|
- highLightPlayingMusic();
|
|
|
|
|
|
+ if (pagingEnabled){
|
|
|
|
+ var targetPageNumber = getPageNumberByPlaybackId(parseInt(id));
|
|
|
|
+ switchToPage(targetPageNumber, function(){
|
|
|
|
+ highLightPlayingMusic();
|
|
|
|
+ parsePlayingSongList();
|
|
|
|
+ });
|
|
|
|
+ }else{
|
|
|
|
+ highLightPlayingMusic();
|
|
|
|
+ }
|
|
}else{
|
|
}else{
|
|
//This is the only song in playlist. Play again from start
|
|
//This is the only song in playlist. Play again from start
|
|
audioElement[0].pause();
|
|
audioElement[0].pause();
|
|
@@ -1483,7 +1527,7 @@
|
|
${i + 1}
|
|
${i + 1}
|
|
</div>
|
|
</div>
|
|
<div class="mainList rightFunctionBar" type="file" align="center" onclick="showMore(this);">
|
|
<div class="mainList rightFunctionBar" type="file" align="center" onclick="showMore(this);">
|
|
- <i class="ellipsis vertical icon" style="top: 2em;"></i>
|
|
|
|
|
|
+ <i class="ellipsis vertical icon" style="margin-top:1.2em;"></i>
|
|
</div>
|
|
</div>
|
|
</div>`);
|
|
</div>`);
|
|
|
|
|
|
@@ -1581,6 +1625,7 @@
|
|
currentMode = "playlist";
|
|
currentMode = "playlist";
|
|
//Clear the main list
|
|
//Clear the main list
|
|
$("#mainList").html("");
|
|
$("#mainList").html("");
|
|
|
|
+ togglePagingMode(false);
|
|
ao_module_agirun("Music/functions/playlist.js", {
|
|
ao_module_agirun("Music/functions/playlist.js", {
|
|
opr: "root",
|
|
opr: "root",
|
|
},function(data){
|
|
},function(data){
|
|
@@ -1628,6 +1673,7 @@
|
|
</div>\
|
|
</div>\
|
|
</div>';
|
|
</div>';
|
|
$("#interfaceTitle").text("Storage");
|
|
$("#interfaceTitle").text("Storage");
|
|
|
|
+ togglePagingMode(false);
|
|
$("#AMmenuIcon").attr("class","folder open icon large whiteFont");
|
|
$("#AMmenuIcon").attr("class","folder open icon large whiteFont");
|
|
ao_module_agirun("Music/functions/listSong.js", {
|
|
ao_module_agirun("Music/functions/listSong.js", {
|
|
listdir: "root",
|
|
listdir: "root",
|
|
@@ -1894,15 +1940,7 @@
|
|
//Use back the previous method of filepath storage for compatibility
|
|
//Use back the previous method of filepath storage for compatibility
|
|
var filepath = $(this).attr("filepath");
|
|
var filepath = $(this).attr("filepath");
|
|
}
|
|
}
|
|
-
|
|
|
|
- /*
|
|
|
|
- if (id == playingFileDetail[0] && filepath == playingFileDetail[1]){
|
|
|
|
- //This piece of music is playing in the current list
|
|
|
|
- $(this).addClass("playingTrack");
|
|
|
|
- }else if (playingFileDetail[0] == -1 && filepath == playingFileDetail[1]){
|
|
|
|
- //This is for external accessed music playback. Music file might or might not exists in the current playlist. Try to highlight anyway
|
|
|
|
- $(this).addClass("playingTrack");
|
|
|
|
- }*/
|
|
|
|
|
|
+
|
|
//Id is ignored in the 9/9/2019 updates and only check if the path matches.
|
|
//Id is ignored in the 9/9/2019 updates and only check if the path matches.
|
|
if (filepath == playingFileDetail[1]){
|
|
if (filepath == playingFileDetail[1]){
|
|
$(this).addClass("playingTrack");
|
|
$(this).addClass("playingTrack");
|
|
@@ -2057,8 +2095,14 @@
|
|
|
|
|
|
//Get thumbnail from the current list to prevent re-loading form remote
|
|
//Get thumbnail from the current list to prevent re-loading form remote
|
|
let targetThumbnail = $("#" + (i + 1)).find("img").attr("src");
|
|
let targetThumbnail = $("#" + (i + 1)).find("img").attr("src");
|
|
|
|
+ let opacityShowing = "";
|
|
|
|
+ if ($("#" + (i + 1)).length == 0){
|
|
|
|
+ //Item not exists
|
|
|
|
+ targetThumbnail = "img/eq.svg";
|
|
|
|
+ opacityShowing = "opacity: 0.6;"
|
|
|
|
+ }
|
|
|
|
|
|
- $("#currentPlayingMainList").append(`<div class="dropdownList file item" filepath="${ao_module_utils.objectToAttr(playingList[i][0])}" listid="${i + 1}" rawname="${ao_module_utils.objectToAttr(playingList[i][1])}">
|
|
|
|
|
|
+ $("#currentPlayingMainList").append(`<div class="dropdownList file item" style="${opacityShowing}" filepath="${ao_module_utils.objectToAttr(playingList[i][0])}" listid="${i + 1}" rawname="${ao_module_utils.objectToAttr(playingList[i][1])}">
|
|
<div class="ui header selectable" style="margin:0px !important;" onClick="playSongFromDropdownList(this);">
|
|
<div class="ui header selectable" style="margin:0px !important;" onClick="playSongFromDropdownList(this);">
|
|
<img class="ui small image" src="${targetThumbnail}" style="margin-right: 0.2em;"></img>
|
|
<img class="ui small image" src="${targetThumbnail}" style="margin-right: 0.2em;"></img>
|
|
<div class="content whiteFont" style="padding-top:5px;line-height:1em;width : 80%;">
|
|
<div class="content whiteFont" style="padding-top:5px;line-height:1em;width : 80%;">
|
|
@@ -2104,13 +2148,32 @@
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- console.log(displayList);
|
|
|
|
-
|
|
|
|
- if (playingList == []){
|
|
|
|
|
|
+
|
|
|
|
+ //Updates 2022-07-12: Check if the list is too long. If yes, use paging
|
|
|
|
+ let renderRange = [0,displayList.length];
|
|
|
|
+
|
|
|
|
+ if (displayList.length > pagingCutoffCount){
|
|
|
|
+ togglePagingMode(true);
|
|
|
|
+ renderRange = [0, pagingCutoffCount];
|
|
|
|
+ }else{
|
|
|
|
+ togglePagingMode(false);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (playingList == []){
|
|
playingList = Array.from(displayList);
|
|
playingList = Array.from(displayList);
|
|
}
|
|
}
|
|
- $("#mainList").html("");
|
|
|
|
- for ( var i =0; i < displayList.length; i++){
|
|
|
|
|
|
+
|
|
|
|
+ renderDisplayList(displayList,renderRange[0], renderRange[1] );
|
|
|
|
+
|
|
|
|
+ }, function(){
|
|
|
|
+ alert("Failed to access listSong API with type: " + type)
|
|
|
|
+ });
|
|
|
|
+ hideLeftMenu();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function renderDisplayList(displayList, start, end, callback=undefined){
|
|
|
|
+ $("#mainList").html("");
|
|
|
|
+ for ( var i =start; i < end; i++){
|
|
var songInfo = displayList[i];
|
|
var songInfo = displayList[i];
|
|
var path = songInfo[0];
|
|
var path = songInfo[0];
|
|
var displayname = ao_module_codec.decodeUmFilename(songInfo[1]);
|
|
var displayname = ao_module_codec.decodeUmFilename(songInfo[1]);
|
|
@@ -2132,18 +2195,82 @@
|
|
</div>
|
|
</div>
|
|
</div>`);
|
|
</div>`);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (pagingEnabled){
|
|
|
|
+ //Append the page switch buttons
|
|
|
|
+ let numberOfPages = Math.ceil(parseFloat(displayList.length) / parseFloat(pagingCutoffCount));
|
|
|
|
+ let pageSelector = "";
|
|
|
|
+ for (var i = 0; i < numberOfPages; i++){
|
|
|
|
+ pageSelector = pageSelector + `<button onclick="switchToPage(${i});" class="inverted ui icon button" style="border: 0px solid transparent; box-shadow: none !important; -webkit-box-shadow: none !important;">
|
|
|
|
+ ${i + 1}
|
|
|
|
+ </button>`;
|
|
|
|
+ }
|
|
|
|
+ $("#mainList").append(`<div class="mainList item" style="cursor: unset;">
|
|
|
|
+ <div>${pageSelector}</div>
|
|
|
|
+ </div>`);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
totalMusicCount = displayList.length;
|
|
totalMusicCount = displayList.length;
|
|
$("#mainList").append("<br><br><br><br><br><br><br>");
|
|
$("#mainList").append("<br><br><br><br><br><br><br>");
|
|
- $("#interfaceDetails").text("[" + i + " songs]");
|
|
|
|
|
|
+ $("#interfaceDetails").text("[" + totalMusicCount + " songs]");
|
|
highLightPlayingMusic();
|
|
highLightPlayingMusic();
|
|
|
|
|
|
|
|
+
|
|
//Load thumbnail for song in list
|
|
//Load thumbnail for song in list
|
|
loadThumbnailToMusicList();
|
|
loadThumbnailToMusicList();
|
|
|
|
|
|
- }, function(){
|
|
|
|
- alert("Failed to access listSong API with type: " + type)
|
|
|
|
- });
|
|
|
|
- hideLeftMenu();
|
|
|
|
|
|
+ if (callback != undefined){
|
|
|
|
+ callback();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function switchToPage(pageNumber, callback=undefined){
|
|
|
|
+ if (!pagingEnabled){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ let thisCallback = callback;
|
|
|
|
+ if (pageNumber == currentPage){
|
|
|
|
+ //Already in that page
|
|
|
|
+ if (thisCallback != undefined){
|
|
|
|
+ callback();
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ currentPage = pageNumber;
|
|
|
|
+
|
|
|
|
+ let startPage = pageNumber * pagingCutoffCount;
|
|
|
|
+ let endPage = startPage + pagingCutoffCount;
|
|
|
|
+ if (endPage > displayList.length){
|
|
|
|
+ endPage = displayList.length;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (thisCallback == undefined){
|
|
|
|
+ renderDisplayList(displayList, startPage, endPage, function(){
|
|
|
|
+ window.scrollTo(0, document.body.scrollHeight);
|
|
|
|
+ });
|
|
|
|
+ }else{
|
|
|
|
+ renderDisplayList(displayList, startPage, endPage,thisCallback);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function getPageNumberByPlaybackId(id){
|
|
|
|
+ let numberOfPages = Math.ceil(parseFloat(displayList.length) / parseFloat(pagingCutoffCount));
|
|
|
|
+ let targetPageNo = Math.ceil(id / pagingCutoffCount) - 1;
|
|
|
|
+ return targetPageNo;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function getPageStartAndEndByPageNumber(pageNumber){
|
|
|
|
+ let startPage = pageNumber * pagingCutoffCount;
|
|
|
|
+ let endPage = startPage + pagingCutoffCount;
|
|
|
|
+ if (endPage > displayList.length){
|
|
|
|
+ endPage = displayList.length;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return [startPage, endPage];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|