Compare commits

...

2 Commits

Author SHA1 Message Date
zzz
db6f64ed9e playlist js updates
fix chrome
partially fix dup play detection
var -> let/const
2024-06-04 09:27:55 -04:00
zzz
3bb08a13d5 WIP: i2psnark: js audio playlist
This is some js that adds buttons to play all the audio files in a directory
without having to click on the m3u link to an external player.
This is a proof of concept, no CSS updates are included to style the buttons
or highlight the playing track.
This uses the existing players, one for each track.
An alternative is to replace all the per-track players with a single one
that has all tracks in it.
2024-06-02 08:16:38 -04:00
2 changed files with 255 additions and 3 deletions

View File

@ -3330,6 +3330,7 @@ public class I2PSnarkServlet extends BasicServlet {
"<link rel=\"shortcut icon\" href=\"" + _themePath + "favicon.ico\">\n"); "<link rel=\"shortcut icon\" href=\"" + _themePath + "favicon.ico\">\n");
if (showPriority) if (showPriority)
buf.append("<script src=\"").append(_contextPath).append(WARBASE + "js/folder.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n"); buf.append("<script src=\"").append(_contextPath).append(WARBASE + "js/folder.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n");
buf.append("<script src=\"").append(_contextPath).append(WARBASE + "js/playlist.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n");
buf.append("</head><body>\n" + buf.append("</head><body>\n" +
"<center><div class=\"snarknavbar\"><a href=\"").append(_contextPath).append("/\" title=\"Torrents\"" + "<center><div class=\"snarknavbar\"><a href=\"").append(_contextPath).append("/\" title=\"Torrents\"" +
" class=\"snarkNav nav_main\">"); " class=\"snarkNav nav_main\">");
@ -3868,18 +3869,26 @@ public class I2PSnarkServlet extends BasicServlet {
// playlist button // playlist button
if (hasCompleteAudio(fileList, storage, remainingArray)) { if (hasCompleteAudio(fileList, storage, remainingArray)) {
buf.append("<tr><td colspan=\"" + (showPriority ? '5' : '4') + "\" class=\"ParentDir\">" + buf.append("<tr><td colspan=\"" + (showPriority ? '5' : '4') + "\">" +
"<a href=\"").append(base).append("?playlist"); "<a href=\"").append(base).append("?playlist");
if (sortParam != null && !"0".equals(sortParam) && !"1".equals(sortParam)) if (sortParam != null && !"0".equals(sortParam) && !"1".equals(sortParam))
buf.append("&amp;sort=").append(sortParam); buf.append("&amp;sort=").append(sortParam);
buf.append("\">"); buf.append("\">");
buf.append(toImg("music")); buf.append(toImg("music"));
buf.append(' ').append(_t("Audio Playlist")).append("</a></td></tr>\n"); buf.append(' ').append(_t("Audio Playlist")).append("</a>\n");
// js play buttons
buf.append("<a class=\"controld script\" id=\"playprev\" href=\"#\">").append(toImg("cancel")).append(_t("Play Previous")).append("</a>\n");
buf.append("<a class=\"control script\" id=\"playall\" href=\"#\">").append(toImg("cancel")).append(_t("Play All")).append("</a>\n");
buf.append("<a class=\"controld script\" id=\"playpause\" href=\"#\">").append(toImg("cancel")).append(_t("Pause")).append("</a>\n");
buf.append("<a class=\"control script\" id=\"playnext\" href=\"#\">").append(toImg("cancel")).append(_t("Play Next")).append("</a>\n");
buf.append("<span id=\"playing\"></span>\n");
buf.append("</td></tr>\n");
} }
boolean showSaveButton = false; boolean showSaveButton = false;
boolean rowEven = true; boolean rowEven = true;
boolean inOrder = storage != null && storage.getInOrder(); boolean inOrder = storage != null && storage.getInOrder();
int audioindex = 0;
for (Sorters.FileAndIndex fai : fileList) for (Sorters.FileAndIndex fai : fileList)
{ {
//String encoded = encodePath(ls[i].getName()); //String encoded = encodePath(ls[i].getName());
@ -3960,7 +3969,7 @@ public class I2PSnarkServlet extends BasicServlet {
if (isAudio || isVideo) { if (isAudio || isVideo) {
// HTML5 // HTML5
if (isAudio) if (isAudio)
buf.append("<audio"); buf.append("<audio class=\"audio\" audioindex=\"").append(audioindex++).append('"');
else else
buf.append("<div class=\"video-wrapper\"><video class=\"video\""); buf.append("<div class=\"video-wrapper\"><video class=\"video\"");
buf.append(" controls><source src=\"").append(ppath).append("\" type=\"").append(mime).append("\">"); buf.append(" controls><source src=\"").append(ppath).append("\" type=\"").append(mime).append("\">");

View File

@ -0,0 +1,243 @@
/* @license http://www.gnu.org/licenses/gpl-2.0.html GPL-2.0 */
/* see also licenses/LICENSE-GPLv2.txt */
var __i2psnark_isplaying = false;
var __i2psnark_autoplay = false;
var __i2psnark_playindex = -1;
var __i2psnark_playsize = 0;
// note that we use currentTime = 0, not fastSeek(0), because
// Chrome doesn't support it.
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
const setupplaybuttons=()=>{
let button = document.getElementById('playall');
if (button === null)
return;
const audios = document.getElementsByClassName("audio");
__i2psnark_playsize = audios.length;
for (var i = 0; i < __i2psnark_playsize; i++) {
const audio = audios[i];
audio.addEventListener("ended", function() {
audioended();
});
audio.addEventListener("pause", function() {
audiopause();
});
audio.addEventListener("play", function() {
audioplay();
});
}
if (__i2psnark_playsize > 1) {
button.addEventListener("click", function() {
playall();
event.preventDefault();
});
} else {
button.display = false;
button.classList.remove("control");
button.classList.add("controld");
}
button = document.getElementById('playpause');
button.disabled = true;
if (__i2psnark_playsize > 1) {
button.addEventListener("click", function() {
playpause();
event.preventDefault();
});
} else {
button.display = false;
button.classList.remove("control");
button.classList.add("controld");
}
button = document.getElementById('playprev');
if (__i2psnark_playsize > 1) {
button.disabled = true;
button.addEventListener("click", function() {
playprev();
event.preventDefault();
});
} else {
button.display = false;
button.classList.remove("control");
button.classList.add("controld");
}
button = document.getElementById('playnext');
if (__i2psnark_playsize > 1) {
button.addEventListener("click", function() {
playnext();
event.preventDefault();
});
} else {
button.display = false;
button.classList.remove("control");
button.classList.add("controld");
}
}
// buttons
const playprev=()=>{
if (__i2psnark_playindex <= 0)
return;
const audios = document.getElementsByClassName("audio");
if (__i2psnark_isplaying) {
audios[__i2psnark_playindex].pause();
audios[__i2psnark_playindex].currentTime = 0;
}
__i2psnark_playindex--;
audios[__i2psnark_playindex].currentTime = 0;
audios[__i2psnark_playindex].play();
playing();
}
const playnext=()=>{
if (__i2psnark_playindex >= __i2psnark_playsize - 1)
return;
const audios = document.getElementsByClassName("audio");
if (__i2psnark_isplaying) {
audios[__i2psnark_playindex].pause();
audios[__i2psnark_playindex].currentTime = 0;
}
__i2psnark_playindex++;
audios[__i2psnark_playindex].currentTime = 0;
audios[__i2psnark_playindex].play();
playing();
}
const playpause=()=>{
__i2psnark_autoplay = false;
if (!__i2psnark_isplaying)
return;
const audios = document.getElementsByClassName("audio");
audios[__i2psnark_playindex].pause();
notplaying();
}
const playall=()=>{
__i2psnark_autoplay = true;
if (__i2psnark_isplaying)
return;
if (__i2psnark_playindex >= __i2psnark_playsize - 1 || __i2psnark_playindex < 0)
__i2psnark_playindex = 0;
const audios = document.getElementsByClassName("audio");
// no, start where we were before
//audios[__i2psnark_playindex].currentTime = 0;
audios[__i2psnark_playindex].play();
playing();
}
// events
const audioended=()=>{
const audio = event.target;
audio.currentTime = 0;
__i2psnark_playindex = Number(audio.getAttribute("audioindex"));
if (__i2psnark_playindex < __i2psnark_playsize - 1) {
__i2psnark_playindex++;
if (__i2psnark_autoplay) {
const audios = document.getElementsByClassName("audio");
audios[__i2psnark_playindex].play();
playing();
} else {
notplaying();
}
} else {
__i2psnark_playindex = -1;
notplaying();
}
}
const audiopause=()=>{
const audio = event.target;
__i2psnark_playindex = Number(audio.getAttribute("audioindex"));
notplaying();
}
const audioplay=()=>{
const audio = event.target;
const old__i2psnark_playindex = __i2psnark_playindex;
__i2psnark_playindex = Number(audio.getAttribute("audioindex"));
if (__i2psnark_isplaying && old__i2psnark_playindex != __i2psnark_playindex && old__i2psnark_playindex >= 0 && old__i2psnark_playindex <= __i2psnark_playsize - 1) {
// prevent two at once
const audios = document.getElementsByClassName("audio");
audios[old__i2psnark_playindex].pause();
audios[old__i2psnark_playindex].currentTime = 0;
}
playing();
}
// state changes
const playing=()=>{
__i2psnark_isplaying = true;
let button = document.getElementById('playprev');
if (__i2psnark_playindex > 0) {
button.disabled=false;
button.classList.remove("controld");
button.classList.add("control");
} else {
button.disabled=true;
button.classList.remove("control");
button.classList.add("controld");
}
button = document.getElementById('playnext');
if (__i2psnark_playindex < __i2psnark_playsize - 1) {
button.disabled=false;
button.classList.remove("controld");
button.classList.add("control");
} else {
button.disabled=true;
button.classList.remove("control");
button.classList.add("controld");
}
button = document.getElementById('playall');
button.disabled=true;
button.classList.remove("control");
button.classList.add("controld");
button = document.getElementById('playpause');
button.disabled=false;
button.classList.remove("controld");
button.classList.add("control");
// getbyclassname[__i2psnark_playindex].getElementsByTagName("source")[0].getAttribute("src")
// lastindexof /
// escape, set text
}
const notplaying=()=>{
__i2psnark_isplaying = false;
let button = document.getElementById('playprev');
if (__i2psnark_playindex > 0) {
button.disabled=false;
button.classList.remove("controld");
button.classList.add("control");
} else {
button.disabled=true;
button.classList.remove("control");
button.classList.add("controld");
}
button = document.getElementById('playnext');
if (__i2psnark_playindex < __i2psnark_playsize - 1) {
button.disabled=false;
button.classList.remove("controld");
button.classList.add("control");
} else {
button.disabled=true;
button.classList.remove("control");
button.classList.add("controld");
}
button = document.getElementById('playall');
button.disabled=false;
button.classList.remove("controld");
button.classList.add("control");
button = document.getElementById('playpause');
button.disabled=true;
button.classList.remove("control");
button.classList.add("controld");
}
document.addEventListener("DOMContentLoaded", function() {
setupplaybuttons();
}, true);
/* @license-end */