Browse Source

Added external playlist load for AirMUsic

Toby Chui 2 years ago
parent
commit
3c1130cee8

+ 101 - 27
web/Music/index.html

@@ -452,40 +452,101 @@
 	});
 
 	function returnToPreviousState(){
-		var hash = window.location.hash;
-		if (hash != ""){
-			//There are state to restore. Restore using the given hash value
-			hash = decodeURIComponent(hash.substring(1));
-			var previousState = JSON.parse(hash);
-			console.log(previousState);
-			var currentPath = previousState.path;
-			var playingFileDetail = previousState.pfp;
-			var initPauseState = previousState.pause;
-			if (currentPath != ""){
-				//Create a dummy folder and trick the system to load to the previous states
-				var a = '<div></div>';
-				a = $(a).attr("filepath",currentPath);
-				openFolder(a[0],{
-					playIDAfterOpen: playingFileDetail[0],
-					startPaused: initPauseState}
-				);
+		var inputFiles = ao_module_loadInputFiles();
+		if (inputFiles == null){
+			//It doesn't seems like is an input file. 
+			//Fall back to legacy process
+			var hash = window.location.hash;
+			if (hash != ""){
+				//There are state to restore. Restore using the given hash value
+				hash = decodeURIComponent(hash.substring(1));
+				var previousState = JSON.parse(hash);
+				console.log(previousState);
+				var currentPath = previousState.path;
+				var playingFileDetail = previousState.pfp;
+				var initPauseState = previousState.pause;
+				if (currentPath != ""){
+					//Create a dummy folder and trick the system to load to the previous states
+					var a = '<div></div>';
+					a = $(a).attr("filepath",currentPath);
+					openFolder(a[0],{
+						playIDAfterOpen: playingFileDetail[0],
+						startPaused: initPauseState}
+					);
+				}else{
+					//currentpath is empty, aka Music Mode
+					loadSongList();
+				}
+				
 			}else{
-				//currentpath is empty, aka Music Mode
-				loadSongList();
+				//No state to restore. Restore Viewing Tab instead.
+				var vt = loadStorage("viewingTab");
+				if (vt != ""){
+					if (vt == "music"){
+						loadSongList();
+						
+					}else if(vt == "folder"){
+						loadFolderView();
+						
+					}else if(vt == "playlist"){
+						loadPlaylistView();
+						
+					}else if(vt == "network"){
+						loadNetworkView();
+					}
+				}else{
+					//Default action
+					loadSongList();
+				}
 			}
-			
 		}else{
-			//No state to restore. Restore Viewing Tab instead.
+			//It is a ArozOS 1.0+ file loading hash. 
+			//load the file as search mode
+		
+			let loadInputfileCallback = function(){
+				enterSearchMode();
+				$("#mainList").html("");
+				let idCounter = 0;
+				inputFiles.forEach(function(musicFile){
+					let songTitle = musicFile.filename.split(".").shift();
+					$("#mainList").append(`<div class="mainList file item" filepath="${ao_module_utils.objectToAttr("/media?file=" + musicFile.filepath)}" id="${idCounter + 1}" rawname=${ao_module_utils.objectToAttr(songTitle)}>
+						<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>
+							<div class="content whiteFont" style="padding-top:5px;line-height:1em;width : 80%;">
+								${songTitle}
+								<div class="sub header fileinfo" style="color: #c7c7c7;">Loaded by external module</div>
+							</div>
+						</div>
+						<div class="topRightCorner" align="center">
+							${idCounter + 1}
+						</div>
+					</div>`);
+
+					//Build the playlist
+					displayList.push([
+						"/media?file=" + musicFile.filepath,
+						songTitle,
+						musicFile.filename.split(".").pop(),
+						"External",
+					]);
+
+					idCounter++;
+				});
+
+				loadThumbnailToMusicList();
+			}
+			
+
 			var vt = loadStorage("viewingTab");
 			if (vt != ""){
 				if (vt == "music"){
-					loadSongList();
+					loadSongList(undefined, loadInputfileCallback);
 					
 				}else if(vt == "folder"){
-					loadFolderView();
+					loadFolderView(loadInputfileCallback);
 					
 				}else if(vt == "playlist"){
-					loadPlaylistView();
+					loadPlaylistView(loadInputfileCallback);
 					
 				}else if(vt == "network"){
 					loadNetworkView();
@@ -494,6 +555,7 @@
 				//Default action
 				loadSongList();
 			}
+
 		}
 	}
 
@@ -1862,7 +1924,7 @@
 	}
 
 	//List the number of playlist stored in this database
-	function loadPlaylistView(){
+	function loadPlaylistView(callback=undefined){
 		currentMode = "playlist";
 		//Clear the main list
 		$("#mainList").html("");
@@ -1894,11 +1956,15 @@
 			$("#interfaceTitle").text("Playlist");
 			$("#AMmenuIcon").attr("class","list icon large whiteFont");
 			$("#interfaceDetails").text("[" + data.length + " playlist]");
+
+			if (callback != undefined){
+				callback();
+			}
 		});
 		
 	}
 	
-	function loadFolderView(){
+	function loadFolderView(callback=undefined){
 		currentMode = "folder";
 	    currentPath = "";
 	    var tempalte = '<div class="mainList item" filepath={filepath} id={id} tag="folder" onClick="openFolder(this);">\
@@ -1962,6 +2028,10 @@
 	            $("#mainList").append(box);
 	        }
 	        $("#interfaceDetails").text("[" + data.length + " folders]");
+
+			if (callback != undefined){
+				callback();
+			}
 	    });
 	    hideLeftMenu();
 	}
@@ -2547,7 +2617,7 @@
 		$(target).attr('src', "img/eq.svg");
 	}
 	
-	function loadSongList(type = "all"){
+	function loadSongList(type = "all", callback=undefined){
 		currentPath = "";
 		currentMode = "music";
     
@@ -2589,6 +2659,10 @@
 
 			renderDisplayList(displayList,renderRange[0], renderRange[1] );
 
+			if (callback != undefined){
+				callback();
+			}
+
 	    }, function(){
 			alert("Failed to access listSong API with type: " + type)
 		});

+ 1 - 0
web/Music/main.css

@@ -11,6 +11,7 @@ body{
 }
 p,span,h1,h2,h3,h4,h5,h6,div,a,button{
     font-family: "Microsoft JhengHei","SimHei", "Apple LiGothic Medium", "STHeiti";
+    font-weight: 300;
 }
 
 .AMmenu{

+ 11 - 1
web/SystemAO/file_system/file_explorer.html

@@ -3425,7 +3425,17 @@
 
                 //Directly passing the file information to the startdir
                 fileHash = encodeURIComponent(JSON.stringify(filelist));
-                window.open("../../" + targetModuleInfo.StartDir + "#" + fileHash);
+                console.log(targetModuleInfo);
+
+                if (targetModuleInfo.StartDir == ""){
+                    //Not a module supporting fw mode
+                    if (targetModuleInfo.SupportEmb == true && targetModuleInfo.LaunchEmb != ""){
+                        window.open("../../" + targetModuleInfo.LaunchEmb + "#" + fileHash);
+                    }
+                }else{
+                    window.open("../../" + targetModuleInfo.StartDir + "#" + fileHash);
+                }
+                
                 hideAllPopupWindows();
             }
 

+ 563 - 563
web/SystemAO/utilities/audio.html

@@ -1,564 +1,564 @@
-<!DOCTYPE html>
-<meta name="apple-mobile-web-app-capable" content="yes" />
-<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=0.6, maximum-scale=0.6"/>
-<html>
-<head>
-<meta charset="UTF-8">
-<script type='text/javascript' charset='utf-8'>
-</script>
-<title>ArOZ Onlineβ</title>
-<link rel="stylesheet" href="../../script/semantic/semantic.min.css">
-<script src="../../script/semantic/semantic.min.js"></script>
-<script src="../../script/jquery.min.js"></script>
-<script src="../../script/ao_module.js"></script>
-<style>
-.transparent{
-	background-color:rgba(255, 255, 255, 0) !important;
-	border:1px solid transparent;
-}
-
-.seventytransparent{
-	background-color:rgba(255, 255, 255, 0.7) !important;
-	border:1px solid transparent;
-}
-body {
-	background: rgba(255,255,255,1);
-}
-
-#songname{
-	clear: both;
-    display: inline-block;
-    overflow: hidden;
-    white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-</style>
-</head>
-<body>
-
-    <div >
-		<!-- Audio Control System with no HTML5 Audio Attribute-->
-		<div>
-			<div id="audio_attr"style="display:none;">
-			<audio id="player" controls autoplay>
-			  <source src="" type="audio/mpeg">
-				Your browser does not support the audio element.
-			</audio>
-			</div>
-			<div id="YamiPlayer" class="content transparent" style="top:0;">
-			<div id="songname" class="ui top attached segment" style="border: 1px solid transparent;">
-				<i class="music icon"></i> 
-			</div>
-			<div id="progressbardiv" class="ui attached progress" style="height: 1em; background-color: #eeeeee;">
-				<div id="audioprogress" class="bar" style="min-width: 0px; width: 0%; height: 1em;"></div>
-			</div>
-			<div style="background-color: white; margin-top: 5px;">
-				<div style="display: flex; flex-wrap: nowrap;">
-					<div class="ui icon buttons" style="margin-left: 12px;">
-						<!-- <button class="ui disabled button" onclick="PreviousSong()"><i class="step backward icon"></i></button> -->
-						<button class="ui basic black button" onclick="playbtn()"><i id='playbtn' class="pause icon"></i></button>
-						<!-- <button class="ui disabled button" onclick="NextSong()"><i class="step forward icon"></i></button> -->
-						<button class="ui basic black button" onclick="stopbtn()"><i class="stop icon"></i></button>
-						<button class="ui basic black button" onclick="volDown()"><i class="volume down icon"></i></button>
-						<button class="ui basic black button" onclick="volUp()"><i class="volume up icon"></i></button>
-						<button class="ui basic black button" onclick="repeatmode()"><i class="repeat icon"></i></button>
-					</div>
-					<div style="display: flex; flex-wrap: nowrap; margin-left: 1em; padding-top: 8px;">
-						<div>
-							<i class="volume off icon"></i><span id="voldis">100%</span> 
-						</div>
-						<div style="margin-left: 0.5em;">
-							<i class="time icon"></i><span id="timecode">0:00/0:00</span>
-						</div>
-						<div style="margin-left: 0.5em;">
-							<i class="repeat icon"></i><span id="repmode">Single</span>
-						</div>
-					</div>
-				</div>
-				
-
-			</div>
-			</div>
-		</div>
-    </div>
-<script>
-	/*
-		ArOZ Online Beta Audio Module Embedded Player
-		Migrated to arozos 1.105 by tobychui
-		Updated UI design in arozos v1.121 by tobychui
-	*/
-//ArOZ Online BETA control system
-var pwa = false;
-var inVDI = true;
-var embedded = true;
-var downloadmode  = false;
-var lastactiveid = -1;
-var RepeatMode = 2;
-var extDiskAccessAPI="../../media/?file=";
-////////////////////////////
-    
-$( document ).ready(function() {
-	//Set the default path selector value
-	if (pwa){
-		$(".pwa").each(function(){
-			$(this).addClass('disabled');
-		});
-		$(".pwahide").each(function(){
-			$(this).hide();
-		});
-	}
-	var is_safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
-	if (is_safari){
-		//This is added to fix some glitch on Safari tested on a Mac Machine
-		$("body").css("background-color:white;")
-	}
-	
-
-	//Update functions called following the AOB 11-8-2018 updates
-	//Now, the embedded windows can ask for resize properties and icon from the system
-	//If it is currently in VDI, force the current window size and resize properties
-	var windowID = $(window.frameElement).parent().attr("id");
-	ao_module_setFixedWindowSize();
-
-	
-	if (inVDI){
-		//It is currently in Virtual Desktop Mode, make it semi-transparent!
-		//$('body').css('background','rgba(255,255,255,0.7)');
-		setInterval(function() {
-			GvolDisplay();
-		},1000);
-		if ($("#backBtn").length > 0){
-		    $("#backBtn").attr("href","");
-		}
-		var windowID = $(window.frameElement).parent().attr("id");
-	}
-
-	$("#searchbar").hide();
-	
-    $('#downloadmode_reminder').hide();
-	$('#playbtn').attr('class', 'play icon');
-	//Load the global volume from the stored data
-	var globalvol = localStorage.getItem("global_volume");
-	var player = document.getElementById("player");
-	//console.log("Global Volume" + globalvol.toString());
-	if (!globalvol){
-		globalvol = 0.6;
-	}
-	player.volume = parseFloat(globalvol);
-	$('#voldis').html(" " + (Math.round(player.volume * 100)).toString() + "%");
-	//Load the repeat mode from stored data
-	var repmode = localStorage.getItem("repeat_mode");
-	if (repmode == 0){
-		//0 
-		$('#repmode').html(' Single');
-		RepeatMode = 0;
-	  }else if (repmode == 1){
-		//1
-		$('#repmode').html(' ALL');
-		RepeatMode = 1;
-	  }else{
-		//2
-		$('#repmode').html(' None');
-		RepeatMode = 2;
-	  }
-	 //console.log(songlist);
-	 if (embedded == true && repmode == 1){
-		 //Now allow all mode in embedded
-		 $('#repmode').html(' None');
-		 RepeatMode = 2;
-	 }
-
-	 //Read the file input
-	 var inputFiles = ao_module_loadInputFiles();
-	 if (inputFiles.length > 0){
-		inputFiles = inputFiles[0];
-		PlaySong(inputFiles.filepath, inputFiles.filename, "");
-	 }
-});
-
-	//On Pause or Play using Android notification on Firefox / Chrome
-	var aud = document.getElementById("player");
-	aud.onpause = function() {
-		//Paused by the user on notification
-		$('#playbtn').attr('class', 'play icon');
-	};
-	aud.onplay = function() {
-		//Play by the user on notification
-		$('#playbtn').attr('class', 'pause icon');
-	};
-	
-	function GvolDisplay(){
-		var globalvol = (Math.round(GetStorage('global_volume') * 100)) / 100;
-		var audio = document.getElementById("player");
-		audio.volume = globalvol;
-		$('#voldis').html(" " + (Math.round(audio.volume * 100)).toString() + "%");
-	}
-	
-	//These function is for ArOZ Online System quick storage data processing
-	function CheckStorage(id){
-		if (typeof(Storage) !== "undefined") {
-			return true;
-		} else {
-			return false;
-		}
-	}
-	function GetStorage(id){
-		//All data get are string
-		return localStorage.getItem(id);
-	}
-	function SaveStorage(id,value){
-		localStorage.setItem(id, value);
-		return true;
-	}
-  function toggleSearch(){
-	  //Id of Search Bar: searchbar
-	  if (SearchBarOn){
-		  //Need to close the Search Bar
-		  $("#searchbar").css("display", "none");
-		  SearchBarOn = false;
-	  }else{
-		  $("#searchbar").css("display", "block");
-		  SearchBarOn = true;
-		  $(window).scrollTop(0);
-		  $("#sbinput").focus();
-	  }
-  }
-    $('#searchbar').bind("enterKey",function(e){
-		var keyword = $( "#sbinput" ).val();
-		if (keyword != ""){
-			window.location.href = "../Audio/index.php?search=" + keyword;
-		}else{
-			window.location.href = "../Audio/";
-		}
-	});
-	$('#searchbar').keyup(function(e){
-		if(e.keyCode == 13)
-		{
-			$(this).trigger("enterKey");
-		}
-	});
-  
-  function toggledownload(){
-	  if (downloadmode == true){
-		  $('#downloadmode_reminder').stop();
-		  $('#sbtext').html('Download Mode Disabled.');
-		  $("#downloadmodeBtn").css("background-color","");
-		  $('#downloadmode_reminder').fadeIn('slow').delay(2000).fadeOut('slow');
-		  downloadmode = false;
-	  }else{
-		  $('#downloadmode_reminder').stop();
-		  $('#sbtext').html('Download Mode Enabled.');
-		  $("#downloadmodeBtn").css("background-color","#b0ffaa");
-		  $('#downloadmode_reminder').fadeIn('slow').delay(2000).fadeOut('slow');
-		  downloadmode = true;
-	  }
-  }
-  
-  function getRealID(textid){
-	  return parseInt(textid.replace("AudioID",""));
-  }
-  function change(sourceUrl) {
-    var audio = $("#player");
-	$("#player").attr("src", "../../media?file=" + sourceUrl);
-    audio[0].pause();
-    audio[0].load();//suspends and restores all audio element
-    //audio[0].play(); changed based on Sprachprofi's comment below
-    audio[0].oncanplaythrough = audio[0].play();
-
-	}
-	
-
-  function PlaySong(name,displayname,id){
-	  if (downloadmode == false){
-		  //This operation is for choosing song
-		  $('#songname').html(`<i class="music icon"></i> `+ decodeURIComponent(displayname));
-		  change(name);
-		  playingSong = [name,displayname,id];
-		  //console.log(playingSong);
-		  $('#playbtn').attr('class', 'pause icon');
-		  if (lastactiveid.toString() != id.toString()){
-			$('#' + lastactiveid).attr('class', 'ts item'); 
-			$('#' + id.toString()).attr('class', 'ts item active');
-		  }
-		  lastactiveid = id;
-		  $(document).prop('title', displayname);
-		  //console.log(lastactiveid);
-		  if (inVDI){
-			 //If it is currently in VDI, update the floatWindow title as well
-			ao_module_setWindowTitle(decodeURIComponent(displayname));
-		  }
-		
-	  }else if (downloadmode == true){
-		  //This operation is for downloading the audio file
-		  saveAs(name,displayname);
-	  }
-  }
-  
-  function CheckPlaying(){
-	var player = document.getElementById('player');
-	if (player.paused){
-		//Chrome does not allow instant playing of audio so user have to click the btn themselves.
-		$('#playbtn').attr('class', 'play icon');
-	}
-  }
-  
-  
-  function NextSong(){
-	  lastactiveid = parseInt(lastactiveid);
-		if (lastactiveid != "undefined"){
-			if (lastactiveid < songlist.length - 1){
-			PlaySong(songlist[lastactiveid + 1][0],songlist[lastactiveid + 1][1],songlist[lastactiveid + 1][2]);
-			}else{
-			PlaySong(songlist[0][0],songlist[0][1],songlist[0][2]);	
-			}
-		}
-  }
-  
-  function PreviousSong(){
-	  lastactiveid = parseInt(lastactiveid);
-		if (lastactiveid != "undefined"){
-			if (lastactiveid > 0){
-			PlaySong(songlist[lastactiveid - 1][0],songlist[lastactiveid - 1][1],songlist[lastactiveid - 1][2]);
-			}
-		}
-  }
-  
-	function saveAs(uri, filename) {
-		if (extStorageMode){
-			uri = extDiskAccessAPI + uri + "&mode=download&filename=" + JSON.stringify(filename);
-		}
-		var link = document.createElement('a');
-		if (typeof link.download === 'string') {
-			document.body.appendChild(link); // Firefox requires the link to be in the body
-			link.download = filename;
-			link.href = uri;
-			link.click();
-			document.body.removeChild(link); // remove the link when done
-		} else {
-			location.replace(uri);
-		}
-	}
-
-
-  function Show_Audio_Attrubute(){
-	  $("#audio_attr").fadeIn("slow");
-  }
-  function Hide_Audio_Attrubute(){
-	  $("#audio_attr").fadeOut("slow");
-  }
-  function repeatmode(){
-	  //This set the repeat mode for the browser reference.
-	  var repmode = localStorage.getItem("repeat_mode");
-	  // 0 = Single Repeat, repeat the same song
-	  // 1 = All Repeat, repeat when it reached the bottom of the list
-	  // 2 = No Repeat, stop after finishing this song.
-	  if (repmode == 0){
-		//0 -> 1
-		if (embedded == true){
-			repmode = 2;
-			$('#repmode').html(' None');
-			localStorage.setItem("repeat_mode", 2);
-		}else{
-			$('#repmode').html(' ALL');
-			localStorage.setItem("repeat_mode", 1);
-		}
-		
-	  }else if (repmode == 1){
-		//1 -> 2
-		$('#repmode').html(' None');
-		localStorage.setItem("repeat_mode", 2);
-	  }else{
-		//2 -> 0
-		$('#repmode').html(' Single');
-		localStorage.setItem("repeat_mode", 0);
-	  }
-	  
-  }
-  
-  
-  function playbtn(){
-	  if (document.getElementById('player').paused == true){
-		 $('#playbtn').attr('class', 'pause icon');
-		 $('#player').trigger('play'); 
-	  }else{
-		$('#playbtn').attr('class', 'play icon');
-		$('#player').trigger('pause');
-	  }		
-	  
-  }
-  function stopbtn(){
-	  $('#player').trigger('pause');
-	  document.getElementById('player').currentTime = 0;
-	  $('#playbtn').attr('class', 'play icon');
-  }
-  
-  $("#progressbardiv").click(function(e){
-	   var parentOffset = $(this).parent().offset(); 
-	   //or $(this).offset(); if you really just want the current element's offset
-	   var relX = e.pageX - parentOffset.left;
-	   var relY = e.pageY - parentOffset.top;
-	   var divwidth = $(this).parent().width();
-	   var ratio = relX / divwidth;
-	   var player = document.getElementById('player');  
-	   var targettime = Math.round(player.duration * ratio);
-	   player.currentTime = parseFloat(targettime);
-	   
-	   //console.log(ratio);
-	});
-
-  var player = document.getElementById('player');  
-	//For every time update
-	player.addEventListener("timeupdate", function() {
-		var currentTime = player.currentTime;
-		var duration = player.duration;
-		$('#timecode').html(" " + FTF(Math.round(currentTime)) + "/" + FTF(Math.round(duration)));
-		$('#audioprogress').stop(true,true).animate({'width':(currentTime)/duration*100+'%'},0,'linear');
-	});
-	
-	//When the audio file is loaded
-	player.addEventListener("canplay", function() {
-		//Load the global volume from the stored data
-		var globalvol = localStorage.getItem("global_volume");
-		//console.log("Global Volume" + globalvol.toString());
-		if (!globalvol){
-			globalvol = 0.6;
-		}
-		player.volume = globalvol;
-		$('#voldis').html(" " + (Math.round(player.volume * 100)).toString() + "%");
-		//Load the repeat mode from stored data
-		var repmode = localStorage.getItem("repeat_mode");
-		if (embedded == true){
-		  if (repmode == 1){
-			  $('#repmode').html(' None');
-			  repmode = 2;
-		  }
-		}
-		if (repmode == 0){
-			//0 
-			$('#repmode').html(' Single');
-			RepeatMode = 0;
-		  }else if (repmode == 1){
-			//1
-			$('#repmode').html(' ALL');
-			RepeatMode = 1;
-		  }else{
-			//2
-			$('#repmode').html(' None');
-			RepeatMode = 2;
-		  }
-	});
-	//Event when the player finished the audio playing
-	player.addEventListener("ended", function() {
-		var repmode = localStorage.getItem("repeat_mode");
-		if (repmode == 0){
-			//0 
-			$('#repmode').html(' Single');
-			RepeatMode = 0;
-		  }else if (repmode == 1){
-			//1
-			$('#repmode').html(' ALL');
-			RepeatMode = 1;
-		  }else{
-			//2
-			$('#repmode').html(' None');
-			RepeatMode = 2;
-		  }
-		  
-		if (embedded == true){
-		  if (RepeatMode == 1){
-			  RepeatMode = 2;
-			  $('#repmode').html(' None');
-		  }
-		}
-		if (RepeatMode == 0){
-			stopbtn();
-			$('#player').trigger('play'); 
-		}else if (RepeatMode == 1){
-			NextSong();
-		}else{
-			stopbtn();
-		}
-	});
-	
-  function volUp(){
-	var audio = document.getElementById("player");
-	if (audio.volume > 0.95){
-		audio.volume = 1;
-	}else{
-		audio.volume += 0.05;
-	}
-	$('#voldis').html(" " + (Math.round(audio.volume * 100)).toString() + "%");
-	localStorage.setItem("global_volume", audio.volume);
-  }
-
-  function volDown(){
-	var audio = document.getElementById("player");
-	if (audio.volume < 0.05){
-		audio.volume = 0;
-	}else{
-		audio.volume -= 0.05; 
-	}
-	$('#voldis').html(" " + (Math.round(audio.volume * 100)).toString() + "%");
-	localStorage.setItem("global_volume", audio.volume);
-  }
-	
-	$("#basedirPath").change(function(){
-		var selectedItem = $("#basedirPath").find(":selected").text();
-		if (selectedItem == "Internal Storage"){
-			if (inVDI){
-				window.location.href = "index.php?mode=fw";
-			}else{
-				window.location.href = "index.php";
-			}
-		}else{
-			if (inVDI){
-				window.location.href = "index.php?mode=fw&extstorage=" + selectedItem.split("/").pop();
-			}else{
-				window.location.href = "index.php?extstorage=" + selectedItem.split("/").pop();
-			}
-		}
-    });
-	
-	//Scroll Controller
-	$(window).scroll(function (event) {
-		var scroll = $(window).scrollTop();
-		if (scroll > 200){
-			$('#YamiPlayer').css('position', 'fixed');
-			$('#YamiPlayer').css('top', '0');
-			$('#YamiPlayer').css('right', '0');
-			$('#YamiPlayer').css('width', '100%');
-			$('#YamiPlayer').css('z-index', '1000');
-		}else if (scroll < 50){
-			$('#YamiPlayer').css('position', '');
-			$('#YamiPlayer').css('top', '');
-			$('#YamiPlayer').css('width', '100%');
-			$('#YamiPlayer').css('right', '');
-			$('#YamiPlayer').css('z-index', '');
-		}
-	});
-	
-	
-	
-	
-	function FTF(time)
-	{   
-		// Hours, minutes and seconds
-		var hrs = ~~(time / 3600);
-		var mins = ~~((time % 3600) / 60);
-		var secs = time % 60;
-
-		// Output like "1:01" or "4:03:59" or "123:03:59"
-		var ret = "";
-
-		if (hrs > 0) {
-			ret += "" + hrs + ":" + (mins < 10 ? "0" : "");
-		}
-
-		ret += "" + mins + ":" + (secs < 10 ? "0" : "");
-		ret += "" + secs;
-		return ret;
-	}
-</script>
-</body>
+<!DOCTYPE html>
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=0.6, maximum-scale=0.6"/>
+<html>
+<head>
+<meta charset="UTF-8">
+<script type='text/javascript' charset='utf-8'>
+</script>
+<title>ArOZ Onlineβ</title>
+<link rel="stylesheet" href="../../script/semantic/semantic.min.css">
+<script src="../../script/jquery.min.js"></script>
+<script src="../../script/semantic/semantic.min.js"></script>
+<script src="../../script/ao_module.js"></script>
+<style>
+.transparent{
+	background-color:rgba(255, 255, 255, 0) !important;
+	border:1px solid transparent;
+}
+
+.seventytransparent{
+	background-color:rgba(255, 255, 255, 0.7) !important;
+	border:1px solid transparent;
+}
+body {
+	background: rgba(255,255,255,1);
+}
+
+#songname{
+	clear: both;
+    display: inline-block;
+    overflow: hidden;
+    white-space: nowrap;
+	text-overflow: ellipsis;
+}
+
+</style>
+</head>
+<body>
+
+    <div >
+		<!-- Audio Control System with no HTML5 Audio Attribute-->
+		<div>
+			<div id="audio_attr"style="display:none;">
+			<audio id="player" controls autoplay>
+			  <source src="" type="audio/mpeg">
+				Your browser does not support the audio element.
+			</audio>
+			</div>
+			<div id="YamiPlayer" class="content transparent" style="top:0;">
+			<div id="songname" class="ui top attached segment" style="border: 1px solid transparent;">
+				<i class="music icon"></i> 
+			</div>
+			<div id="progressbardiv" class="ui attached progress" style="height: 1em; background-color: #eeeeee;">
+				<div id="audioprogress" class="bar" style="min-width: 0px; width: 0%; height: 1em;"></div>
+			</div>
+			<div style="background-color: white; margin-top: 5px;">
+				<div style="display: flex; flex-wrap: nowrap;">
+					<div class="ui icon buttons" style="margin-left: 12px;">
+						<!-- <button class="ui disabled button" onclick="PreviousSong()"><i class="step backward icon"></i></button> -->
+						<button class="ui basic black button" onclick="playbtn()"><i id='playbtn' class="pause icon"></i></button>
+						<!-- <button class="ui disabled button" onclick="NextSong()"><i class="step forward icon"></i></button> -->
+						<button class="ui basic black button" onclick="stopbtn()"><i class="stop icon"></i></button>
+						<button class="ui basic black button" onclick="volDown()"><i class="volume down icon"></i></button>
+						<button class="ui basic black button" onclick="volUp()"><i class="volume up icon"></i></button>
+						<button class="ui basic black button" onclick="repeatmode()"><i class="repeat icon"></i></button>
+					</div>
+					<div style="display: flex; flex-wrap: nowrap; margin-left: 1em; padding-top: 8px;">
+						<div>
+							<i class="volume off icon"></i><span id="voldis">100%</span> 
+						</div>
+						<div style="margin-left: 0.5em;">
+							<i class="time icon"></i><span id="timecode">0:00/0:00</span>
+						</div>
+						<div style="margin-left: 0.5em;">
+							<i class="repeat icon"></i><span id="repmode">Single</span>
+						</div>
+					</div>
+				</div>
+				
+
+			</div>
+			</div>
+		</div>
+    </div>
+<script>
+	/*
+		ArOZ Online Beta Audio Module Embedded Player
+		Migrated to arozos 1.105 by tobychui
+		Updated UI design in arozos v1.121 by tobychui
+	*/
+//ArOZ Online BETA control system
+var pwa = false;
+var inVDI = true;
+var embedded = true;
+var downloadmode  = false;
+var lastactiveid = -1;
+var RepeatMode = 2;
+var extDiskAccessAPI="../../media/?file=";
+////////////////////////////
+    
+$( document ).ready(function() {
+	//Set the default path selector value
+	if (pwa){
+		$(".pwa").each(function(){
+			$(this).addClass('disabled');
+		});
+		$(".pwahide").each(function(){
+			$(this).hide();
+		});
+	}
+	var is_safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+	if (is_safari){
+		//This is added to fix some glitch on Safari tested on a Mac Machine
+		$("body").css("background-color:white;")
+	}
+	
+
+	//Update functions called following the AOB 11-8-2018 updates
+	//Now, the embedded windows can ask for resize properties and icon from the system
+	//If it is currently in VDI, force the current window size and resize properties
+	var windowID = $(window.frameElement).parent().attr("id");
+	ao_module_setFixedWindowSize();
+
+	
+	if (inVDI){
+		//It is currently in Virtual Desktop Mode, make it semi-transparent!
+		//$('body').css('background','rgba(255,255,255,0.7)');
+		setInterval(function() {
+			GvolDisplay();
+		},1000);
+		if ($("#backBtn").length > 0){
+		    $("#backBtn").attr("href","");
+		}
+		var windowID = $(window.frameElement).parent().attr("id");
+	}
+
+	$("#searchbar").hide();
+	
+    $('#downloadmode_reminder').hide();
+	$('#playbtn').attr('class', 'play icon');
+	//Load the global volume from the stored data
+	var globalvol = localStorage.getItem("global_volume");
+	var player = document.getElementById("player");
+	//console.log("Global Volume" + globalvol.toString());
+	if (!globalvol){
+		globalvol = 0.6;
+	}
+	player.volume = parseFloat(globalvol);
+	$('#voldis').html(" " + (Math.round(player.volume * 100)).toString() + "%");
+	//Load the repeat mode from stored data
+	var repmode = localStorage.getItem("repeat_mode");
+	if (repmode == 0){
+		//0 
+		$('#repmode').html(' Single');
+		RepeatMode = 0;
+	  }else if (repmode == 1){
+		//1
+		$('#repmode').html(' ALL');
+		RepeatMode = 1;
+	  }else{
+		//2
+		$('#repmode').html(' None');
+		RepeatMode = 2;
+	  }
+	 //console.log(songlist);
+	 if (embedded == true && repmode == 1){
+		 //Now allow all mode in embedded
+		 $('#repmode').html(' None');
+		 RepeatMode = 2;
+	 }
+
+	 //Read the file input
+	 var inputFiles = ao_module_loadInputFiles();
+	 if (inputFiles.length > 0){
+		inputFiles = inputFiles[0];
+		PlaySong(inputFiles.filepath, inputFiles.filename, "");
+	 }
+});
+
+	//On Pause or Play using Android notification on Firefox / Chrome
+	var aud = document.getElementById("player");
+	aud.onpause = function() {
+		//Paused by the user on notification
+		$('#playbtn').attr('class', 'play icon');
+	};
+	aud.onplay = function() {
+		//Play by the user on notification
+		$('#playbtn').attr('class', 'pause icon');
+	};
+	
+	function GvolDisplay(){
+		var globalvol = (Math.round(GetStorage('global_volume') * 100)) / 100;
+		var audio = document.getElementById("player");
+		audio.volume = globalvol;
+		$('#voldis').html(" " + (Math.round(audio.volume * 100)).toString() + "%");
+	}
+	
+	//These function is for ArOZ Online System quick storage data processing
+	function CheckStorage(id){
+		if (typeof(Storage) !== "undefined") {
+			return true;
+		} else {
+			return false;
+		}
+	}
+	function GetStorage(id){
+		//All data get are string
+		return localStorage.getItem(id);
+	}
+	function SaveStorage(id,value){
+		localStorage.setItem(id, value);
+		return true;
+	}
+  function toggleSearch(){
+	  //Id of Search Bar: searchbar
+	  if (SearchBarOn){
+		  //Need to close the Search Bar
+		  $("#searchbar").css("display", "none");
+		  SearchBarOn = false;
+	  }else{
+		  $("#searchbar").css("display", "block");
+		  SearchBarOn = true;
+		  $(window).scrollTop(0);
+		  $("#sbinput").focus();
+	  }
+  }
+    $('#searchbar').bind("enterKey",function(e){
+		var keyword = $( "#sbinput" ).val();
+		if (keyword != ""){
+			window.location.href = "../Audio/index.php?search=" + keyword;
+		}else{
+			window.location.href = "../Audio/";
+		}
+	});
+	$('#searchbar').keyup(function(e){
+		if(e.keyCode == 13)
+		{
+			$(this).trigger("enterKey");
+		}
+	});
+  
+  function toggledownload(){
+	  if (downloadmode == true){
+		  $('#downloadmode_reminder').stop();
+		  $('#sbtext').html('Download Mode Disabled.');
+		  $("#downloadmodeBtn").css("background-color","");
+		  $('#downloadmode_reminder').fadeIn('slow').delay(2000).fadeOut('slow');
+		  downloadmode = false;
+	  }else{
+		  $('#downloadmode_reminder').stop();
+		  $('#sbtext').html('Download Mode Enabled.');
+		  $("#downloadmodeBtn").css("background-color","#b0ffaa");
+		  $('#downloadmode_reminder').fadeIn('slow').delay(2000).fadeOut('slow');
+		  downloadmode = true;
+	  }
+  }
+  
+  function getRealID(textid){
+	  return parseInt(textid.replace("AudioID",""));
+  }
+  function change(sourceUrl) {
+    var audio = $("#player");
+	$("#player").attr("src", "../../media?file=" + sourceUrl);
+    audio[0].pause();
+    audio[0].load();//suspends and restores all audio element
+    //audio[0].play(); changed based on Sprachprofi's comment below
+    audio[0].oncanplaythrough = audio[0].play();
+
+	}
+	
+
+  function PlaySong(name,displayname,id){
+	  if (downloadmode == false){
+		  //This operation is for choosing song
+		  $('#songname').html(`<i class="music icon"></i> `+ decodeURIComponent(displayname));
+		  change(name);
+		  playingSong = [name,displayname,id];
+		  //console.log(playingSong);
+		  $('#playbtn').attr('class', 'pause icon');
+		  if (lastactiveid.toString() != id.toString()){
+			$('#' + lastactiveid).attr('class', 'ts item'); 
+			$('#' + id.toString()).attr('class', 'ts item active');
+		  }
+		  lastactiveid = id;
+		  $(document).prop('title', displayname);
+		  //console.log(lastactiveid);
+		  if (inVDI){
+			 //If it is currently in VDI, update the floatWindow title as well
+			ao_module_setWindowTitle(decodeURIComponent(displayname));
+		  }
+		
+	  }else if (downloadmode == true){
+		  //This operation is for downloading the audio file
+		  saveAs(name,displayname);
+	  }
+  }
+  
+  function CheckPlaying(){
+	var player = document.getElementById('player');
+	if (player.paused){
+		//Chrome does not allow instant playing of audio so user have to click the btn themselves.
+		$('#playbtn').attr('class', 'play icon');
+	}
+  }
+  
+  
+  function NextSong(){
+	  lastactiveid = parseInt(lastactiveid);
+		if (lastactiveid != "undefined"){
+			if (lastactiveid < songlist.length - 1){
+			PlaySong(songlist[lastactiveid + 1][0],songlist[lastactiveid + 1][1],songlist[lastactiveid + 1][2]);
+			}else{
+			PlaySong(songlist[0][0],songlist[0][1],songlist[0][2]);	
+			}
+		}
+  }
+  
+  function PreviousSong(){
+	  lastactiveid = parseInt(lastactiveid);
+		if (lastactiveid != "undefined"){
+			if (lastactiveid > 0){
+			PlaySong(songlist[lastactiveid - 1][0],songlist[lastactiveid - 1][1],songlist[lastactiveid - 1][2]);
+			}
+		}
+  }
+  
+	function saveAs(uri, filename) {
+		if (extStorageMode){
+			uri = extDiskAccessAPI + uri + "&mode=download&filename=" + JSON.stringify(filename);
+		}
+		var link = document.createElement('a');
+		if (typeof link.download === 'string') {
+			document.body.appendChild(link); // Firefox requires the link to be in the body
+			link.download = filename;
+			link.href = uri;
+			link.click();
+			document.body.removeChild(link); // remove the link when done
+		} else {
+			location.replace(uri);
+		}
+	}
+
+
+  function Show_Audio_Attrubute(){
+	  $("#audio_attr").fadeIn("slow");
+  }
+  function Hide_Audio_Attrubute(){
+	  $("#audio_attr").fadeOut("slow");
+  }
+  function repeatmode(){
+	  //This set the repeat mode for the browser reference.
+	  var repmode = localStorage.getItem("repeat_mode");
+	  // 0 = Single Repeat, repeat the same song
+	  // 1 = All Repeat, repeat when it reached the bottom of the list
+	  // 2 = No Repeat, stop after finishing this song.
+	  if (repmode == 0){
+		//0 -> 1
+		if (embedded == true){
+			repmode = 2;
+			$('#repmode').html(' None');
+			localStorage.setItem("repeat_mode", 2);
+		}else{
+			$('#repmode').html(' ALL');
+			localStorage.setItem("repeat_mode", 1);
+		}
+		
+	  }else if (repmode == 1){
+		//1 -> 2
+		$('#repmode').html(' None');
+		localStorage.setItem("repeat_mode", 2);
+	  }else{
+		//2 -> 0
+		$('#repmode').html(' Single');
+		localStorage.setItem("repeat_mode", 0);
+	  }
+	  
+  }
+  
+  
+  function playbtn(){
+	  if (document.getElementById('player').paused == true){
+		 $('#playbtn').attr('class', 'pause icon');
+		 $('#player').trigger('play'); 
+	  }else{
+		$('#playbtn').attr('class', 'play icon');
+		$('#player').trigger('pause');
+	  }		
+	  
+  }
+  function stopbtn(){
+	  $('#player').trigger('pause');
+	  document.getElementById('player').currentTime = 0;
+	  $('#playbtn').attr('class', 'play icon');
+  }
+  
+  $("#progressbardiv").click(function(e){
+	   var parentOffset = $(this).parent().offset(); 
+	   //or $(this).offset(); if you really just want the current element's offset
+	   var relX = e.pageX - parentOffset.left;
+	   var relY = e.pageY - parentOffset.top;
+	   var divwidth = $(this).parent().width();
+	   var ratio = relX / divwidth;
+	   var player = document.getElementById('player');  
+	   var targettime = Math.round(player.duration * ratio);
+	   player.currentTime = parseFloat(targettime);
+	   
+	   //console.log(ratio);
+	});
+
+  var player = document.getElementById('player');  
+	//For every time update
+	player.addEventListener("timeupdate", function() {
+		var currentTime = player.currentTime;
+		var duration = player.duration;
+		$('#timecode').html(" " + FTF(Math.round(currentTime)) + "/" + FTF(Math.round(duration)));
+		$('#audioprogress').stop(true,true).animate({'width':(currentTime)/duration*100+'%'},0,'linear');
+	});
+	
+	//When the audio file is loaded
+	player.addEventListener("canplay", function() {
+		//Load the global volume from the stored data
+		var globalvol = localStorage.getItem("global_volume");
+		//console.log("Global Volume" + globalvol.toString());
+		if (!globalvol){
+			globalvol = 0.6;
+		}
+		player.volume = globalvol;
+		$('#voldis').html(" " + (Math.round(player.volume * 100)).toString() + "%");
+		//Load the repeat mode from stored data
+		var repmode = localStorage.getItem("repeat_mode");
+		if (embedded == true){
+		  if (repmode == 1){
+			  $('#repmode').html(' None');
+			  repmode = 2;
+		  }
+		}
+		if (repmode == 0){
+			//0 
+			$('#repmode').html(' Single');
+			RepeatMode = 0;
+		  }else if (repmode == 1){
+			//1
+			$('#repmode').html(' ALL');
+			RepeatMode = 1;
+		  }else{
+			//2
+			$('#repmode').html(' None');
+			RepeatMode = 2;
+		  }
+	});
+	//Event when the player finished the audio playing
+	player.addEventListener("ended", function() {
+		var repmode = localStorage.getItem("repeat_mode");
+		if (repmode == 0){
+			//0 
+			$('#repmode').html(' Single');
+			RepeatMode = 0;
+		  }else if (repmode == 1){
+			//1
+			$('#repmode').html(' ALL');
+			RepeatMode = 1;
+		  }else{
+			//2
+			$('#repmode').html(' None');
+			RepeatMode = 2;
+		  }
+		  
+		if (embedded == true){
+		  if (RepeatMode == 1){
+			  RepeatMode = 2;
+			  $('#repmode').html(' None');
+		  }
+		}
+		if (RepeatMode == 0){
+			stopbtn();
+			$('#player').trigger('play'); 
+		}else if (RepeatMode == 1){
+			NextSong();
+		}else{
+			stopbtn();
+		}
+	});
+	
+  function volUp(){
+	var audio = document.getElementById("player");
+	if (audio.volume > 0.95){
+		audio.volume = 1;
+	}else{
+		audio.volume += 0.05;
+	}
+	$('#voldis').html(" " + (Math.round(audio.volume * 100)).toString() + "%");
+	localStorage.setItem("global_volume", audio.volume);
+  }
+
+  function volDown(){
+	var audio = document.getElementById("player");
+	if (audio.volume < 0.05){
+		audio.volume = 0;
+	}else{
+		audio.volume -= 0.05; 
+	}
+	$('#voldis').html(" " + (Math.round(audio.volume * 100)).toString() + "%");
+	localStorage.setItem("global_volume", audio.volume);
+  }
+	
+	$("#basedirPath").change(function(){
+		var selectedItem = $("#basedirPath").find(":selected").text();
+		if (selectedItem == "Internal Storage"){
+			if (inVDI){
+				window.location.href = "index.php?mode=fw";
+			}else{
+				window.location.href = "index.php";
+			}
+		}else{
+			if (inVDI){
+				window.location.href = "index.php?mode=fw&extstorage=" + selectedItem.split("/").pop();
+			}else{
+				window.location.href = "index.php?extstorage=" + selectedItem.split("/").pop();
+			}
+		}
+    });
+	
+	//Scroll Controller
+	$(window).scroll(function (event) {
+		var scroll = $(window).scrollTop();
+		if (scroll > 200){
+			$('#YamiPlayer').css('position', 'fixed');
+			$('#YamiPlayer').css('top', '0');
+			$('#YamiPlayer').css('right', '0');
+			$('#YamiPlayer').css('width', '100%');
+			$('#YamiPlayer').css('z-index', '1000');
+		}else if (scroll < 50){
+			$('#YamiPlayer').css('position', '');
+			$('#YamiPlayer').css('top', '');
+			$('#YamiPlayer').css('width', '100%');
+			$('#YamiPlayer').css('right', '');
+			$('#YamiPlayer').css('z-index', '');
+		}
+	});
+	
+	
+	
+	
+	function FTF(time)
+	{   
+		// Hours, minutes and seconds
+		var hrs = ~~(time / 3600);
+		var mins = ~~((time % 3600) / 60);
+		var secs = time % 60;
+
+		// Output like "1:01" or "4:03:59" or "123:03:59"
+		var ret = "";
+
+		if (hrs > 0) {
+			ret += "" + hrs + ":" + (mins < 10 ? "0" : "");
+		}
+
+		ret += "" + mins + ":" + (secs < 10 ? "0" : "");
+		ret += "" + secs;
+		return ret;
+	}
+</script>
+</body>
 </html>

+ 9 - 0
web/desktop.system

@@ -1704,6 +1704,8 @@
             var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
             if (typeof action == "undefined"){
                 $(".notificationbar").stop().finish().fadeToggle("fast", function(){
+                    /*
+                    //Firefox 103 now support backdrop-filter
                     if ($(this).is(":visible")){
                         if (isFirefox){
                             $("#bgwrapper").addClass("blured");
@@ -1721,10 +1723,13 @@
                             $("#listMenu").removeClass("blured");
                         }
                     }
+                    */
                 });
             }else{
                 if (action == "hide"){
                     $(".notificationbar").stop().finish().fadeOut("fast");
+                     /*
+                    //Firefox 103 now support backdrop-filter
                     if (isFirefox){
                         $("#bgwrapper").removeClass("blured");
                         $("#iconwrapper").removeClass("blured");
@@ -1732,9 +1737,12 @@
                         $(".floatWindow").removeClass("blured");
                         $("#listMenu").removeClass("blured");
                     }
+                    */
                   
                 }else if (action == "show"){
                     $(".notificationbar").stop().finish().fadeIn("fast");
+                    /*
+                    //Firefox 103 now support backdrop-filter
                     if (isFirefox){
                         $("#bgwrapper").addClass("blured");
                         $("#iconwrapper").addClass("blured");
@@ -1742,6 +1750,7 @@
                         $(".floatWindow").addClass("blured");
                         $("#listMenu").addClass("blured");
                     }
+                    */
                 }
             }
         }