Version 0.6.0 - Ajout des playlists

This commit is contained in:
CICD - Pipeline 2023-08-28 23:01:37 +02:00
parent e34134537e
commit d5651f8cef
14 changed files with 861 additions and 123 deletions

View File

@ -15,20 +15,8 @@
<div style="font-size: 14px;">
## Changelog
### Subsonics - Web - 0.5.0
- **Adds :** *Web features : Search & Play*
#### Details
**Web Player Features**
> - Search & Play
>> - SEND/ SEARCH_SONGS
>> - SEND/ PLAY_SONG
<hr>
### Subsonics - Web - 0.6.0
- **Adds :** *Web features : Playlist | Pipeline Deploy V2 | Search Ellipis*
- **Adds :** *Web features : Playlist | Pipeline Deploy V2 | Search Ellipis | Handle Playlist on Web*
#### Details
**Web Player Features**
> - Playlist

View File

@ -16,5 +16,11 @@
"password": "horizxon.studio",
"port": 443,
"secure": true
},
{
"host": "eu-lavalink.lexnet.cc",
"password": "lexn3tl@val!nk",
"port": 443,
"secure": true
}
]

39
data/playlist.json Normal file
View File

@ -0,0 +1,39 @@
{
"486943594893017119": {
"Mes musiques": [
{
"track": "QAAAlQIAJElGU0NMIFRSQUlMRVIgTVVTSUMgLSBORVcgQ0hBTExFTkdFUwAXQ2luw6ltb3JwaGlxdWUgT2ZmaWNpZWwAAAAAAAGaKAALazZkWDZSQ2NLQXMAAQAraHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1rNmRYNlJDY0tBcwAHeW91dHViZQAAAAAAAAAA",
"title": "IFSCL TRAILER MUSIC - NEW CHALLENGES",
"identifier": "k6dX6RCcKAs",
"author": "Cinémorphique Officiel",
"duration": 105000,
"isSeekable": true,
"isStream": false,
"uri": "https://www.youtube.com/watch?v=k6dX6RCcKAs",
"thumbnail": "https://img.youtube.com/vi/k6dX6RCcKAs/default.jpg"
},
{
"track": "QAAAiwIAIk15bGVuZSBGYXJtZXIgICBhcHBlbGxlIG1vbiBudW1lcm8AD0ZhbGxpbmdPdXRPZkNhcgAAAAAABQz4AAtVSkpxUnNGZXpZUQABACtodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PVVKSnFSc0ZlellRAAd5b3V0dWJlAAAAAAAAAAA=",
"title": "Mylene Farmer appelle mon numero",
"identifier": "UJJqRsFezYQ",
"author": "FallingOutOfCar",
"duration": 331000,
"isSeekable": true,
"isStream": false,
"uri": "https://www.youtube.com/watch?v=UJJqRsFezYQ",
"thumbnail": "https://img.youtube.com/vi/UJJqRsFezYQ/default.jpg"
},
{
"track": "QAAAdgIAElBva8OpcmFwIEdTIEZyZW5jaAAKTWVudGFsaWkxMQAAAAAAA9CQAAttbUFTZkVUblBqWQABACtodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PW1tQVNmRVRuUGpZAAd5b3V0dWJlAAAAAAAAAAA=",
"title": "Pokérap GS French",
"identifier": "mmASfETnPjY",
"author": "Mentalii11",
"duration": 250000,
"isSeekable": true,
"isStream": false,
"uri": "https://www.youtube.com/watch?v=mmASfETnPjY",
"thumbnail": "https://img.youtube.com/vi/mmASfETnPjY/default.jpg"
}
]
}
}

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "subsonics-web",
"version": "0.5.0",
"version": "0.6.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "subsonics-web",
"version": "0.5.0",
"version": "0.6.0",
"dependencies": {
"cookie": "^0.5.0",
"cookie-parser": "^1.4.6",

View File

@ -1,7 +1,7 @@
{
"name": "subsonics-web",
"author": "Raphix",
"version": "0.5.0",
"version": "0.6.0",
"nodemonConfig": {
"ext": "js, html",
"ignore": [
@ -30,5 +30,5 @@
"start": "nodemon src/main.js",
"dev": "set DEV=true& nodemon src/main.js"
},
"beta_on": true
"beta_on": false
}

View File

@ -16,7 +16,8 @@ const __glob = {
PACKAGE: root + path.sep + "package.json",
DATA: root + path.sep + "data" + path.sep,
NODES: root + path.sep + "data" + path.sep + "nodes.json",
README: root + path.sep + "README.md"
README: root + path.sep + "README.md",
PLAYLIST: root + path.sep + "data" + path.sep + "playlist.json",
};
const webroot = __glob.WEB_DIR + path.sep

View File

@ -4,7 +4,6 @@ const { LogType } = require("./sub-log");
var { List } = require("./sub-list")
const discord = require("./discord-bot")
var ytfps = require("ytfps");
const { use } = require("../web/routes/login");
const packageJson = require(__glob.PACKAGE);
@ -656,7 +655,7 @@ module.exports.updateMusicState = function (client, action) {
data["isOnline"] = false
}
clog.log("Actualisation de tous les clients - Titre : " + currentTitle)
clog.log("Actualisation de tous les clients - Titre : " + currentTitle + " - Loop : " + data.loop + " - Shuffle : " + data.shuffle + " - Playing : " + data.playing + " - Volume : " + Math.trunc(data.volume / 10) )
return data

103
src/modules/sub-playlist.js Normal file
View File

@ -0,0 +1,103 @@
const { SlashCommandBuilder, EmbedBuilder, DefaultWebSocketManagerOptions, discordSort } = require("discord.js");
const { __glob } = require("../modules/global-variables");
const { LogType } = require("./sub-log");
var { List } = require("./sub-list")
const discord = require("./discord-bot")
const subplayer = require("./sub-player")
const fs = require("fs")
var playlists = {}
const plog = new LogType("Playlist-Manager")
check()
module.exports.getUser = function (id) {
check()
if(!playlists[id]) {
plog.log("Ajout de l'utilisateur \"" + id + "\" dans la base de donnée Playlist !")
playlists[id] = {}
fs.writeFileSync(__glob.PLAYLIST, JSON.stringify(playlists, null, 2))
return playlists[id]
} else {
plog.log("L'utilisateur \"" + id + "\" existe déjà dans la base de donnée Playlist !")
return playlists[id]
}
}
module.exports.addPlaylist = function (id, name) {
check()
if(!playlists[id][name]) {
plog.log("Ajout de la playlist à l'utilisateur \"" + id + "\" dans la base de donnée Playlist !")
playlists[id][name] = []
fs.writeFileSync(__glob.PLAYLIST, JSON.stringify(playlists, null, 2))
} else {
plog.log("L'utilisateur \"" + id + "\" à déjà une playlist avec le nom "+ name + " dans la base de donnée Playlist !")
}
}
module.exports.removePlaylist = function (id, name) {
check()
if(playlists[id][name]) {
plog.log("Supression de la playlist à l'utilisateur \"" + id + "\" dans la base de donnée Playlist !")
delete playlists[id][name]
fs.writeFileSync(__glob.PLAYLIST, JSON.stringify(playlists, null, 2))
} else {
plog.log("L'utilisateur \"" + id + "\" n'a pas une playlist avec le nom "+ name + " dans la base de donnée Playlist !")
}
}
module.exports.addSong = function (id, name, song) {
check()
if(playlists[id][name]) {
plog.log("Ajout d'une chanson dans la playlist '" + name + "' à l'utilisateur \"" + id + "\" dans la base de donnée Playlist !")
playlists[id][name].push(song)
fs.writeFileSync(__glob.PLAYLIST, JSON.stringify(playlists, null, 2))
} else {
plog.log("L'utilisateur \"" + id + "\" n'a pas une playlist avec le nom "+ name + " dans la base de donnée Playlist !")
}
}
module.exports.removeSong = function (id, name, song ) {
check()
if(playlists[id][name]) {
plog.log("Supression d'une chanson dans la playlist '" + name + "' à l'utilisateur \"" + id + "\" dans la base de donnée Playlist !")
playlists[id][name].splice(playlists[id][name].indexOf(song), 1)
fs.writeFileSync(__glob.PLAYLIST, JSON.stringify(playlists, null, 2))
} else {
plog.log("L'utilisateur \"" + id + "\" n'a pas une playlist avec le nom "+ name + " dans la base de donnée Playlist !")
}
}
function check() {
if(fs.existsSync(__glob.PLAYLIST)) {
playlists = JSON.parse(fs.readFileSync(__glob.PLAYLIST))
} else {
fs.writeFileSync(__glob.PLAYLIST, JSON.stringify(playlists, null, 2))
}
}

View File

@ -1,5 +1,5 @@
const internal = require("stream");
const { __glob, __web } = require("../modules/global-variables");
const { __glob, __web } = require("./global-variables");
const { LogType } = require("./sub-log");
const log = require("./sub-log");
const auth = require("./sub-auth");
@ -7,6 +7,9 @@ const cook = require("cookie")
const wlog = new LogType("Web")
const subplayer = require(__glob.SUBPLAYER);
const { List } = require("./sub-list")
const subplaylist = require("./sub-playlist")
module.exports.WebServer = class {
constructor() {
@ -196,6 +199,20 @@ function IOConnection(io) {
io.sockets.emit("/ALWAYS/MUSIC_STATE", data)
})
GetRequest(io, socket, "PLAYLIST", () => {
var cookies = socket.handshake.headers.cookie
cookies = cook.parse(cookies)
var token = cookies.token
const user = auth.getUser(token)
const playlistResult = subplaylist.getUser(user.user.id)
socket.emit("ANSWER/GET/PLAYLIST", playlistResult)
})
@ -243,6 +260,15 @@ function IOConnection(io) {
})
GetRequest(io, socket, "RESTART", () => {
const pm2 = require('pm2');
pm2.restart('SubSonics - Bot Discord')
})
GetRequest(io, socket, "SPECIAL/MJ", () => {
@ -503,6 +529,152 @@ function IOConnection(io) {
})
socket.on("SEND/CREATE_PLAYLIST", async (data) => {
var cookies = socket.handshake.headers.cookie
if(cookies) {
cookies = cook.parse(cookies)
var token = cookies.token
if(auth.checkUser(token)) {
var user = auth.getUser(token)
var userId = user.user.id
subplaylist.addPlaylist(userId, data)
io.emit("DO_UPDATE_PLAYLIST")
io.emit("ANSWER/SEND/CREATE_PLAYLIST/OK")
} else {
io.emit("ANSWER/SEND/CREATE_PLAYLIST", {"error":"USER_DONT_EXIST"})
}
} else {
io.emit("ANSWER/SEND/CREATE_PLAYLIST", {"error":"TOKEN_NOT_FINDED"})
}
})
socket.on("SEND/DELETE_PLAYLIST", async (data) => {
var cookies = socket.handshake.headers.cookie
if(cookies) {
cookies = cook.parse(cookies)
var token = cookies.token
if(auth.checkUser(token)) {
var user = auth.getUser(token)
var userId = user.user.id
subplaylist.removePlaylist(userId, data)
io.emit("DO_UPDATE_PLAYLIST")
io.emit("ANSWER/SEND/DELETE_PLAYLIST/OK")
} else {
io.emit("ANSWER/SEND/DELETE_PLAYLIST", {"error":"USER_DONT_EXIST"})
}
} else {
io.emit("ANSWER/SEND/DELETE_PLAYLIST", {"error":"TOKEN_NOT_FINDED"})
}
})
socket.on("SEND/ADD_SONG_TO_PLAYLIST", async (data, song) => {
var cookies = socket.handshake.headers.cookie
if(cookies) {
cookies = cook.parse(cookies)
var token = cookies.token
if(auth.checkUser(token)) {
var user = auth.getUser(token)
var userId = user.user.id
subplaylist.addSong(userId, data, song)
io.emit("DO_UPDATE_PLAYLIST")
io.emit("ANSWER/SEND/ADD_SONG_TO_PLAYLIST/OK")
} else {
io.emit("ANSWER/SEND/ADD_SONG_TO_PLAYLIST", {"error":"USER_DONT_EXIST"})
}
} else {
io.emit("ANSWER/SEND/ADD_SONG_TO_PLAYLIST", {"error":"TOKEN_NOT_FINDED"})
}
})
socket.on("SEND/DELETE_SONG_TO_PLAYLIST", async (data, song) => {
var cookies = socket.handshake.headers.cookie
if(cookies) {
cookies = cook.parse(cookies)
var token = cookies.token
if(auth.checkUser(token)) {
var user = auth.getUser(token)
var userId = user.user.id
subplaylist.removeSong(userId, data, song)
io.emit("DO_UPDATE_PLAYLIST")
io.emit("ANSWER/SEND/DELETE_SONG_TO_PLAYLIST/OK")
} else {
io.emit("ANSWER/SEND/DELETE_SONG_TO_PLAYLIST", {"error":"USER_DONT_EXIST"})
}
} else {
io.emit("ANSWER/SEND/DELETE_SONG_TO_PLAYLIST", {"error":"TOKEN_NOT_FINDED"})
}
})
@ -528,6 +700,8 @@ function GetRequest (io, socket, name, func) {
if(auth.checkUser(token)) {
const user = auth.getUser(token)
wlog.log("Requête de " + user.user.username + " avec l'information \"" + name + "\"")
func()
} else {

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: $$$/GeneralStr/196=Adobe Illustrator 27.6.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-5.6112" y1="-3.8605" x2="209.7163" y2="212.1815">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="0.2662" style="stop-color:#9B9B9A"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<rect x="-12.202" y="-9.773" style="fill:url(#SVGID_1_);stroke:#000000;stroke-miterlimit:10;" width="222.626" height="221.963"/>
</g>
<g>
<polygon style="fill:#FFFFFF;" points="153.605,27.568 66.499,59.327 66.498,49.578 149.843,19.207 153.6,17.838 "/>
<g>
<ellipse transform="matrix(0.938 -0.3466 0.3466 0.938 -34.4075 53.653)" style="fill:#FFFFFF;" cx="132.775" cy="123.007" rx="21.27" ry="17.78"/>
<rect x="150.06" y="19.307" style="fill:#FFFFFF;" width="3.524" height="102.982"/>
</g>
<ellipse transform="matrix(0.938 -0.3466 0.3466 0.938 -50.0962 26.5542)" style="fill:#FFFFFF;" cx="49.18" cy="153.313" rx="21.27" ry="17.78"/>
<rect x="66.465" y="49.613" style="fill:#FFFFFF;" width="3.524" height="102.982"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -30,11 +30,11 @@ function get(request) {
}
function send(request, data) {
function send(request, data, secondata, thirddata) {
return new Promise((resolve, reject) => {
socket.emit("SEND/" + request, data)
socket.emit("SEND/" + request, data, secondata, thirddata)
console.log("Envoi de la requête SEND : " + request)
socket.once("ANSWER/SEND/" + request, (answer) => {

View File

@ -17,7 +17,7 @@ const settings_dialog = document.getElementById("SETTINGS_dialog")
const settings_close = document.getElementById("SETTINGS_close")
const settingsBtn = document.getElementById("settingsBtn")
const SPECIAL = document.getElementById("SPECIAL")
const loop = document.getElementById("loop")
const vol = document.getElementById("vol")
@ -43,10 +43,27 @@ const report_level = document.getElementById("report_level")
const report_desc = document.getElementById("report_desc")
const report_send = document.getElementById("report_send")
const searchBar = document.getElementById("searchBar")
const searchcontent = document.getElementById("search_content")
const searchBtn = document.getElementById("search_btn")
const homeBtn = document.getElementById("home_btn")
const mainView = document.getElementById("mainView")
const WelcomeContent = searchcontent.outerHTML
const restartBtn = document.getElementById("restartBtn")
const WelcomeContent = mainView.firstElementChild.outerHTML
const playlistContent = document.getElementById("playlist-content")
var playlistSelected = null
var deleteJustBefore = null
var playlistAvailable = null
restartBtn.addEventListener("click", () => {
get("RESTART")
})
homeBtn.style.color = "white"
var xMousePos = 0;
var yMousePos = 0;
@ -57,25 +74,84 @@ document.onmousemove = function(e)
};
homeBtn.addEventListener("click", () => {
searchBar.addEventListener("change", () => {
mainView.innerHTML = WelcomeContent
if(searchBar.value == "") {
})
function delPlayList(key) {
send("DELETE_PLAYLIST", key)
mainView.innerHTML = WelcomeContent
}
socket.on("DO_UPDATE_PLAYLIST", () => {
get("PLAYLIST")
})
get("PLAYLIST")
socket.on("ANSWER/GET/PLAYLIST", (data) => {
var contentToPush = new Array()
var selectionData = new Array()
for (const [key, value] of Object.entries(data)) {
contentToPush.push('<div id="' + key + '_playlist" class="playlist_div checker"><img class="playlist_tile" src="/images/playlist-tile.svg"><p>' + key + '</p></div>')
selectionData.push('<option style="color: black;">' + key + '</option>')
}
contentToPush.push('<div id="SPECIAL" class="playlist_div"><i class="fa-solid fa-gears playlist_tile"></i> Debug</div>')
contentToPush.push('<div id="addPlaylist" class="playlist_div"><i class="fa-solid fa-plus playlist_tile"></i> Ajouter une playlist</div>')
if(contentToPush.join("") == "") {
playlistContent.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
searchcontent.innerHTML = WelcomeContent
} else {
send("SEARCH", searchBar.value).then(results => {
playlistContent.innerHTML = contentToPush.join("")
playlistAvailable = selectionData
}
if(results.tracks != null) {
const data = results.tracks
if(playlistSelected && deleteJustBefore) {
deleteJustBefore = null
loadPlaylist(playlistSelected, data[playlistSelected])
}
console.log(data)
var contentToPush = new Array()
for (const [key, value] of Object.entries(data)) {
for(var title of data) {
const playlist_selector = document.getElementById(key + '_playlist')
var Formatduration = null
playlist_selector.addEventListener("click", () => {
loadPlaylist(key, value)
})
}
function loadPlaylist(key, value) {
var playlistToPush = new Array()
var playlist_songs = new Array()
playlistSelected = key
for(var title of value) {
var Formatduration = null
durationAll = title.duration
const maxhours = Math.floor(durationAll / 3600000);
@ -103,74 +179,259 @@ searchBar.addEventListener("change", () => {
}
Formatduration = max
contentToPush.push(' <div class="search_song"> <img class="search_thumbnail" src="' + title.thumbnail + '"><div class="search_titleSong"> <p class="search_title">' + title.title + '</p></div> <p>' + title.author + '</p><p>' + Formatduration + '</p> <div class="search_buttons"><button id="' + data.indexOf(title) + '_ladd" class="search_add"><i class="fa fa-plus"></i></button> <div class="searchMoreDiv"><button id="' + data.indexOf(title) + '_lmore" class="search_lmore"><i class="fa-solid fa-ellipsis"></i></button></div><div class="searchPopup" id="' + data.indexOf(title) + '_popup"><div id="' + data.indexOf(title) + '_playNow" class="INDEX_line"><i class="fa-solid fa-play"></i> Lire maintenant</div><!--<div id="' + data.indexOf(title) +'_addlater" class="INDEX_line"><i class="fa-solid fa-list-ul"></i> Ajouter à une playlist</div>--></div></div></div>')
}
if(contentToPush.join("") == "") {
searchcontent.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
} else {
searchcontent.innerHTML = contentToPush.join("")
}
for(var title of data) {
const add_to = document.getElementById(data.indexOf(title) + "_ladd")
const test_lmore = document.getElementById(data.indexOf(title) + "_lmore")
const testPopup = document.getElementById(data.indexOf(title) + "_popup")
const playNow = document.getElementById(data.indexOf(title) + "_playNow")
testPopup.style.display = "none"
add_to.addEventListener("click", () => {
send("ADD_SONG", data[add_to.id.replace("_ladd", "")])
})
test_lmore.addEventListener("click",( ) => {
testPopup.style.display = "flex"
testPopup.style.top = yMousePos + "px"
document.getElementById("test").show()
console.log()
})
testPopup.addEventListener("mouseleave", () => {
testPopup.style.display = "none"
})
playNow.addEventListener("click", () => {
send("ADD_SONG_NOW", data[add_to.id.replace("_ladd", "")])
})
}
} else {
searchcontent.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
playlist_songs.push('<div class="search_song"> <img class="search_thumbnail" src="' + title.thumbnail + '"><div class="search_titleSong"> <p class="search_title">' + title.title + '</p></div> <p>' + title.author + '</p><p>' + Formatduration + '</p> <div class="search_buttons"><button id="' + value.indexOf(title) + '_padd" class="search_add"><i class="fa fa-plus"></i></button><button id="' + value.indexOf(title) + '_pplay" class="search_lmore"><i class="fa fa-play"></i></button><button id="' + value.indexOf(title) + '_pdelete" style="font-size: 20px;" class="list_delete"><i class="fa fa-trash"></i></button></div></div>')
}
})
playlistToPush.push('<div class="apPres"><div class="apTitle"><img class="apTile" src="/images/playlist-tile.svg"><p class="apName">' + key + '</p></div><div class="apButtons"><button id="'+ key +'_playlistplay" class="primary"><i class="fas fa-play"></i></button><button onclick="delPlayList(\''+ key +'\')" "id="'+ key +'_playlistdelete" class="list_delete"><i class="fas fa-trash"></i></button></div></div><hr>' + playlist_songs.join(""))
if(playlistToPush.join("") == "") {
mainView.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
} else {
mainView.innerHTML = playlistToPush.join("")
}
for(var title of value) {
const add_to = document.getElementById(value.indexOf(title) + "_padd")
const playNow = document.getElementById(value.indexOf(title) + "_pplay")
const deleteBtn = document.getElementById(value.indexOf(title) + "_pdelete")
add_to.addEventListener("click", () => {
send("ADD_SONG", value[add_to.id.replace("_padd", "")])
})
playNow.addEventListener("click", () => {
send("ADD_SONG_NOW", value[add_to.id.replace("_padd", "")])
})
deleteBtn.addEventListener("click", () => {
deleteJustBefore = true
send("DELETE_SONG_TO_PLAYLIST", key, value[add_to.id.replace("_padd", "")])
})
}
}
const buttons = document.querySelectorAll(".checker");
buttons.forEach(button => {
button.addEventListener("click", function () {
buttons.forEach(btn => {
if (btn === button) {
btn.style.color = "white";
} else {
btn.style.color = "";
}
});
});
});
const SPECIAL = document.getElementById("SPECIAL")
const addPlaylist = document.getElementById("addPlaylist")
const addPlaylist_dialog = document.getElementById("addPlaylist_dialog")
const apText = document.getElementById("apText")
const apCreate = document.getElementById("apCreate")
addPlaylist_close.addEventListener("click", () => {
addPlaylist_dialog.close()
})
addPlaylist.addEventListener("click", () => {
apText.value = ""
addPlaylist_dialog.showModal()
})
apCreate.addEventListener("click", () => {
addPlaylist_dialog.close()
send("CREATE_PLAYLIST", apText.value)
})
SPECIAL.addEventListener("click", () => {
get("SPECIAL/MJ")
})
console.log(data)
})
searchBtn.addEventListener("click", () => {
mainView.innerHTML = '<div class="findbar"><i class="fa fa-search"></i><input autofocus id="searchBar" placeholder="Insérez des mots-clés ou un lien" type="text"></div><div class="search_middle"></div><div id="search_content"></div>'
const searchBar = document.getElementById("searchBar")
const searchcontent = document.getElementById("search_content")
searchBar.addEventListener("change", () => {
send("SEARCH", searchBar.value).then(results => {
if(results.tracks != null) {
const data = results.tracks
console.log(data)
var contentToPush = new Array()
for(var title of data) {
var Formatduration = null
durationAll = title.duration
const maxhours = Math.floor(durationAll / 3600000);
var maxmin = Math.trunc(durationAll / 60000) - (Math.floor(durationAll / 60000 / 60) * 60);
var maxsec = Math.floor(durationAll / 1000) - (Math.floor(durationAll / 1000 / 60) * 60);
if (maxsec < 10) {
maxsec = `0${maxsec}`;
}
if(maxhours != 0) {
if (maxmin < 10) {
maxmin = `0${maxmin}`;
}
max = maxhours + ":" + maxmin + ":" + maxsec
} else {
max = maxmin + ":" + maxsec
}
Formatduration = max
contentToPush.push(' <div class="search_song"> <img class="search_thumbnail" src="' + title.thumbnail + '"><div class="search_titleSong"> <p class="search_title">' + title.title + '</p></div> <p>' + title.author + '</p><p>' + Formatduration + '</p> <div class="search_buttons"><button id="' + data.indexOf(title) + '_ladd" class="search_add"><i class="fa fa-plus"></i></button> <div class="searchMoreDiv"><button id="' + data.indexOf(title) + '_lmore" class="search_lmore"><i class="fa-solid fa-ellipsis"></i></button></div><div class="searchPopup" id="' + data.indexOf(title) + '_popup"><div id="' + data.indexOf(title) + '_playNow" class="INDEX_line"><i class="fa-solid fa-play"></i> Lire maintenant</div><div id="' + data.indexOf(title) +'_addPlaylist" class="INDEX_line"><i class="fa-solid fa-list-ul"></i> Ajouter à une playlist</div></div></div><dialog id="' + data.indexOf(title) + 'playlistManager" class="report_dialog"><div class="rlineclose"><p class="rtitle"><i class="fa fa-list-ol"></i> Ajouter à une playlist</p><button id="' + data.indexOf(title) + 'playlistManager_close" class="report_close"><i class="fa-solid fa-xmark"></i></button></div><div class="apContent"><img id="' + data.indexOf(title) + 'playlist_add_img" class="ppTile" src="/images/playlist-tile.svg"><p style="padding: 1%;" id="' + data.indexOf(title) + 'playlist_add_music"></p><p>Selectionner la playlist</p><select style=" color: white; background-color: transparent; border: solid 2px #2c3df4;padding: 1%; border-radius: 12px;" id="' + data.indexOf(title) + 'playlistSelection"></select><button id="' + data.indexOf(title) + 'playlistAddSong" class="rsend"><i class="fa fa-plus"></i> Ajouter</button></div></dialog></div>')
}
if(contentToPush.join("") == "") {
searchcontent.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
} else {
searchcontent.innerHTML = contentToPush.join("")
}
for(var title of data) {
const add_to = document.getElementById(data.indexOf(title) + "_ladd")
const test_lmore = document.getElementById(data.indexOf(title) + "_lmore")
const testPopup = document.getElementById(data.indexOf(title) + "_popup")
const playNow = document.getElementById(data.indexOf(title) + "_playNow")
const addPlaylist = document.getElementById(data.indexOf(title) + "_addPlaylist")
const PlaylistManager = document.getElementById(data.indexOf(title) + "playlistManager")
const playlistManager_close = document.getElementById(data.indexOf(title) + "playlistManager_close")
const playlistSelection = document.getElementById(data.indexOf(title) + "playlistSelection")
const playlist_add_music = document.getElementById(data.indexOf(title) + "playlist_add_music")
const playlist_add_img = document.getElementById(data.indexOf(title) + "playlist_add_img")
const playlistAddSong = document.getElementById(data.indexOf(title) + "playlistAddSong")
testPopup.style.display = "none"
add_to.addEventListener("click", () => {
send("ADD_SONG", data[add_to.id.replace("_ladd", "")])
})
addPlaylist.addEventListener("click", () => {
PlaylistManager.showModal()
playlist_add_music.innerHTML = data[add_to.id.replace("_ladd", "")].title
playlist_add_img.src = data[add_to.id.replace("_ladd", "")].thumbnail
playlistSelection.innerHTML = playlistAvailable
})
playlistManager_close.addEventListener("click", () => {
PlaylistManager.close()
})
playlistAddSong.addEventListener("click", () => {
PlaylistManager.close()
socket.emit("SEND/ADD_SONG_TO_PLAYLIST", playlistSelection.value , data[add_to.id.replace("_ladd", "")])
})
test_lmore.addEventListener("click",( ) => {
testPopup.style.display = "flex"
testPopup.style.top = yMousePos + "px"
})
testPopup.addEventListener("mouseleave", () => {
testPopup.style.display = "none"
})
playNow.addEventListener("click", () => {
send("ADD_SONG_NOW", data[add_to.id.replace("_ladd", "")])
})
}
} else {
searchcontent.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
}
})
})
})
volBox.classList.add("invisible")
listBox.classList.add("invisible")
@ -216,11 +477,6 @@ disconnect.addEventListener("click", () => {
get("DISCONNECT")
})
SPECIAL.addEventListener("click", () => {
get("SPECIAL/MJ")
})
/*settingsBtn.addEventListener("click", () => {
@ -283,6 +539,8 @@ userInfo.then(user => {
}
userInfoDiv.innerHTML = "<div class='INDEX_userInfo_name'><p class='INDEX_gbname'>" + user.user.global_name + "</p><p class='INDEX_usrname'>" + user.user.username + "</p></div><div class='INDEX_picture'><img src='https://cdn.discordapp.com/avatars/" + user.user.id + "/" + user.user.avatar + "'>" + betastar + "</div>"
})
@ -297,6 +555,7 @@ userInfoDiv.addEventListener("click", () => {
}
})
userInfoPopup.classList.add("invisible")
userInfoPopup.addEventListener("mouseleave", () => {
@ -306,6 +565,8 @@ userInfoPopup.addEventListener("mouseleave", () => {
get("MUSIC_STATE").then(data => {
console.log(data)
})
@ -328,7 +589,6 @@ forward.addEventListener("click", () => {
socket.on("/ALWAYS/MUSIC_STATE", (data) => {
stopInterval()
console.log(data)

View File

@ -770,9 +770,10 @@ p {
.INDEX_playlist {
background-color: #2e2e2e86;
width: 0%;
width: 20%;
height: 68vh;
border-radius: 12px;
overflow-y: auto;
}
.INDEX_search {
@ -837,7 +838,7 @@ p {
.search_thumbnail {
width: 100px;
height: 75px;
margin-right: 20px;
}
.search_middle {
@ -902,3 +903,131 @@ p {
z-index: 2;
}
/* PLAYLIST */
.pSearch {
display: flex;
color: rgba(255, 255, 255, 0.719);
flex-direction: row;
align-items: center;
margin-top: 5%;
width: 100%;
padding: 2%;
padding-left: 7%;
font-size: 20px;
transition: 0.1s;
}
.pSearch:hover {
cursor: pointer;
}
.pSearch p {
width: 100%;
}
.playlist-content {
}
.playlist_div {
color: rgba(255, 255, 255, 0.719);
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
padding: 4%;
}
.playlist_div:hover {
background-color: rgb(255, 255, 255);
color: black !important;
cursor: pointer;
}
.playlist_tile {
width: 60px;
height: 60px;
margin-right: 5%;
}
.apContent {
display: flex;
flex-direction: column;
text-align: center;
align-items: center;
color: white;
margin-top: 5%;
}
.apContent p {
padding: 3%;
}
#apText {
border: none;
border-radius: 12px;
padding: 0.5%;
padding-left: 1%;
}
.apTile {
width: 150px;
height: 150px;
}
.apTitle {
display: flex;
width: 60%;
align-items: end;
}
.apPres {
display: flex;
align-items: end;
justify-content: space-between;
}
.apName {
font-family: "Gunship", sans-serif;
font-size: 35px;
margin-left: 2% !important;
}
.apButtons {
display: flex;
justify-content: end;
align-items: center;
gap: 10%;
width: 10%;
}
.ppTile {
width: 180px;
}

View File

@ -17,35 +17,49 @@
<div class="INDEX_userInfo" id="userInfo"></div>
<div class="INDEX_userPopup" id="userPopup">
<!--div id="settingsBtn" class="INDEX_line"><i class="fa-solid fa-wrench"></i> Paramètres</div>-->
<div id="SPECIAL" class="INDEX_line"><i class="fa-solid fa-gears"></i> Debug</div>
<div id="reportBtn" class="INDEX_line"><i class="fa-solid fa-bug"></i> Rapport</div>
<div id="restartBtn" class="INDEX_line"><i class="fa-solid fa-power-off"></i> Redémarrer</div>
<a class="INDEX_signout" href="/internal/logout"><i class="fa fa-sign-out " aria-hidden="true"></i> Déconnexion</a>
</div>
</div>
</div>
<div class="INDEX_subcontent">
<div class="INDEX_playlist">
<div id="home_btn" class="pSearch checker">
</div>
<div class="INDEX_search">
<div class="findbar">
<i class="fa fa-search"></i>
<input id="searchBar" placeholder="Insérez des mots-clés ou un lien" type="text">
<p><i class="fa fa-home"></i> Accueil</p>
</div>
<div class="search_middle"></div>
<div id="search_btn" class="pSearch checker">
<div id="search_content">
<div style="color: white">
<p><i class="fa fa-search"></i> Rechercher</p>
</div>
<hr style="color: white;">
<div class="playlist-content" id="playlist-content">
<%- welcome %>
</div>
<dialog id="addPlaylist_dialog" class="report_dialog">
<div class="rlineclose">
<p class="rtitle"><i class="fa fa-plus"></i> Ajouter une playlist</p>
<button id="addPlaylist_close" class="report_close"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="apContent">
<img class="apTile" src="/images/playlist-tile.svg">
<p>Nom de la playlist</p>
<input type="text" id="apText">
<button id="apCreate" class="rsend"><i class="fa fa-plus"></i> Créer</button>
</div>
</dialog>
</div>
<div style="color: white" id="mainView" class="INDEX_search">
<div style="color: white">
<%- welcome %>
</div>
</div>
</div>