Browse Source

Fixed Music Playlist paging bug

Toby Chui 3 năm trước cách đây
mục cha
commit
e24d4862d4

+ 1 - 0
mod/filesystem/abstractions/smbfs/smbfs.go

@@ -311,6 +311,7 @@ func (a ServerMessageBlockFileSystemAbstraction) ReadStream(filename string) (io
 	return f, nil
 }
 
+//Note that walk on SMB is super slow. Avoid using this if possible.
 func (a ServerMessageBlockFileSystemAbstraction) Walk(root string, walkFn filepath.WalkFunc) error {
 	root = toWinPath(filterFilepath(root))
 	err := fs.WalkDir(a.share.DirFS(root), ".", func(path string, d fs.DirEntry, err error) error {

+ 62 - 10
mod/share/share.go

@@ -38,6 +38,7 @@ import (
 	"imuslab.com/arozos/mod/auth"
 	"imuslab.com/arozos/mod/common"
 	filesystem "imuslab.com/arozos/mod/filesystem"
+	"imuslab.com/arozos/mod/filesystem/arozfs"
 	"imuslab.com/arozos/mod/filesystem/metadata"
 	"imuslab.com/arozos/mod/share/shareEntry"
 	"imuslab.com/arozos/mod/user"
@@ -525,9 +526,27 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
 					w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
 					//http.ServeFile(w, r, targetFilepath)
 
-					f, _ := targetFshAbs.ReadStream(targetFilepath)
-					io.Copy(w, f)
-					f.Close()
+					if targetFsh.RequireBuffer {
+						f, err := targetFshAbs.ReadStream(targetFilepath)
+						if err != nil {
+							w.WriteHeader(http.StatusInternalServerError)
+							w.Write([]byte("500 - Internal Server Error: " + err.Error()))
+							return
+						}
+						defer f.Close()
+						io.Copy(w, f)
+					} else {
+						f, err := targetFshAbs.Open(targetFilepath)
+						if err != nil {
+							w.WriteHeader(http.StatusInternalServerError)
+							w.Write([]byte("500 - Internal Server Error: " + err.Error()))
+							return
+						}
+						defer f.Close()
+						fi, _ := f.Stat()
+						http.ServeContent(w, r, arozfs.Base(targetFilepath), fi.ModTime(), f)
+					}
+
 				} else {
 					//Download this folder as zip
 					//Create a zip using ArOZ Zipper, tmp zip files are located under tmp/share-cache/*.zip
@@ -693,18 +712,51 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
 					//This file exists in local file system. Serve it directly
 					http.ServeFile(w, r, fileRuntimeAbsPath)
 				} else {
-					//This file is not on local file system. Use streaming
-					f, _ := targetFshAbs.ReadStream(fileRuntimeAbsPath)
-					io.Copy(w, f)
-					f.Close()
+					if targetFsh.RequireBuffer {
+						f, err := targetFshAbs.ReadStream(fileRuntimeAbsPath)
+						if err != nil {
+							w.WriteHeader(http.StatusInternalServerError)
+							w.Write([]byte("500 - Internal Server Error: " + err.Error()))
+							return
+						}
+						defer f.Close()
+						io.Copy(w, f)
+					} else {
+						f, err := targetFshAbs.Open(fileRuntimeAbsPath)
+						if err != nil {
+							w.WriteHeader(http.StatusInternalServerError)
+							w.Write([]byte("500 - Internal Server Error: " + err.Error()))
+							return
+						}
+						defer f.Close()
+						fi, _ := f.Stat()
+						http.ServeContent(w, r, arozfs.Base(fileRuntimeAbsPath), fi.ModTime(), f)
+					}
 				}
 			} else if directServe {
 				w.Header().Set("Access-Control-Allow-Origin", "*")
 				w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
 				w.Header().Set("Content-Type", contentType)
-				f, _ := targetFshAbs.ReadStream(fileRuntimeAbsPath)
-				io.Copy(w, f)
-				f.Close()
+				if targetFsh.RequireBuffer {
+					f, err := targetFshAbs.ReadStream(fileRuntimeAbsPath)
+					if err != nil {
+						w.WriteHeader(http.StatusInternalServerError)
+						w.Write([]byte("500 - Internal Server Error: " + err.Error()))
+						return
+					}
+					defer f.Close()
+					io.Copy(w, f)
+				} else {
+					f, err := targetFshAbs.Open(fileRuntimeAbsPath)
+					if err != nil {
+						w.WriteHeader(http.StatusInternalServerError)
+						w.Write([]byte("500 - Internal Server Error: " + err.Error()))
+						return
+					}
+					defer f.Close()
+					fi, _ := f.Stat()
+					http.ServeContent(w, r, arozfs.Base(fileRuntimeAbsPath), fi.ModTime(), f)
+				}
 			} else {
 				//Serve the download page
 				content, err := ioutil.ReadFile("./system/share/downloadPage.html")

+ 1 - 1
web/Music/functions/listSong.js

@@ -85,7 +85,7 @@ function handleUserRequest(){
                 var musicFiles = [];
                 for (var i = 0; i < musicDis.length; i++){
                     var thisFileLib = musicDis[i];
-                    var allfilelist = filelib.walk(thisFileLib, "file");
+                    var allfilelist = filelib.walk(thisFileLib + "Music/", "file");
                     for (var k = 0; k < allfilelist.length; k++){
                         var ext = allfilelist[k].split('.').pop();
                         if (IsSupportExt(ext) == true && !IsMetaFile(allfilelist[k])){

+ 58 - 8
web/Music/index.html

@@ -373,8 +373,10 @@
 	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 pagingEnabled = false; //Enable this when there are too many songs in list
+	var pagingEnableForPlayingList = false; 
 	var pagingCutoffCount = 100; //No. of songs to start paging
 	var currentPage = 0;
+	var currentPlayingPage = 0;
 	var randomMode = false;
 	var repeatMode = 0; //Repeat mode 0 -> No repeat, 1 -> Repeat all 2 -> Repeat one
 	var updateSystemVolume = true;
@@ -676,6 +678,8 @@
 		displayList = data;
 		if (playingList == []){
 			playingList = Array.from(displayList);
+			pagingEnableForPlayingList = pagingEnabled;
+			currentPlayingPage = currentPage;
 		}
 		$("#mainList").html("");
 		for ( var i =0; i < data.length; i++){
@@ -1192,6 +1196,8 @@
 		//Only backup when it is not call from dropdown list
 		if (!$(object).parent().hasClass("dropdownList")){
 			playingList = Array.from(displayList);
+			pagingEnableForPlayingList = pagingEnabled;
+			currentPlayingPage = currentPage;
 		}
 	    parsePlayingSongList();
 	    if ($("#miniPlayer").hasClass("hidden")){
@@ -2086,6 +2092,13 @@
 			//This song already playing. Ignore play request.
 			return;
 		}
+
+		if (pagingEnableForPlayingList && $(object).attr("targetPage") != currentPlayingPage){
+			let newPage = parseInt($(object).attr("targetPage"));
+			if (!isNaN(newPage)){
+				currentPlayingPage = newPage;
+			}
+		}
 		playSong(object);
 		//Check if the song is also in main list. If yes, highlight it as well
 		/*
@@ -2106,10 +2119,16 @@
 		var counter = playingList.length;
 		var totalSize = 0.0;
 		var renderRange = [0, playingList.length];
-		if (pagingEnabled){
+		var pageKeepRange = [0, playingList.length]
+		if (pagingEnableForPlayingList){
 			//Paging Enabled. Only show 1/2 max + current page song + 1/2 max
-			var startEndRange = getPageStartAndEndByPageNumber(currentPage);
+			var startEndRange = getPageStartAndEndByPageNumber(currentPlayingPage, playingList);
 			startEndRange = [startEndRange[0] - pagingCutoffCount /2, startEndRange[1] + pagingCutoffCount / 2]
+			//console.log("DEFAULT START END RANGE", startEndRange)
+			//page keep range is the middle 1/2 number of songs, [1/4 => prev page][1/2][1/4 => next page]
+			pageKeepRange[0] = startEndRange[0] + pagingCutoffCount / 2;
+			pageKeepRange[1] = startEndRange[1] - pagingCutoffCount / 2;
+			
 			if (startEndRange[0] < 0){
 				startEndRange[0] = 0;
 			}
@@ -2119,6 +2138,16 @@
 			}
 
 			renderRange = startEndRange;
+			
+			
+
+			if (pageKeepRange[0] < 0){
+				pageKeepRange[0] = 0;
+			}
+			if (pageKeepRange[1] > playingList.length){
+				pageKeepRange[1] = playingList.length;
+			}
+			//console.log("KEEP RANGE", pageKeepRange);
 		}
 
 		for (var i = renderRange[0]; i < renderRange[1]; i++){
@@ -2142,12 +2171,31 @@
 				//Item not exists
 				targetThumbnail = "img/eq.svg";
 				opacityShowing = "opacity: 0.6;"
+			}else if (pagingEnableForPlayingList){
+				if (i < pageKeepRange[0] || i > pageKeepRange[1]){
+					//Out of paging range. Do hidden display
+					targetThumbnail = "img/eq.svg";
+					opacityShowing = "opacity: 0.6;"
+				}else{
+					targetThumbnail = `../system/file_system/loadThumbnail?bytes=true&vpath=${encodeURIComponent(realVpath)}`;
+				}
 			}else{
+				//Non paging list. Always do all thumbnails.
 				targetThumbnail = `../system/file_system/loadThumbnail?bytes=true&vpath=${encodeURIComponent(realVpath)}`;
 			}
 
+			let targetPage = currentPlayingPage;
+			if (i < pageKeepRange[0]){
+				targetPage -= 1;
+			}
+			if (i > pageKeepRange[1]){
+				targetPage += 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);" targetPage="${targetPage}">
 					<img class="ui small image" src="${targetThumbnail}" onError="replaceImageToDefault(this);" style="margin-right: 0.2em;"></img>
 					<div class="content whiteFont" style="padding-top:5px;line-height:1em;width : 80%;">
 						<span style="font-weight: lighter;">${displayname}</span>
@@ -2209,6 +2257,8 @@
 
 			if (playingList == []){
 	            playingList = Array.from(displayList);
+				pagingEnableForPlayingList = pagingEnabled;
+				currentPlayingPage = currentPage;
 	        }
 
 			renderDisplayList(displayList,renderRange[0], renderRange[1] );
@@ -2316,11 +2366,11 @@
 		return targetPageNo;
 	}
 
-	function getPageStartAndEndByPageNumber(pageNumber){
+	function getPageStartAndEndByPageNumber(pageNumber, targetList){
 		let startPage = pageNumber * pagingCutoffCount;
 		let endPage = startPage + pagingCutoffCount;
-		if (endPage > displayList.length){
-			endPage = displayList.length;
+		if (endPage > targetList.length){
+			endPage = targetList.length;
 		}
 
 		return [startPage, endPage];
@@ -2329,7 +2379,7 @@
 	
 	function toggleLeftMenu(){
 		if (leftMenuShown){
-			$("#leftSideBar").animate({left: $("#leftSideBar").width() * -1}, 300,function(){
+			$("#leftSideBar").animate({left: $("#leftSideBar").width() * -1}, 120,function(){
 				$("#leftSideBar").hide();
 			});
 			$("#sideBarCover").fadeOut();
@@ -2345,7 +2395,7 @@
 	
 	function hideLeftMenu(){
 	    if (leftMenuShown){
-	        $("#leftSideBar").animate({left: $("#leftSideBar").width() * -1}, 300,function(){
+	        $("#leftSideBar").animate({left: $("#leftSideBar").width() * -1}, 120,function(){
 				$("#leftSideBar").hide();
 			});
 			$("#sideBarCover").fadeOut();