Version 0.6.0 - Ajout des playlists
This commit is contained in:
parent
e34134537e
commit
d5651f8cef
14
README.md
14
README.md
@ -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
|
||||
|
@ -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
39
data/playlist.json
Normal 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
4
package-lock.json
generated
@ -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",
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
103
src/modules/sub-playlist.js
Normal 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))
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
25
src/web/public/images/playlist-tile.svg
Normal file
25
src/web/public/images/playlist-tile.svg
Normal 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 |
@ -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) => {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user