Version 1.1.0 - Preversion 2.0.0 - Rework Code & Fixes
							
								
								
									
										20
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@@ -20,3 +20,23 @@
 | 
			
		||||
</strong>
 | 
			
		||||
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Changelog
 | 
			
		||||
 | 
			
		||||
## Subsonics - Web - 2.0.0
 | 
			
		||||
 - **Adds :** *Rework Style, Soundboard Editor, OOBE*
 | 
			
		||||
 ### Details
 | 
			
		||||
**Rework Style**
 | 
			
		||||
> - Style principal, (Cf StylePlans)
 | 
			
		||||
> - Création d'éléments modèles (Classe commune)
 | 
			
		||||
> - Permettre l'ajout de playlist youtube en favoris
 | 
			
		||||
 | 
			
		||||
**Soundboard Editor**
 | 
			
		||||
> - Faire l'HTML & CSS
 | 
			
		||||
> - Faire le lien entre l'API Discord et Subsonics
 | 
			
		||||
> - Demander les permissions à IcePlayer
 | 
			
		||||
 | 
			
		||||
**OOBE**
 | 
			
		||||
> - Faire l'HTML & CSS
 | 
			
		||||
> - Faire la vérification de la lecture de l'OOBE
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
["486943594893017119","442290526545510421"]
 | 
			
		||||
@@ -2,6 +2,31 @@
 | 
			
		||||
  {
 | 
			
		||||
    "name": "visitorCounted",
 | 
			
		||||
    "description": "Nombre de visiteurs",
 | 
			
		||||
    "value": 1023
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "numberOfCommands",
 | 
			
		||||
    "description": "Nombre de commandes éxécutées",
 | 
			
		||||
    "value": 3
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "userCommand_raphixscrap",
 | 
			
		||||
    "description": "Nombre de commandes éxécutées par l'utilisateur : raphixscrap",
 | 
			
		||||
    "value": 2
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "songPlayed",
 | 
			
		||||
    "description": "Nombre de musiques jouées",
 | 
			
		||||
    "value": 25
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "songDuration",
 | 
			
		||||
    "description": "Durée totale des musiques jouées en secondes",
 | 
			
		||||
    "value": 5641
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "name": "userMusicPlayed_raphixscrap",
 | 
			
		||||
    "description": "Nombre de musiques jouées par l'utilisateur : raphixscrap",
 | 
			
		||||
    "value": 17
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								data/pictures/158369928104116224.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 31 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/168086507486314496.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 32 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/172437570905571328.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 21 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/226744358567804928.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 32 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/249494159629484033.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 30 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/253494094179991552.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 MiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/362983050054991872.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 20 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/428869747594231808.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 34 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/435462012974268426.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 26 KiB  | 
							
								
								
									
										0
									
								
								data/pictures/442290526545510421.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								data/pictures/454603829556805632.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 40 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/pictures/486943594893017119.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 30 KiB  | 
@@ -382,6 +382,391 @@
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=jfKfPfyJRdk",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/jfKfPfyJRdk/default.jpg"
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "Liste de lecture Immu": [
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAhAIAIFRoYW5jcmVkIFdhdGVyczogVGhlIE1hbiAtIEZGWElWAApGbHVmZlN0dWZmAAAAAAAENiAAC3dGV1pMLTFJWG5jAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9d0ZXWkwtMUlYbmMAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "Thancred Waters: The Man - FFXIV",
 | 
			
		||||
        "identifier": "wFWZL-1IXnc",
 | 
			
		||||
        "author": "FluffStuff",
 | 
			
		||||
        "duration": 276000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=wFWZL-1IXnc",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/wFWZL-1IXnc/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAvwIAYkZveGVzIHBlcmZvcm1zICdEb24ndCBTdG9wIE1lIE5vdycgb24gYm9hcmQgdGhlIE9yaWVudCBFeHByZXNzIC0gRG9jdG9yIFdobzogU2VyaWVzIDggKDIwMTQpIC0gQkJDAANCQkMAAAAAAAMVEAALaC1PVFlUMDJXN0UAAQAraHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1oLU9UWVQwMlc3RQAHeW91dHViZQAAAAAAAAAA",
 | 
			
		||||
        "title": "Foxes performs 'Don't Stop Me Now' on board the Orient Express - Doctor Who: Series 8 (2014) - BBC",
 | 
			
		||||
        "identifier": "h-OTYT02W7E",
 | 
			
		||||
        "author": "BBC",
 | 
			
		||||
        "duration": 202000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=h-OTYT02W7E",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/h-OTYT02W7E/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAjAIAKkRvY3RvciBXaG8gKDEtMTEpIHZpZDogR29uZSBpbiB0aGUgTW9ybmluZwAIc2hheWVyYTkAAAAAAAIqsAALazNWclpETVhIbUUAAQAraHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1rM1ZyWkRNWEhtRQAHeW91dHViZQAAAAAAAAAA",
 | 
			
		||||
        "title": "Doctor Who (1-11) vid: Gone in the Morning",
 | 
			
		||||
        "identifier": "k3VrZDMXHmE",
 | 
			
		||||
        "author": "shayera9",
 | 
			
		||||
        "duration": 142000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=k3VrZDMXHmE",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/k3VrZDMXHmE/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAhwIAJjMgRG9vcnMgRG93biAtIEtyeXB0b25pdGUgKFNtYWxsVmlsbGUpAAdXRUlMSU5OAAAAAAADikAAC0VPTzRWTjFHM0dZAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9RU9PNFZOMUczR1kAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "3 Doors Down - Kryptonite (SmallVille)",
 | 
			
		||||
        "identifier": "EOO4VN1G3GY",
 | 
			
		||||
        "author": "WEILINN",
 | 
			
		||||
        "duration": 232000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=EOO4VN1G3GY",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/EOO4VN1G3GY/default.jpg"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "226744358567804928": {
 | 
			
		||||
    "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"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAgwIAHU15bGVuZSBGYXJtZXIgLSBQZXV0LUV0cmUgVG9pAAxNdXNpY2Jlc3QxMTEAAAAAAASIKAALOE0zRndOYjZnTFkAAQAraHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj04TTNGd05iNmdMWQAHeW91dHViZQAAAAAAAAAA",
 | 
			
		||||
        "title": "Mylene Farmer - Peut-Etre Toi",
 | 
			
		||||
        "identifier": "8M3FwNb6gLY",
 | 
			
		||||
        "author": "Musicbest111",
 | 
			
		||||
        "duration": 297000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=8M3FwNb6gLY",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/8M3FwNb6gLY/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAfgIAG1ZheWEgY29uIGRpb3MgLSBOYWggbmVoIG5haAAJRGFuaWtsZWluAAAAAAACo8gACzdMVW0tRTRHUFU4AAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9N0xVbS1FNEdQVTgAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "Vaya con dios - Nah neh nah",
 | 
			
		||||
        "identifier": "7LUm-E4GPU8",
 | 
			
		||||
        "author": "Daniklein",
 | 
			
		||||
        "duration": 173000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=7LUm-E4GPU8",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/7LUm-E4GPU8/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAigIAJ0lGU0NMIDQuNS5YIFRyYWlsZXIgWyBDb2RlIEx5b2tvIEdhbWUgXQAJSW1tdWRlbGtpAAAAAAABtYAAC1cyVXI1NkNFQXdvAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9VzJVcjU2Q0VBd28AB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "IFSCL 4.5.X Trailer [ Code Lyoko Game ]",
 | 
			
		||||
        "identifier": "W2Ur56CEAwo",
 | 
			
		||||
        "author": "Immudelki",
 | 
			
		||||
        "duration": 112000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=W2Ur56CEAwo",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/W2Ur56CEAwo/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAwwIASVRIUklMTEVSICAgMzV0aCBBbm5pdmVyc2FyeSBTV0cgUmVtYXN0ZXJlZCBFeHRlbmRlZCBNaXggICBNSUNIQUVMIEpBQ0tTT04AIEV4cHJlY2lvbiBNdXNpY2FsIEFsdGVybmF0aXZhIEZNAAAAAAAIZHAAC1UtUnlXSzJERlM4AAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9VS1SeVdLMkRGUzgAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "THRILLER   35th Anniversary SWG Remastered Extended Mix   MICHAEL JACKSON",
 | 
			
		||||
        "identifier": "U-RyWK2DFS8",
 | 
			
		||||
        "author": "Exprecion Musical Alternativa FM",
 | 
			
		||||
        "duration": 550000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=U-RyWK2DFS8",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/U-RyWK2DFS8/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAnAIAOUlGU0NMIDEzdGggVWx0aW1hdGUgQW5uaXZlcnNhcnkgVHJhaWxlciB8IENvZGUgTHlva28gR2FtZQAJSW1tdWRlbGtpAAAAAAABrbAAC2tZTTV4WUxzMUJBAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9a1lNNXhZTHMxQkEAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "IFSCL 13th Ultimate Anniversary Trailer | Code Lyoko Game",
 | 
			
		||||
        "identifier": "kYM5xYLs1BA",
 | 
			
		||||
        "author": "Immudelki",
 | 
			
		||||
        "duration": 110000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=kYM5xYLs1BA",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/kYM5xYLs1BA/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAfQIAH0fDqW7DqXJpcXVlIFBva8OpbW9uIENocm9uaWNsZXMABHRvdG8AAAAAAACUcAALSzRzRm5RTFV1ZXcAAQAraHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1LNHNGblFMVXVldwAHeW91dHViZQAAAAAAAAAA",
 | 
			
		||||
        "title": "Générique Pokémon Chronicles",
 | 
			
		||||
        "identifier": "K4sFnQLUuew",
 | 
			
		||||
        "author": "toto",
 | 
			
		||||
        "duration": 38000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=K4sFnQLUuew",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/K4sFnQLUuew/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAABEAIALVJlcGxpY2F0aW9uIG9mIENpbmVtb3JwaGlxdWUgLSBOZXcgQ2hhbGxlbmdlcwAGUmFwaGl4AAAAAAABqJgAck86aHR0cHM6Ly9hcGktdjIuc291bmRjbG91ZC5jb20vbWVkaWEvc291bmRjbG91ZDp0cmFja3M6MTYwNDMwNjc4NC81YmUxOWNiZS03NTkyLTQ0ODktYjMzMC0yN2RlZGMyYTFjZjIvc3RyZWFtL2hscwABAERodHRwczovL3NvdW5kY2xvdWQuY29tL3JhcGhpeC0zNTkzMDEwNjkvY2luZW1vcnBoaXF1ZS1uZXctY2hhbGxlbmdlcwAKc291bmRjbG91ZAAAAAAAAAAA",
 | 
			
		||||
        "title": "Replication of Cinemorphique - New Challenges",
 | 
			
		||||
        "identifier": "O:https://api-v2.soundcloud.com/media/soundcloud:tracks:1604306784/5be19cbe-7592-4489-b330-27dedc2a1cf2/stream/hls",
 | 
			
		||||
        "author": "Raphix",
 | 
			
		||||
        "duration": 108696,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://soundcloud.com/raphix-359301069/cinemorphique-new-challenges",
 | 
			
		||||
        "thumbnail": null
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAqwIANE11cnJheSBIZWFkIC0gT25lIE5pZ2h0IEluIEJhbmdrb2sgKExvbmcgSW50cm8gMTo0NykAHUpvc8OpIE9zdmFsZG8gT3J0aWdvemEg7aC87b6tAAAAAAAEp2gAC1l2RGdNZEdDUmEwAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WXZEZ01kR0NSYTAAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "Murray Head - One Night In Bangkok (Long Intro 1:47)",
 | 
			
		||||
        "identifier": "YvDgMdGCRa0",
 | 
			
		||||
        "author": "José Osvaldo Ortigoza 🎭",
 | 
			
		||||
        "duration": 305000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=YvDgMdGCRa0",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/YvDgMdGCRa0/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAkAIALkJvbiBKb3ZpIC0gSXQncyBNeSBMaWZlIChPZmZpY2lhbCBNdXNpYyBWaWRlbykACEJvbiBKb3ZpAAAAAAAEEvgAC3Z4MnU1dVV1M0RFAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9dngydTV1VXUzREUAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "Bon Jovi - It's My Life (Official Music Video)",
 | 
			
		||||
        "identifier": "vx2u5uUu3DE",
 | 
			
		||||
        "author": "Bon Jovi",
 | 
			
		||||
        "duration": 267000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=vx2u5uUu3DE",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/vx2u5uUu3DE/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAlwIAMllvdXNzb3UgTidEb3VyIC0gNyBTZWNvbmRzIChSYWRpbyBFZGl0KSBbQXVkaW8gSFFdAAtHb2xkZW5NdXNpYwAAAAAAA9hgAAtDaGlyZU5pcXhUbwABACtodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PUNoaXJlTmlxeFRvAAd5b3V0dWJlAAAAAAAAAAA=",
 | 
			
		||||
        "title": "Youssou N'Dour - 7 Seconds (Radio Edit) [Audio HQ]",
 | 
			
		||||
        "identifier": "ChireNiqxTo",
 | 
			
		||||
        "author": "GoldenMusic",
 | 
			
		||||
        "duration": 252000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=ChireNiqxTo",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/ChireNiqxTo/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAkQIALE1JQ0hBRUwgSkFDS1NPTiAtIEJBRCBbQUpBWMK0UyBFWFRFTkRFRCBNSVhdAAtBamF4U3RyaWtlcgAAAAAACDGoAAszRWE3XzZRdTJ4bwABACtodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PTNFYTdfNlF1MnhvAAd5b3V0dWJlAAAAAAAAAAA=",
 | 
			
		||||
        "title": "MICHAEL JACKSON - BAD [AJAX´S EXTENDED MIX]",
 | 
			
		||||
        "identifier": "3Ea7_6Qu2xo",
 | 
			
		||||
        "author": "AjaxStriker",
 | 
			
		||||
        "duration": 537000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=3Ea7_6Qu2xo",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/3Ea7_6Qu2xo/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAlgIAM2xvZmkgaGlwIGhvcCByYWRpbyDtoL3ts5ogLSBiZWF0cyB0byByZWxheC9zdHVkeSB0bwAJTG9maSBHaXJsf/////////8AC2pmS2ZQZnlKUmRrAQEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9amZLZlBmeUpSZGsAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "lofi hip hop radio 📚 - beats to relax/study to",
 | 
			
		||||
        "identifier": "jfKfPfyJRdk",
 | 
			
		||||
        "author": "Lofi Girl",
 | 
			
		||||
        "duration": 9223372036854776000,
 | 
			
		||||
        "isSeekable": false,
 | 
			
		||||
        "isStream": true,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=jfKfPfyJRdk",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/jfKfPfyJRdk/default.jpg"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "442290526545510421": {},
 | 
			
		||||
  "158369928104116224": {
 | 
			
		||||
    "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"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAgwIAHU15bGVuZSBGYXJtZXIgLSBQZXV0LUV0cmUgVG9pAAxNdXNpY2Jlc3QxMTEAAAAAAASIKAALOE0zRndOYjZnTFkAAQAraHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj04TTNGd05iNmdMWQAHeW91dHViZQAAAAAAAAAA",
 | 
			
		||||
        "title": "Mylene Farmer - Peut-Etre Toi",
 | 
			
		||||
        "identifier": "8M3FwNb6gLY",
 | 
			
		||||
        "author": "Musicbest111",
 | 
			
		||||
        "duration": 297000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=8M3FwNb6gLY",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/8M3FwNb6gLY/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAfgIAG1ZheWEgY29uIGRpb3MgLSBOYWggbmVoIG5haAAJRGFuaWtsZWluAAAAAAACo8gACzdMVW0tRTRHUFU4AAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9N0xVbS1FNEdQVTgAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "Vaya con dios - Nah neh nah",
 | 
			
		||||
        "identifier": "7LUm-E4GPU8",
 | 
			
		||||
        "author": "Daniklein",
 | 
			
		||||
        "duration": 173000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=7LUm-E4GPU8",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/7LUm-E4GPU8/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAigIAJ0lGU0NMIDQuNS5YIFRyYWlsZXIgWyBDb2RlIEx5b2tvIEdhbWUgXQAJSW1tdWRlbGtpAAAAAAABtYAAC1cyVXI1NkNFQXdvAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9VzJVcjU2Q0VBd28AB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "IFSCL 4.5.X Trailer [ Code Lyoko Game ]",
 | 
			
		||||
        "identifier": "W2Ur56CEAwo",
 | 
			
		||||
        "author": "Immudelki",
 | 
			
		||||
        "duration": 112000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=W2Ur56CEAwo",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/W2Ur56CEAwo/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAwwIASVRIUklMTEVSICAgMzV0aCBBbm5pdmVyc2FyeSBTV0cgUmVtYXN0ZXJlZCBFeHRlbmRlZCBNaXggICBNSUNIQUVMIEpBQ0tTT04AIEV4cHJlY2lvbiBNdXNpY2FsIEFsdGVybmF0aXZhIEZNAAAAAAAIZHAAC1UtUnlXSzJERlM4AAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9VS1SeVdLMkRGUzgAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "THRILLER   35th Anniversary SWG Remastered Extended Mix   MICHAEL JACKSON",
 | 
			
		||||
        "identifier": "U-RyWK2DFS8",
 | 
			
		||||
        "author": "Exprecion Musical Alternativa FM",
 | 
			
		||||
        "duration": 550000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=U-RyWK2DFS8",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/U-RyWK2DFS8/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAnAIAOUlGU0NMIDEzdGggVWx0aW1hdGUgQW5uaXZlcnNhcnkgVHJhaWxlciB8IENvZGUgTHlva28gR2FtZQAJSW1tdWRlbGtpAAAAAAABrbAAC2tZTTV4WUxzMUJBAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9a1lNNXhZTHMxQkEAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "IFSCL 13th Ultimate Anniversary Trailer | Code Lyoko Game",
 | 
			
		||||
        "identifier": "kYM5xYLs1BA",
 | 
			
		||||
        "author": "Immudelki",
 | 
			
		||||
        "duration": 110000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=kYM5xYLs1BA",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/kYM5xYLs1BA/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAfQIAH0fDqW7DqXJpcXVlIFBva8OpbW9uIENocm9uaWNsZXMABHRvdG8AAAAAAACUcAALSzRzRm5RTFV1ZXcAAQAraHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1LNHNGblFMVXVldwAHeW91dHViZQAAAAAAAAAA",
 | 
			
		||||
        "title": "Générique Pokémon Chronicles",
 | 
			
		||||
        "identifier": "K4sFnQLUuew",
 | 
			
		||||
        "author": "toto",
 | 
			
		||||
        "duration": 38000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=K4sFnQLUuew",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/K4sFnQLUuew/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAABEAIALVJlcGxpY2F0aW9uIG9mIENpbmVtb3JwaGlxdWUgLSBOZXcgQ2hhbGxlbmdlcwAGUmFwaGl4AAAAAAABqJgAck86aHR0cHM6Ly9hcGktdjIuc291bmRjbG91ZC5jb20vbWVkaWEvc291bmRjbG91ZDp0cmFja3M6MTYwNDMwNjc4NC81YmUxOWNiZS03NTkyLTQ0ODktYjMzMC0yN2RlZGMyYTFjZjIvc3RyZWFtL2hscwABAERodHRwczovL3NvdW5kY2xvdWQuY29tL3JhcGhpeC0zNTkzMDEwNjkvY2luZW1vcnBoaXF1ZS1uZXctY2hhbGxlbmdlcwAKc291bmRjbG91ZAAAAAAAAAAA",
 | 
			
		||||
        "title": "Replication of Cinemorphique - New Challenges",
 | 
			
		||||
        "identifier": "O:https://api-v2.soundcloud.com/media/soundcloud:tracks:1604306784/5be19cbe-7592-4489-b330-27dedc2a1cf2/stream/hls",
 | 
			
		||||
        "author": "Raphix",
 | 
			
		||||
        "duration": 108696,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://soundcloud.com/raphix-359301069/cinemorphique-new-challenges",
 | 
			
		||||
        "thumbnail": null
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAqwIANE11cnJheSBIZWFkIC0gT25lIE5pZ2h0IEluIEJhbmdrb2sgKExvbmcgSW50cm8gMTo0NykAHUpvc8OpIE9zdmFsZG8gT3J0aWdvemEg7aC87b6tAAAAAAAEp2gAC1l2RGdNZEdDUmEwAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WXZEZ01kR0NSYTAAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "Murray Head - One Night In Bangkok (Long Intro 1:47)",
 | 
			
		||||
        "identifier": "YvDgMdGCRa0",
 | 
			
		||||
        "author": "José Osvaldo Ortigoza 🎭",
 | 
			
		||||
        "duration": 305000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=YvDgMdGCRa0",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/YvDgMdGCRa0/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAkAIALkJvbiBKb3ZpIC0gSXQncyBNeSBMaWZlIChPZmZpY2lhbCBNdXNpYyBWaWRlbykACEJvbiBKb3ZpAAAAAAAEEvgAC3Z4MnU1dVV1M0RFAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9dngydTV1VXUzREUAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "Bon Jovi - It's My Life (Official Music Video)",
 | 
			
		||||
        "identifier": "vx2u5uUu3DE",
 | 
			
		||||
        "author": "Bon Jovi",
 | 
			
		||||
        "duration": 267000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=vx2u5uUu3DE",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/vx2u5uUu3DE/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAlwIAMllvdXNzb3UgTidEb3VyIC0gNyBTZWNvbmRzIChSYWRpbyBFZGl0KSBbQXVkaW8gSFFdAAtHb2xkZW5NdXNpYwAAAAAAA9hgAAtDaGlyZU5pcXhUbwABACtodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PUNoaXJlTmlxeFRvAAd5b3V0dWJlAAAAAAAAAAA=",
 | 
			
		||||
        "title": "Youssou N'Dour - 7 Seconds (Radio Edit) [Audio HQ]",
 | 
			
		||||
        "identifier": "ChireNiqxTo",
 | 
			
		||||
        "author": "GoldenMusic",
 | 
			
		||||
        "duration": 252000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=ChireNiqxTo",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/ChireNiqxTo/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAkQIALE1JQ0hBRUwgSkFDS1NPTiAtIEJBRCBbQUpBWMK0UyBFWFRFTkRFRCBNSVhdAAtBamF4U3RyaWtlcgAAAAAACDGoAAszRWE3XzZRdTJ4bwABACtodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PTNFYTdfNlF1MnhvAAd5b3V0dWJlAAAAAAAAAAA=",
 | 
			
		||||
        "title": "MICHAEL JACKSON - BAD [AJAX´S EXTENDED MIX]",
 | 
			
		||||
        "identifier": "3Ea7_6Qu2xo",
 | 
			
		||||
        "author": "AjaxStriker",
 | 
			
		||||
        "duration": 537000,
 | 
			
		||||
        "isSeekable": true,
 | 
			
		||||
        "isStream": false,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=3Ea7_6Qu2xo",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/3Ea7_6Qu2xo/default.jpg"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "track": "QAAAlgIAM2xvZmkgaGlwIGhvcCByYWRpbyDtoL3ts5ogLSBiZWF0cyB0byByZWxheC9zdHVkeSB0bwAJTG9maSBHaXJsf/////////8AC2pmS2ZQZnlKUmRrAQEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9amZLZlBmeUpSZGsAB3lvdXR1YmUAAAAAAAAAAA==",
 | 
			
		||||
        "title": "lofi hip hop radio 📚 - beats to relax/study to",
 | 
			
		||||
        "identifier": "jfKfPfyJRdk",
 | 
			
		||||
        "author": "Lofi Girl",
 | 
			
		||||
        "duration": 9223372036854776000,
 | 
			
		||||
        "isSeekable": false,
 | 
			
		||||
        "isStream": true,
 | 
			
		||||
        "uri": "https://www.youtube.com/watch?v=jfKfPfyJRdk",
 | 
			
		||||
        "thumbnail": "https://img.youtube.com/vi/jfKfPfyJRdk/default.jpg"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										417
									
								
								data/users.json
									
									
									
									
									
								
							
							
						
						@@ -1,42 +1,4 @@
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "gHgMkIRcjnOTRTJNPfRHWLEiIkYIw4",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "qkgDIogFGXM4A8PlO2zZmsCrdpQrvv",
 | 
			
		||||
      "scope": "identify guilds guilds.members.read"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2019-11-30T19:59:21.532000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725552968204288"
 | 
			
		||||
    ],
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "442290526545510421",
 | 
			
		||||
      "username": "mido_lol27",
 | 
			
		||||
      "avatar": "715cd4626ba7f734affdb2623bc4fb24",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 64,
 | 
			
		||||
      "flags": 64,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": null,
 | 
			
		||||
      "global_name": "Mido",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
      "banner_color": null
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "bd442487-c73e-451f-9e3b-9f902170f7d8",
 | 
			
		||||
    "admin": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
@@ -72,20 +34,104 @@
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "b4f1b8cd-2711-48b7-b301-0290f9d9f69b",
 | 
			
		||||
    "admin": false
 | 
			
		||||
    "token": "bd1edc6d-351f-443f-87ed-d52d2794758b",
 | 
			
		||||
    "admin": false,
 | 
			
		||||
    "picture": "/userspictures/226744358567804928.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "9mddRrtxla0BS69BVagf6fu2BHIHxa",
 | 
			
		||||
      "access_token": "A1XKJTzNC3TmCV6XJuy8uROva6e8Dc",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "9Rio7R8v8jbLTeJASem1zXKtz9YH8W",
 | 
			
		||||
      "refresh_token": "un7NRYkhCsWCLJhWoTlU0L6mFZV7D1",
 | 
			
		||||
      "scope": "identify guilds.members.read guilds"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2020-03-30T21:34:43.763000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725552968204288"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "362983050054991872",
 | 
			
		||||
      "username": "roman_cinemorphique",
 | 
			
		||||
      "avatar": "d103a76a2f5a3a61e46d9b975ac0d23f",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 0,
 | 
			
		||||
      "flags": 0,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": null,
 | 
			
		||||
      "global_name": "Roman",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
      "banner_color": null
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "7782668f-b8ef-4ebc-8722-70206ceffe47",
 | 
			
		||||
    "admin": false,
 | 
			
		||||
    "picture": "/userspictures/362983050054991872.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "Kr8S9MviRsO68aBii2TBXLPhhRHivK",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "3lmSmZeHDi169D7Vzisvu1qSAbOgZK",
 | 
			
		||||
      "scope": "guilds identify guilds.members.read"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2019-01-13T22:43:08.924000+00:00",
 | 
			
		||||
    "nick": "Néo",
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": "2021-05-09T22:00:03.632000+00:00",
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397726163180716032",
 | 
			
		||||
      "630169940640399370"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "428869747594231808",
 | 
			
		||||
      "username": "neonightfr",
 | 
			
		||||
      "avatar": "6c55374fd43613fe8f4a4d2f4b46750c",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 0,
 | 
			
		||||
      "flags": 0,
 | 
			
		||||
      "banner": "7421deb5e7ff351828e77f79265246aa",
 | 
			
		||||
      "accent_color": null,
 | 
			
		||||
      "global_name": "Néo Night FR",
 | 
			
		||||
      "avatar_decoration_data": {
 | 
			
		||||
        "asset": "a_fed43ab12698df65902ba06727e20c0e",
 | 
			
		||||
        "sku_id": "1144058844004233369"
 | 
			
		||||
      },
 | 
			
		||||
      "banner_color": null
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "f931f59c-ec29-43cc-a5fc-7f05a8d3361e",
 | 
			
		||||
    "picture": "/userspictures/428869747594231808.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "QMEQsujfQeJFRpx2gl61UvrmhK9k4g",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "iDKDGlLsCdCZkNVlMuozhPR00uKA1J",
 | 
			
		||||
      "scope": "guilds identify guilds.members.read"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2020-04-14T08:47:38.484000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
@@ -94,14 +140,16 @@
 | 
			
		||||
      "397725552968204288",
 | 
			
		||||
      "630169940640399370"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "435462012974268426",
 | 
			
		||||
      "username": "gabouille",
 | 
			
		||||
      "avatar": "5424e9938b46c0cd48b4145136dd88dd",
 | 
			
		||||
      "avatar": "78790482ad52bad210a6e979847420d9",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 256,
 | 
			
		||||
      "premium_type": 2,
 | 
			
		||||
      "flags": 256,
 | 
			
		||||
      "banner": "336d92bc07973449e1347736839d06e6",
 | 
			
		||||
      "banner": "7c3d04b3afb1f624a7266b5dc42dbb29",
 | 
			
		||||
      "accent_color": 16775056,
 | 
			
		||||
      "global_name": "Gabouille",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
@@ -111,16 +159,96 @@
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "baedf970-fec2-4d8b-ac06-a1652480a653",
 | 
			
		||||
    "admin": false
 | 
			
		||||
    "token": "4c8833ba-d02c-4661-93e8-94aa87626b36",
 | 
			
		||||
    "picture": "/userspictures/435462012974268426.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "xa9w0vGStc3NMnSM7JadWJXdlE8vjw",
 | 
			
		||||
      "access_token": "sVto3Z4OtZi2d1gufLjdMVSu0AqoVM",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "yIPoVpUVq59oI5Nin2i4YbKI6G2Wxb",
 | 
			
		||||
      "scope": "identify guilds guilds.members.read"
 | 
			
		||||
      "refresh_token": "hlL3RjDyXtcNWUkiBtTzT4caoc0jFY",
 | 
			
		||||
      "scope": "guilds.members.read identify guilds"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2021-10-04T21:39:15.519000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725552968204288"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "454603829556805632",
 | 
			
		||||
      "username": ".mophie",
 | 
			
		||||
      "avatar": "0cfb7c8d85b1b8c245b2545e3e1b75da",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 0,
 | 
			
		||||
      "premium_type": 0,
 | 
			
		||||
      "flags": 0,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": 3553599,
 | 
			
		||||
      "global_name": "Mophie",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
      "banner_color": "#36393f"
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "188204a0-123c-42b5-b92e-8cbbed3c975f",
 | 
			
		||||
    "picture": "/userspictures/454603829556805632.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "aaNl0ZbjqF80r38Uhh6dGj0UStCyF9",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "OBDdGUO1ws4ZtZf4ZOs9xJ6eeu8BoM",
 | 
			
		||||
      "scope": "identify guilds.members.read guilds"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2020-03-06T18:17:58.037000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725552968204288"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "249494159629484033",
 | 
			
		||||
      "username": "immudelki",
 | 
			
		||||
      "avatar": "10376ec122172dd172d70876e3b532aa",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 0,
 | 
			
		||||
      "premium_type": 0,
 | 
			
		||||
      "flags": 0,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": 1123662,
 | 
			
		||||
      "global_name": "Immudelki",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
      "banner_color": "#11254e"
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "e635ee17-ba13-47f7-8330-7679cb724936",
 | 
			
		||||
    "picture": "/userspictures/249494159629484033.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "9oiQMo6zqVFkDnD7iA3theiy5YjMT5",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "F8Cc1cftPfcajzHHthhgVFDYKRTk0p",
 | 
			
		||||
      "scope": "guilds identify guilds.members.read"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
@@ -132,12 +260,14 @@
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725552968204288"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "158369928104116224",
 | 
			
		||||
      "username": "pierreber",
 | 
			
		||||
      "avatar": "8ecb7b32c67be13eadb2f6e3a372c205",
 | 
			
		||||
      "avatar": "b32d53187e2a0c4e419a5c038c6de1a8",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 0,
 | 
			
		||||
      "premium_type": 0,
 | 
			
		||||
      "flags": 0,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": 921132,
 | 
			
		||||
@@ -149,34 +279,201 @@
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "58e43544-b4f7-4f32-bb7d-d00d71577629",
 | 
			
		||||
    "token": "a6dfef7b-0a16-4fff-864e-1b5a165cba97",
 | 
			
		||||
    "picture": "/userspictures/158369928104116224.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "h7RD4cRiX2mo9lHXWjNBCWoLNdXsLU",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "6OhGjmNHMlj2ip4VD7vtmaQiHrzQqc",
 | 
			
		||||
      "scope": "identify guilds.members.read guilds"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2019-11-30T19:59:21.532000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725552968204288"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "442290526545510421",
 | 
			
		||||
      "username": "mido_lol27",
 | 
			
		||||
      "avatar": "097bd2ba3fee996828eef0d0558bb830",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 64,
 | 
			
		||||
      "premium_type": 0,
 | 
			
		||||
      "flags": 64,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": null,
 | 
			
		||||
      "global_name": "Mido",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
      "banner_color": null
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "3d977bde-c5ec-4740-902c-4def1e45fb03",
 | 
			
		||||
    "picture": "/userspictures/442290526545510421.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "gOP2InJLgtHkxDQVXhX81cDnTYa97m",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "3vBdERIVShrs6jZsYZBvQ0PPFUeGiE",
 | 
			
		||||
      "scope": "guilds identify guilds.members.read"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2019-06-28T21:40:53.652000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725956598530050",
 | 
			
		||||
      "840278326210985994"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "172437570905571328",
 | 
			
		||||
      "username": "iceplayer",
 | 
			
		||||
      "avatar": "255f537528548d5def12fcf93d5ca439",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 0,
 | 
			
		||||
      "premium_type": 1,
 | 
			
		||||
      "flags": 0,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": null,
 | 
			
		||||
      "global_name": "IcePlayer",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
      "banner_color": null
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "0adeb1bf-c4a9-4d39-b40c-bc844cd50f2d",
 | 
			
		||||
    "picture": "/userspictures/172437570905571328.png"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "zR2x55rWjbMeKXNlGWnUXBmaATBZRO",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "gFu5XPe3yD5zUkSw69rOGlehRwD8B4",
 | 
			
		||||
      "scope": "guilds guilds.members.read identify"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2018-05-17T09:35:10.139000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397726163180716032",
 | 
			
		||||
      "840278326210985994"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "168086507486314496",
 | 
			
		||||
      "username": "entreenatcho",
 | 
			
		||||
      "avatar": "27b13203cd91c88ff80ab350a21cd49c",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 0,
 | 
			
		||||
      "premium_type": 0,
 | 
			
		||||
      "flags": 0,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": null,
 | 
			
		||||
      "global_name": "EntreeNATCHO",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
      "banner_color": null
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "2dbb9339-d54d-4a22-85c3-c24dc22c2251",
 | 
			
		||||
    "picture": "/userspictures/168086507486314496.png",
 | 
			
		||||
    "admin": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "jY17lCWaOpTdPQCnz50kfNm7ABpsGz",
 | 
			
		||||
      "access_token": "4kUniqI5SwtuZXFowjasl5WA9Qe6Xa",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "3TronknZ7j5kVSDBjI3OechmCYF8ck",
 | 
			
		||||
      "scope": "guilds identify guilds.members.read"
 | 
			
		||||
      "refresh_token": "9fm6lraCAXgHbEBesgRSQGEdunj4QT",
 | 
			
		||||
      "scope": "guilds.members.read identify guilds"
 | 
			
		||||
    },
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2017-08-28T19:23:58.611000+00:00",
 | 
			
		||||
    "nick": null,
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725552968204288",
 | 
			
		||||
      "840278326210985994"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "253494094179991552",
 | 
			
		||||
      "username": "darkguillaume",
 | 
			
		||||
      "avatar": "a_395293ae3b4fc6c67f9ef1af5a17196f",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 128,
 | 
			
		||||
      "premium_type": 2,
 | 
			
		||||
      "flags": 128,
 | 
			
		||||
      "banner": "a_256ce480b73b88f5c80d2e096ae4e9e8",
 | 
			
		||||
      "accent_color": null,
 | 
			
		||||
      "global_name": "DarkGuillaume",
 | 
			
		||||
      "avatar_decoration_data": null,
 | 
			
		||||
      "banner_color": null
 | 
			
		||||
    },
 | 
			
		||||
    "mute": false,
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "de730e3b-a000-4376-8f95-e1052c441636",
 | 
			
		||||
    "picture": "/userspictures/253494094179991552.png",
 | 
			
		||||
    "admin": false
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "auth": {
 | 
			
		||||
      "token_type": "Bearer",
 | 
			
		||||
      "access_token": "fATWAIB6UrA8FnN9xKofUyLdGXXoKk",
 | 
			
		||||
      "expires_in": 604800,
 | 
			
		||||
      "refresh_token": "pWF4LL5uFbbQmwwNmGWftiBMi2Rrip",
 | 
			
		||||
      "scope": "guilds.members.read identify guilds"
 | 
			
		||||
    },
 | 
			
		||||
    "admin": true,
 | 
			
		||||
    "avatar": null,
 | 
			
		||||
    "communication_disabled_until": null,
 | 
			
		||||
    "flags": 0,
 | 
			
		||||
    "joined_at": "2023-03-06T18:20:23.413000+00:00",
 | 
			
		||||
    "joined_at": "2023-09-24T18:54:49.914000+00:00",
 | 
			
		||||
    "nick": "Raphix",
 | 
			
		||||
    "pending": false,
 | 
			
		||||
    "premium_since": null,
 | 
			
		||||
    "roles": [
 | 
			
		||||
      "397725552968204288"
 | 
			
		||||
    ],
 | 
			
		||||
    "unusual_dm_activity_until": null,
 | 
			
		||||
    "user": {
 | 
			
		||||
      "id": "486943594893017119",
 | 
			
		||||
      "username": "raphixscrap",
 | 
			
		||||
      "avatar": "7129e80c23aa3ba3d2d45814dd352a29",
 | 
			
		||||
      "avatar": "f3fa652cc177da053b27985a56d61f80",
 | 
			
		||||
      "discriminator": "0",
 | 
			
		||||
      "public_flags": 4194368,
 | 
			
		||||
      "premium_type": 0,
 | 
			
		||||
      "flags": 4194368,
 | 
			
		||||
      "banner": null,
 | 
			
		||||
      "accent_color": 10712214,
 | 
			
		||||
@@ -188,6 +485,12 @@
 | 
			
		||||
    "deaf": false,
 | 
			
		||||
    "bio": "",
 | 
			
		||||
    "banner": null,
 | 
			
		||||
    "token": "adf077e6-1fac-4c0c-9468-6ebe698c550a"
 | 
			
		||||
    "token": [
 | 
			
		||||
      "2cb1bbb1-08de-4d42-b62a-346113dfe06c",
 | 
			
		||||
      "4a271f57-8433-4761-961f-da584651fd8c",
 | 
			
		||||
      "c1d699c8-615d-42bc-a1e1-8967475d816a",
 | 
			
		||||
      "e04a58b9-76fa-4bee-836c-6ec4f83b92c3"
 | 
			
		||||
    ],
 | 
			
		||||
    "picture": "/userspictures/486943594893017119.png"
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										710
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						@@ -1,7 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "subsonics-web",
 | 
			
		||||
  "author": "Raphix",
 | 
			
		||||
  "version": "1.0.3",
 | 
			
		||||
  "version": "1.1.0",
 | 
			
		||||
  "nodemonConfig": {
 | 
			
		||||
    "ext": "js, html",
 | 
			
		||||
    "ignore": [
 | 
			
		||||
@@ -19,9 +19,11 @@
 | 
			
		||||
    "erela.js": "^2.4.0",
 | 
			
		||||
    "express": "^4.18.2",
 | 
			
		||||
    "express-favicon": "^2.0.4",
 | 
			
		||||
    "loguix": "^1.4.2",
 | 
			
		||||
    "markdown-it": "^13.0.1",
 | 
			
		||||
    "nodemon": "^2.0.22",
 | 
			
		||||
    "pm2": "^5.3.0",
 | 
			
		||||
    "request": "^2.88.2",
 | 
			
		||||
    "socket.io": "^4.6.1",
 | 
			
		||||
    "uuid": "^9.0.0",
 | 
			
		||||
    "webmetrik": "^0.1.4",
 | 
			
		||||
@@ -30,8 +32,8 @@
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "start": "nodemon src/main.js",
 | 
			
		||||
    "dev": "set DEV=true& nodemon src/main.js",
 | 
			
		||||
    "stop": "ssh raphix@raphix.fr sudo -S -u gitlab-ci pm2 stop 'SubSonics - Bot Discord'",
 | 
			
		||||
    "restart": "ssh raphix@raphix.fr sudo -S -u gitlab-ci pm2 start 'SubSonics - Bot Discord'"
 | 
			
		||||
    "stop": "ssh raphix@raphix.fr sudo -S -u gitlab-ci pm2 stop 'Subsonics'",
 | 
			
		||||
    "restart": "ssh raphix@raphix.fr sudo -S -u gitlab-ci pm2 start 'Subsonics'"
 | 
			
		||||
  },
 | 
			
		||||
  "beta_on": false
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require("../modules/sub-log");
 | 
			
		||||
const { LogType } = require("loguix");
 | 
			
		||||
const { List } = require("../modules/sub-list");
 | 
			
		||||
const subplayer = require(__glob.SUBPLAYER);
 | 
			
		||||
const packageJson = require(__glob.PACKAGE);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require("../modules/sub-log");
 | 
			
		||||
const { List } = require("../modules/sub-list");
 | 
			
		||||
const subplayer = require(__glob.SUBPLAYER);
 | 
			
		||||
const packageJson = require(__glob.PACKAGE);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require("../modules/sub-log");
 | 
			
		||||
const { List } = require("../modules/sub-list");
 | 
			
		||||
const subplayer = require(__glob.SUBPLAYER);
 | 
			
		||||
const packageJson = require(__glob.PACKAGE);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
const { SlashCommandBuilder, EmbedBuilder, Client } = require("discord.js");
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require("../modules/sub-log");
 | 
			
		||||
const { List } = require("../modules/sub-list");
 | 
			
		||||
const subplayer = require(__glob.SUBPLAYER);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require("../modules/sub-log");
 | 
			
		||||
const { List } = require("../modules/sub-list");
 | 
			
		||||
const subplayer = require(__glob.SUBPLAYER);
 | 
			
		||||
const packageJson = require(__glob.PACKAGE);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require("../modules/sub-log");
 | 
			
		||||
const { List } = require("../modules/sub-list");
 | 
			
		||||
const subplayer = require(__glob.SUBPLAYER);
 | 
			
		||||
const packageJson = require(__glob.PACKAGE);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,15 @@
 | 
			
		||||
const fs = require("node:fs")
 | 
			
		||||
const path = require("path")
 | 
			
		||||
const { LogType } = require("./modules/sub-log")
 | 
			
		||||
const { LogType } = require("loguix")
 | 
			
		||||
const log = require("loguix")
 | 
			
		||||
const { __glob } = require("./modules/global-variables")
 | 
			
		||||
log.setup(__glob.LOGS, __glob.PACKAGE)
 | 
			
		||||
const { DiscordBot } = require("./modules/discord-bot")
 | 
			
		||||
const { WebServer } = require("./modules/sub-web")
 | 
			
		||||
const metric = require("webmetrik")
 | 
			
		||||
metric.setMetricFile(__glob.METRIC_FILE)
 | 
			
		||||
metric.publishMetrics("8001", "raphraph")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
setup()
 | 
			
		||||
@@ -14,6 +20,7 @@ function setup() {
 | 
			
		||||
 | 
			
		||||
    const dlog = new LogType("Discord")
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
    // Discord Bot - INIT PHASE
 | 
			
		||||
        
 | 
			
		||||
    const bot = new DiscordBot(getConfig(dlog), dlog)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,12 @@ const fs = require("node:fs")
 | 
			
		||||
const path = require("path")
 | 
			
		||||
const { Manager } = require("erela.js")
 | 
			
		||||
const { __glob } = require("./global-variables")
 | 
			
		||||
const { LogType } = require("../modules/sub-log")
 | 
			
		||||
const { LogType } = require("loguix")
 | 
			
		||||
const { List } = require("./sub-list")
 | 
			
		||||
const nodeFinder = require("./nodes-finder")
 | 
			
		||||
const subplayer = require("./sub-player")
 | 
			
		||||
const nodemon = require("nodemon")
 | 
			
		||||
const metric = require("webmetrik") 
 | 
			
		||||
 | 
			
		||||
const client = new Client({
 | 
			
		||||
    intents:[GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMembers],
 | 
			
		||||
@@ -121,10 +123,16 @@ function init(dlog, config) {
 | 
			
		||||
        
 | 
			
		||||
        if(!interaction.isCommand()) return;
 | 
			
		||||
 | 
			
		||||
        var numberOfCommands = new metric.Metric("numberOfCommands", "Nombre de commandes éxécutées")
 | 
			
		||||
        numberOfCommands.setValue(numberOfCommands.getValue() + 1)
 | 
			
		||||
 | 
			
		||||
        const command = client.commands.get(interaction.commandName)
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            
 | 
			
		||||
            // Create a metric to count the number of commands executed by each user
 | 
			
		||||
            const userCommand = new metric.Metric("userCommand_" + interaction.member.user.username, "Nombre de commandes éxécutées par l'utilisateur : " + interaction.member.user.username)
 | 
			
		||||
            userCommand.setValue(userCommand.getValue() + 1)
 | 
			
		||||
            dlog.log(interaction.member.user.username + "-> /" + interaction.commandName)
 | 
			
		||||
            command.execute(client, interaction)
 | 
			
		||||
        } catch(error) {
 | 
			
		||||
@@ -224,8 +232,19 @@ function startErelaManager(dlog, config) {
 | 
			
		||||
 | 
			
		||||
    client.manager.on("trackStart", async (player) => {
 | 
			
		||||
 | 
			
		||||
        // Create a metric to count the number of songs played
 | 
			
		||||
        const songPlayed = new metric.Metric("songPlayed", "Nombre de musiques jouées")
 | 
			
		||||
        songPlayed.setValue(songPlayed.getValue() + 1)
 | 
			
		||||
 | 
			
		||||
        if(player) {
 | 
			
		||||
            plog.log("Lecture de '" + player.queue.current.title + "' de '" + player.queue.current.author + "'")
 | 
			
		||||
            // Create a metric to count the number of minutes played by the bot using player.queue.current.duration which is in ms (milliseconds) and verify if it's not a livestream
 | 
			
		||||
 | 
			
		||||
            if(player.queue.current.duration && player.queue.current.duration != 9223372036854776000) {
 | 
			
		||||
                const songDuration = new metric.Metric("songDuration", "Durée totale des musiques jouées en secondes")
 | 
			
		||||
                songDuration.setValue(songDuration.getValue() + (player.queue.current.duration / 1000))
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await list.setCurrent(player)
 | 
			
		||||
            await player.seek(0)
 | 
			
		||||
            process.emit("MUSIC_UPDATE_STATE")
 | 
			
		||||
@@ -240,6 +259,7 @@ function startErelaManager(dlog, config) {
 | 
			
		||||
 | 
			
		||||
            await list.addCurrentToPrevious()
 | 
			
		||||
            if(await list.haveSongs()) {
 | 
			
		||||
                
 | 
			
		||||
                await player.play(list.next())
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
@@ -275,3 +295,17 @@ function startErelaManager(dlog, config) {
 | 
			
		||||
    client.on("raw", d => client.manager.updateVoiceState(d));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function closeClient()  {
 | 
			
		||||
    console.log("Fermeture du client Discord")
 | 
			
		||||
    if(client) {
 | 
			
		||||
        let player = await client.manager.players.get("137291455336022018")
 | 
			
		||||
        if(player) {
 | 
			
		||||
            await player.destroy()
 | 
			
		||||
        }
 | 
			
		||||
        client.destroy()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ const root = path.resolve(__dirname, '../../')
 | 
			
		||||
const __glob = {
 | 
			
		||||
    CONFIG:  root + path.sep + "data" + path.sep + "config.json",
 | 
			
		||||
    USERS:  root + path.sep + "data" + path.sep + "users.json",
 | 
			
		||||
    BETA_USERS:  root + path.sep + "data" + path.sep + "betas.json",
 | 
			
		||||
    ROOT: root,
 | 
			
		||||
    WEB_DIR: root + path.sep + "src" + path.sep + "web",
 | 
			
		||||
    COMMANDS: root + path.sep + "src" + path.sep + "commands",
 | 
			
		||||
@@ -21,6 +20,7 @@ const __glob = {
 | 
			
		||||
    RADIO:  root + path.sep + "data" + path.sep + "radios.json",
 | 
			
		||||
    LOGS: root + path.sep + "src" + path.sep + "modules" + path.sep + "logs",
 | 
			
		||||
    METRIC_FILE: root + path.sep + "data" + path.sep + "metrics.json",
 | 
			
		||||
    PICTURE_DIR: root + path.sep + "data" + path.sep + "pictures",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const webroot = __glob.WEB_DIR + path.sep 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
const { __glob } = require("./global-variables")
 | 
			
		||||
const { LogType } = require("../modules/sub-log")
 | 
			
		||||
const { LogType } = require("loguix")
 | 
			
		||||
const fs = require("fs")
 | 
			
		||||
const discord = require("./discord-bot")
 | 
			
		||||
 | 
			
		||||
@@ -7,242 +7,127 @@ const nlog = new LogType("Node-Finder")
 | 
			
		||||
 | 
			
		||||
const nodesState = new Map()
 | 
			
		||||
 | 
			
		||||
module.exports.getNodes = function () {
 | 
			
		||||
        nlog.step.init("find_nodes", "Récupération des nodes de la base de donnée")
 | 
			
		||||
        
 | 
			
		||||
        if(fs.existsSync(__glob.NODES)) {
 | 
			
		||||
            try {  
 | 
			
		||||
 | 
			
		||||
                var nodes_data = JSON.parse(fs.readFileSync(__glob.NODES))
 | 
			
		||||
                const nodes_array = new Array()
 | 
			
		||||
 | 
			
		||||
                for(var node of nodes_data) {
 | 
			
		||||
                    nodes_array.push(node)
 | 
			
		||||
                    nodesState.set(node.host, false)
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                nlog.log("Récupération de " + nodes_array.length + " nodes dans la base de donnée !")
 | 
			
		||||
                nlog.step.end("find_nodes")
 | 
			
		||||
                return nodes_array
 | 
			
		||||
            } catch(error) {
 | 
			
		||||
                nlog.step.error("find_nodes", error)
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            nlog.warn("Fichier de configuration introuvable !")
 | 
			
		||||
            
 | 
			
		||||
            try {
 | 
			
		||||
                var nodes = {}
 | 
			
		||||
 | 
			
		||||
               
 | 
			
		||||
                fs.writeFileSync(__glob.NODES, JSON.stringify(nodes, null, 2))
 | 
			
		||||
                nlog.log("Création d'un fichier de base de donnée de nodes ! Redémarrage de l'application nécéssaire !")
 | 
			
		||||
                nlog.step.error("find_nodes", "Redémarrage requis pour lire la nouvelle base de donnée des nodes !")
 | 
			
		||||
                process.exit(0)
 | 
			
		||||
            } catch(error) {
 | 
			
		||||
                nlog.step.error("find_nodes", "Tentative de création du fichier de base de donnée nodes échoué !"  + error)
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.getNodesData = function () {
 | 
			
		||||
    nlog.step.init("findu_nodes", "Récupération des nodes pour envoi d'informations!")
 | 
			
		||||
    
 | 
			
		||||
    if(fs.existsSync(__glob.NODES)) {
 | 
			
		||||
        try {  
 | 
			
		||||
 | 
			
		||||
            var nodes_data = JSON.parse(fs.readFileSync(__glob.NODES))
 | 
			
		||||
            const nodes_array = new Array()
 | 
			
		||||
 | 
			
		||||
            for(var node of nodes_data) {
 | 
			
		||||
                node.state = nodesState.get(node.host)
 | 
			
		||||
                nodes_array.push(node)
 | 
			
		||||
                
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            nlog.log("Récupération de " + nodes_array.length + " nodes pour envoi d'informations!")
 | 
			
		||||
            nlog.step.end("findu_nodes")
 | 
			
		||||
            return nodes_array
 | 
			
		||||
        } catch(error) {
 | 
			
		||||
            nlog.step.error("findu_nodes", error)
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        nlog.warn("Fichier de configuration introuvable !")
 | 
			
		||||
        
 | 
			
		||||
function checkAndCreate() {
 | 
			
		||||
    if (!fs.existsSync(__glob.NODES)) {
 | 
			
		||||
        try {
 | 
			
		||||
            var nodes = {}
 | 
			
		||||
 | 
			
		||||
           
 | 
			
		||||
            fs.writeFileSync(__glob.NODES, JSON.stringify(nodes, null, 2))
 | 
			
		||||
            saveNodesFile(nodes) 
 | 
			
		||||
            nlog.log("Création d'un fichier de base de donnée de nodes ! Redémarrage de l'application nécéssaire !")
 | 
			
		||||
            nlog.step.error("find_nodes", "Redémarrage requis pour lire la nouvelle base de donnée des nodes !")
 | 
			
		||||
            process.exit(0)
 | 
			
		||||
        } catch(error) {
 | 
			
		||||
            nlog.step.error("find_nodes", "Tentative de création du fichier de base de donnée nodes échoué !"  + error)
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.addNodes = function (data) {
 | 
			
		||||
 | 
			
		||||
    nlog.step.init("add_nodes", "Ajout d'un nouveau noeud dans la base de donnée de nodes : " + data.host)
 | 
			
		||||
        
 | 
			
		||||
    if(fs.existsSync(__glob.NODES)) {
 | 
			
		||||
        try {  
 | 
			
		||||
 | 
			
		||||
            var nodes_data = JSON.parse(fs.readFileSync(__glob.NODES))
 | 
			
		||||
            
 | 
			
		||||
            nodes_data.push(data)
 | 
			
		||||
            fs.writeFileSync(__glob.NODES, JSON.stringify(nodes_data, null, 2))
 | 
			
		||||
           
 | 
			
		||||
            nlog.step.end("add_nodes")
 | 
			
		||||
 | 
			
		||||
            const client = discord.getClient()
 | 
			
		||||
 | 
			
		||||
            if(client.manager) {
 | 
			
		||||
                const nodesPresent = client.manager.nodes
 | 
			
		||||
 | 
			
		||||
                if(!nodesPresent.get(data.host)) {
 | 
			
		||||
                    
 | 
			
		||||
                    client.manager.createNode(data)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                client.manager.nodes.get(data.host).connect()
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          
 | 
			
		||||
        } catch(error) {
 | 
			
		||||
            nlog.step.error("add_nodes", error)
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        nlog.warn("Fichier de configuration introuvable !")
 | 
			
		||||
        
 | 
			
		||||
        try {
 | 
			
		||||
            var nodes = []
 | 
			
		||||
 | 
			
		||||
           
 | 
			
		||||
            fs.writeFileSync(__glob.NODES, JSON.stringify(nodes, null, 2))
 | 
			
		||||
            nlog.log("Création d'un fichier de base de donnée de nodes ! Redémarrage de l'application nécéssaire !")
 | 
			
		||||
            nlog.step.error("add_nodes", "Redémarrage requis pour lire la nouvelle base de donnée des nodes !")
 | 
			
		||||
            process.exit(0)
 | 
			
		||||
        } catch(error) {
 | 
			
		||||
            nlog.step.error("add_nodes", "Tentative de création du fichier de nodes échoué !"  + error)
 | 
			
		||||
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            nlog.step.error("find_nodes", "Tentative de création du fichier de base de donnée nodes échoué !" + error)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.deleteNode = function (data) {
 | 
			
		||||
function readNodesFile() {
 | 
			
		||||
    checkAndCreate()
 | 
			
		||||
    return JSON.parse(fs.readFileSync(__glob.NODES))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    nlog.step.init("deleteNodes", "Supression d'un noeud dans la base de donnée de nodes : " + data.host)
 | 
			
		||||
        
 | 
			
		||||
    if(fs.existsSync(__glob.NODES)) {
 | 
			
		||||
        try {  
 | 
			
		||||
 | 
			
		||||
            var nodes_data = JSON.parse(fs.readFileSync(__glob.NODES))
 | 
			
		||||
 | 
			
		||||
            var nodeIndex = -1
 | 
			
		||||
 | 
			
		||||
            for(var node of nodes_data) {
 | 
			
		||||
 | 
			
		||||
                if(node.host == data.host) {
 | 
			
		||||
 | 
			
		||||
                    nodeIndex = nodes_data.indexOf(node)
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            nodes_data.splice(nodeIndex, 1)
 | 
			
		||||
 | 
			
		||||
            const client = discord.getClient()
 | 
			
		||||
 | 
			
		||||
            if(client.manager) {
 | 
			
		||||
                const nodesPresent = client.manager.nodes
 | 
			
		||||
 | 
			
		||||
                if(nodesPresent.get(data.host)) {
 | 
			
		||||
                    
 | 
			
		||||
                    client.manager.destroyNode(data.host)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            fs.writeFileSync(__glob.NODES, JSON.stringify(nodes_data, null, 2))
 | 
			
		||||
           
 | 
			
		||||
            nlog.step.end("deleteNodes")
 | 
			
		||||
 | 
			
		||||
          
 | 
			
		||||
        } catch(error) {
 | 
			
		||||
            nlog.step.error("deleteNodes", error)
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        nlog.warn("Fichier de configuration introuvable !")
 | 
			
		||||
        
 | 
			
		||||
        try {
 | 
			
		||||
            var nodes = []
 | 
			
		||||
 | 
			
		||||
           
 | 
			
		||||
            fs.writeFileSync(__glob.NODES, JSON.stringify(nodes, null, 2))
 | 
			
		||||
            nlog.log("Création d'un fichier de base de donnée de nodes ! Redémarrage de l'application nécéssaire !")
 | 
			
		||||
            nlog.step.error("deleteNodes", "Redémarrage requis pour lire la nouvelle base de donnée des nodes !")
 | 
			
		||||
            process.exit(0)
 | 
			
		||||
        } catch(error) {
 | 
			
		||||
            nlog.step.error("deleteNodes", "Tentative de création du fichier de nodes échoué !"  + error)
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
function saveNodesFile(data) { 
 | 
			
		||||
    fs.writeFileSync(__glob.NODES, JSON.stringify(data, null, 2))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.reloadNode = function (data) {
 | 
			
		||||
 | 
			
		||||
    const client = discord.getClient()
 | 
			
		||||
 | 
			
		||||
    if(client.manager) {
 | 
			
		||||
    if (client.manager) {
 | 
			
		||||
        const nodesPresent = client.manager.nodes
 | 
			
		||||
 | 
			
		||||
        if(nodesPresent.get(data.host)) {
 | 
			
		||||
            
 | 
			
		||||
        if (nodesPresent.get(data.host)) {
 | 
			
		||||
            client.manager.destroyNode(data.host)
 | 
			
		||||
        }
 | 
			
		||||
        nlog.log("Redémarrage de la node : " + data.host)
 | 
			
		||||
 | 
			
		||||
        client.manager.createNode(data)
 | 
			
		||||
        client.manager.nodes.get(data.host).connect()
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Ajout de l'état des nodes
 | 
			
		||||
 * @param {string} node
 | 
			
		||||
 * @param {boolean} state 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module.exports.setNodeState = function(node, state) {
 | 
			
		||||
 | 
			
		||||
module.exports.setNodeState = function (node, state) {
 | 
			
		||||
    nodesState.set(node, state)
 | 
			
		||||
    process.emit("UPDATE_NODES")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.getNodesStates = function() {
 | 
			
		||||
 | 
			
		||||
module.exports.getNodesStates = function () {
 | 
			
		||||
    return nodesState
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.getNodes = function () {
 | 
			
		||||
 | 
			
		||||
    nlog.step.init("find_nodes", "Récupération des nodes de la base de donnée")
 | 
			
		||||
    try {
 | 
			
		||||
        var nodes_data = readNodesFile()
 | 
			
		||||
        const nodes_array = new Array()
 | 
			
		||||
        for (var node of nodes_data) {
 | 
			
		||||
            nodes_array.push(node)
 | 
			
		||||
            nodesState.set(node.host, false)
 | 
			
		||||
        }
 | 
			
		||||
        nlog.log("Récupération de " + nodes_array.length + " nodes dans la base de donnée !")
 | 
			
		||||
        nlog.step.end("find_nodes")
 | 
			
		||||
        return nodes_array
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        nlog.step.error("find_nodes", error)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.getNodesData = function () {
 | 
			
		||||
    nlog.step.init("findu_nodes", "Récupération des nodes pour envoi d'informations!")
 | 
			
		||||
    try {
 | 
			
		||||
        var nodes_data = readNodesFile()
 | 
			
		||||
        const nodes_array = new Array()
 | 
			
		||||
        for (var node of nodes_data) {
 | 
			
		||||
            node.state = nodesState.get(node.host)
 | 
			
		||||
            nodes_array.push(node)
 | 
			
		||||
        }
 | 
			
		||||
        nlog.log("Récupération de " + nodes_array.length + " nodes pour envoi d'informations!")
 | 
			
		||||
        nlog.step.end("findu_nodes")
 | 
			
		||||
        return nodes_array
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        nlog.step.error("findu_nodes", error)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.addNodes = function (data) {
 | 
			
		||||
    nlog.step.init("add_nodes", "Ajout d'un nouveau noeud dans la base de donnée de nodes : " + data.host)
 | 
			
		||||
    try {
 | 
			
		||||
        var nodes_data = readNodesFile()
 | 
			
		||||
        nodes_data.push(data)
 | 
			
		||||
        saveNodesFile(nodes_data) 
 | 
			
		||||
        nlog.step.end("add_nodes")
 | 
			
		||||
        const client = discord.getClient()
 | 
			
		||||
        if (client.manager) {
 | 
			
		||||
            const nodesPresent = client.manager.nodes
 | 
			
		||||
            if (!nodesPresent.get(data.host)) {
 | 
			
		||||
                client.manager.createNode(data)
 | 
			
		||||
            }
 | 
			
		||||
            client.manager.nodes.get(data.host).connect()
 | 
			
		||||
        }
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        nlog.step.error("add_nodes", error)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.deleteNode = function (data) {
 | 
			
		||||
    nlog.step.init("deleteNodes", "Supression d'un noeud dans la base de donnée de nodes : " + data.host)
 | 
			
		||||
    try {
 | 
			
		||||
        var nodes_data = readNodesFile()
 | 
			
		||||
        var nodeIndex = -1
 | 
			
		||||
        for (var node of nodes_data) {
 | 
			
		||||
            if (node.host == data.host) {
 | 
			
		||||
                nodeIndex = nodes_data.indexOf(node)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        nodes_data.splice(nodeIndex, 1)
 | 
			
		||||
        const client = discord.getClient()
 | 
			
		||||
        if (client.manager) {
 | 
			
		||||
            const nodesPresent = client.manager.nodes
 | 
			
		||||
            if (nodesPresent.get(data.host)) {
 | 
			
		||||
                client.manager.destroyNode(data.host)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        saveNodesFile(nodes_data) 
 | 
			
		||||
        nlog.step.end("deleteNodes")
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        nlog.step.error("deleteNodes", error)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,94 @@
 | 
			
		||||
const { resolve } = require("path");
 | 
			
		||||
const { __glob, __web } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require('./sub-log');
 | 
			
		||||
const fs = require("fs")
 | 
			
		||||
const { __glob, __web } = require("./global-variables");
 | 
			
		||||
const { LogType } = require('loguix');
 | 
			
		||||
const fs = require("fs");
 | 
			
		||||
 | 
			
		||||
const alog = new LogType("Authentification")
 | 
			
		||||
 | 
			
		||||
var users = new Map()
 | 
			
		||||
var sessions = new Array()
 | 
			
		||||
var betausers = new Array()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var packageJson = JSON.parse(fs.readFileSync(__glob.PACKAGE))
 | 
			
		||||
 | 
			
		||||
updateUsers()
 | 
			
		||||
 | 
			
		||||
module.exports.checkUser = function (token) {
 | 
			
		||||
    
 | 
			
		||||
    if(users.has(token)) {
 | 
			
		||||
 | 
			
		||||
        return true
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        return false
 | 
			
		||||
    }
 | 
			
		||||
if(!fs.existsSync(__glob.PICTURE_DIR)){
 | 
			
		||||
    
 | 
			
		||||
    fs.mkdirSync(__glob.PICTURE_DIR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
updateUsers()
 | 
			
		||||
checkAllPictures()
 | 
			
		||||
 | 
			
		||||
module.exports.getDiscordUser = function (code, session) {
 | 
			
		||||
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
        alog.log("Récupération de l'autorisation de récupération des informations de l'utilisateur associé à la session : " + session + " [ETAPE 2]")
 | 
			
		||||
 | 
			
		||||
        var link = "https://subsonics.raphix.fr" 
 | 
			
		||||
 | 
			
		||||
        if(process.env.DEV == "true") {
 | 
			
		||||
            link = "http://localhost:4000"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const params = new URLSearchParams();
 | 
			
		||||
        params.append('client_id', "1094727789682380922");
 | 
			
		||||
        params.append('client_secret', "uwtyPOPKCgw6ciBs20qiJ7LJrW9Ziclo");
 | 
			
		||||
        params.append('grant_type', 'authorization_code');
 | 
			
		||||
        params.append('code', code);
 | 
			
		||||
        params.append('redirect_uri',  link + "/internal/redirect");
 | 
			
		||||
        params.append('scope', 'identify guilds');
 | 
			
		||||
 | 
			
		||||
        fetch('https://discord.com/api/oauth2/token', {
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            headers: {
 | 
			
		||||
                'Content-Type': 'application/x-www-form-urlencoded'
 | 
			
		||||
            }, body : params
 | 
			
		||||
        }).then(resp1 => resp1.json()).then(authorizationKey => {
 | 
			
		||||
 | 
			
		||||
            alog.log("Récupération des informations de l'utilisateur associé à l'autorisation : '" + authorizationKey.access_token + "' et associé à la session : " + session + " [ETAPE 3]")
 | 
			
		||||
 | 
			
		||||
            fetch('https://discord.com/api/users/@me/guilds/137291455336022018/member', {
 | 
			
		||||
                headers: {
 | 
			
		||||
                    authorization: `${authorizationKey.token_type} ${authorizationKey.access_token}`,
 | 
			
		||||
                },
 | 
			
		||||
            }).then(resp2 => resp2.json()).then(userInfo => {
 | 
			
		||||
 | 
			
		||||
                var user = {}
 | 
			
		||||
                
 | 
			
		||||
                if(typeof userInfo.joined_at == "undefined") {
 | 
			
		||||
                    reject("NOT_IN_CLP")
 | 
			
		||||
                } else if(typeof userInfo.user == "undefined") {
 | 
			
		||||
                    reject("MIGRATE_ACCOUNT_ONLY")
 | 
			
		||||
                } else {
 | 
			
		||||
 | 
			
		||||
                    // Replace existing user from the DB file if exist
 | 
			
		||||
                    const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
                    for (const user of userDB) {
 | 
			
		||||
                        if(user.user.id == userInfo.user.id) {	
 | 
			
		||||
                            userInfo.token = user.token
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                                               
 | 
			
		||||
                    user.auth = authorizationKey;
 | 
			
		||||
 | 
			
		||||
                    if(userInfo.user.id == "486943594893017119") {
 | 
			
		||||
                        user.admin = true;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Object.assign(user, userInfo);
 | 
			
		||||
                    resolve(user);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }).catch(error => reject(error)) 
 | 
			
		||||
 | 
			
		||||
        }).catch(error => reject(error))
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
/*Session*/
 | 
			
		||||
 | 
			
		||||
module.exports.getSession = function (session) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -39,105 +103,6 @@ module.exports.getSession = function (session) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.getDiscordUser = function (code, session) {
 | 
			
		||||
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
        alog.log("Récupération de l'autorisation de récupération des informations de l'utilisateur associé à la session : " + session + " [ETAPE 2]")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            var link = "https://subsonics.raphix.fr" 
 | 
			
		||||
 | 
			
		||||
            if(process.env.DEV == "true") {
 | 
			
		||||
                link = "http://localhost:4000"
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const params = new URLSearchParams();
 | 
			
		||||
            params.append('client_id', "1094727789682380922");
 | 
			
		||||
            params.append('client_secret', "uwtyPOPKCgw6ciBs20qiJ7LJrW9Ziclo");
 | 
			
		||||
            params.append('grant_type', 'authorization_code');
 | 
			
		||||
            params.append('code', code);
 | 
			
		||||
            params.append('redirect_uri',  link + "/internal/redirect");
 | 
			
		||||
            params.append('scope', 'identify guilds');
 | 
			
		||||
 | 
			
		||||
            fetch('https://discord.com/api/oauth2/token', {
 | 
			
		||||
                method: "POST",
 | 
			
		||||
                headers: {
 | 
			
		||||
                    'Content-Type': 'application/x-www-form-urlencoded'
 | 
			
		||||
                }, body : params
 | 
			
		||||
            }).then(resp1 => resp1.json()).then(authorizationKey => {
 | 
			
		||||
 | 
			
		||||
                alog.log("Récupération des informations de l'utilisateur associé à l'autorisation : '" + authorizationKey.access_token + "' et associé à la session : " + session + " [ETAPE 3]")
 | 
			
		||||
 | 
			
		||||
                fetch('https://discord.com/api/users/@me/guilds/137291455336022018/member', {
 | 
			
		||||
                    headers: {
 | 
			
		||||
                        authorization: `${authorizationKey.token_type} ${authorizationKey.access_token}`,
 | 
			
		||||
                    },
 | 
			
		||||
                }).then(resp2 => resp2.json()).then(userInfo => {
 | 
			
		||||
 | 
			
		||||
                    var user = {}
 | 
			
		||||
 | 
			
		||||
                    if(typeof userInfo.joined_at == "undefined") {
 | 
			
		||||
 | 
			
		||||
                        reject("NOT_IN_CLP")
 | 
			
		||||
 | 
			
		||||
                    } else if(typeof userInfo.user == "undefined") {
 | 
			
		||||
                        reject("MIGRATE_ACCOUNT_ONLY")
 | 
			
		||||
 | 
			
		||||
                    } else {
 | 
			
		||||
 | 
			
		||||
                        if(packageJson.beta_on == false) {
 | 
			
		||||
                            user.auth = authorizationKey
 | 
			
		||||
                            if(userInfo.user.id == "486943594893017119") {
 | 
			
		||||
 | 
			
		||||
                                user.admin = true
 | 
			
		||||
                            }
 | 
			
		||||
        
 | 
			
		||||
                            Object.assign(user, userInfo)
 | 
			
		||||
                            
 | 
			
		||||
                           
 | 
			
		||||
                            resolve(user)
 | 
			
		||||
 | 
			
		||||
                        } else {
 | 
			
		||||
 | 
			
		||||
                            if(betausers.includes(userInfo.user.id)) {
 | 
			
		||||
                                user.auth = authorizationKey
 | 
			
		||||
                                if(userInfo.user.id == "486943594893017119") {
 | 
			
		||||
 | 
			
		||||
                                    user.admin = true
 | 
			
		||||
                                }
 | 
			
		||||
                                user.beta = true
 | 
			
		||||
                                Object.assign(user, userInfo)
 | 
			
		||||
                                
 | 
			
		||||
                               
 | 
			
		||||
                                resolve(user)
 | 
			
		||||
    
 | 
			
		||||
                            } else {
 | 
			
		||||
 | 
			
		||||
                                reject("NOT_IN_BETA")
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                  
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                }).catch(error => reject(error)) 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            }).catch(error => reject(error))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.saveSession = function (session) {
 | 
			
		||||
 | 
			
		||||
    sessions.push(session)
 | 
			
		||||
@@ -153,23 +118,52 @@ module.exports.removeSession = function (session) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*Users*/
 | 
			
		||||
 | 
			
		||||
module.exports.checkUser = function (token) {
 | 
			
		||||
    
 | 
			
		||||
    for(var user of users) {
 | 
			
		||||
            
 | 
			
		||||
        if(user[1].token.includes(token)) {
 | 
			
		||||
    
 | 
			
		||||
            return true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports.getUser = function (token) {
 | 
			
		||||
    
 | 
			
		||||
        for(var user of users) {
 | 
			
		||||
                
 | 
			
		||||
            if(user[1].token.includes(token)) {
 | 
			
		||||
        
 | 
			
		||||
                return user[1]
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        return null
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports.getUsers = function () {
 | 
			
		||||
 | 
			
		||||
    const userDB = JSON.parse(fs.readFileSync(__glob.USERS))
 | 
			
		||||
    const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
    return userDB
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports.getUsersList = function () {
 | 
			
		||||
module.exports.getSimpleUsers = function () {
 | 
			
		||||
 | 
			
		||||
    var userList = new Array()
 | 
			
		||||
    const userDB = JSON.parse(fs.readFileSync(__glob.USERS))
 | 
			
		||||
    const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
 | 
			
		||||
    for(var user of userDB) {
 | 
			
		||||
 | 
			
		||||
        userList.push({"username": user.user.username, "global_name":user.user.global_name, "avatar": user.user.avatar, "id": user.user.id, "admin": user.admin})
 | 
			
		||||
        userList.push({"username": user.user.username, "global_name":user.user.global_name, "avatar": user.user.avatar, "id": user.user.id, "admin": user.admin, "picture": user.picture})
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -180,32 +174,20 @@ module.exports.getUsersList = function () {
 | 
			
		||||
 | 
			
		||||
module.exports.getSimpleUser = function (token) {
 | 
			
		||||
 | 
			
		||||
    var user = users.get(token)
 | 
			
		||||
    const user = this.getUser(token)
 | 
			
		||||
 | 
			
		||||
    if(!user) {
 | 
			
		||||
 | 
			
		||||
        return null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ({"username": user.user.username, "global_name":user.user.global_name, "avatar": user.user.avatar, "id": user.user.id, "admin": user.admin})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports.getUser = function (token) {
 | 
			
		||||
    return users.get(token)
 | 
			
		||||
    return ({"username": user.user.username, "global_name":user.user.global_name, "avatar": user.user.avatar, "id": user.user.id, "admin": user.admin, "picture": user.picture})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports.addUser = function (user) {
 | 
			
		||||
    
 | 
			
		||||
    if(!fs.existsSync(__glob.USERS)){
 | 
			
		||||
 | 
			
		||||
        fs.writeFileSync(__glob.USERS, '[]')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    const userDB = JSON.parse(fs.readFileSync(__glob.USERS))
 | 
			
		||||
    const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    var selectedUser = null
 | 
			
		||||
@@ -229,21 +211,63 @@ module.exports.addUser = function (user) {
 | 
			
		||||
 | 
			
		||||
        userDB.push(user)        
 | 
			
		||||
    }
 | 
			
		||||
    fs.writeFileSync(__glob.USERS, JSON.stringify(userDB, null, 2))
 | 
			
		||||
 | 
			
		||||
    saveUsersFile( userDB)
 | 
			
		||||
    var OPdest = __glob.PICTURE_DIR + "/" + user.user.id + ".png"
 | 
			
		||||
    if (fs.existsSync(OPdest)) {
 | 
			
		||||
        fs.rmSync(OPdest);
 | 
			
		||||
    }
 | 
			
		||||
    checkAllPictures()
 | 
			
		||||
    updateUsers()
 | 
			
		||||
    alog.log("Ajout de " + user.user.username + " en tant qu'utilisateur avec le token : " + user.token)
 | 
			
		||||
 | 
			
		||||
}  
 | 
			
		||||
 | 
			
		||||
module.exports.removeUser = function (token) {
 | 
			
		||||
 | 
			
		||||
    const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
    var selectedUser = null
 | 
			
		||||
    for (const user of userDB) {
 | 
			
		||||
        if(user.token == token) {
 | 
			
		||||
 | 
			
		||||
            selectedUser = user
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    const index = userDB.indexOf(selectedUser)
 | 
			
		||||
    alog.log("Supression de " + selectedUser.user.username + " en tant qu'utilisateur avec le token : " + selectedUser.token)
 | 
			
		||||
 | 
			
		||||
    userDB.splice(index, 1)
 | 
			
		||||
    saveUsersFile(userDB)
 | 
			
		||||
 | 
			
		||||
    updateUsers()
 | 
			
		||||
    
 | 
			
		||||
}  
 | 
			
		||||
 | 
			
		||||
module.exports.removeToken = function (token) {
 | 
			
		||||
    
 | 
			
		||||
        const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
        var selectedUser = null
 | 
			
		||||
        for (const user of userDB) {
 | 
			
		||||
            var usersTokens = user.token
 | 
			
		||||
            if(usersTokens.includes(token)) {
 | 
			
		||||
    
 | 
			
		||||
                selectedUser = user
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        const index = userDB.indexOf(selectedUser)
 | 
			
		||||
        alog.log("Supression du token de " + selectedUser.user.username + " en tant qu'utilisateur avec le token : " + selectedUser.token)
 | 
			
		||||
    
 | 
			
		||||
        const tokens = selectedUser.token
 | 
			
		||||
        tokens.splice(tokens.indexOf(token), 1)
 | 
			
		||||
 | 
			
		||||
        saveUsersFile(userDB)
 | 
			
		||||
    
 | 
			
		||||
        updateUsers()
 | 
			
		||||
        
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.setAdmin = function (user) {
 | 
			
		||||
 | 
			
		||||
    if(!fs.existsSync(__glob.USERS)){
 | 
			
		||||
 | 
			
		||||
        fs.writeFileSync(__glob.USERS, '[]')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const userDB = JSON.parse(fs.readFileSync(__glob.USERS))
 | 
			
		||||
    const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
 | 
			
		||||
    var selectedUser = null
 | 
			
		||||
 | 
			
		||||
@@ -268,7 +292,7 @@ module.exports.setAdmin = function (user) {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    fs.writeFileSync(__glob.USERS, JSON.stringify(userDB, null, 2))
 | 
			
		||||
    saveUsersFile(userDB)
 | 
			
		||||
 | 
			
		||||
    updateUsers()
 | 
			
		||||
    alog.log("Ajout de " + user.user.username + " en tant qu'administrateur avec le token : " + user.token)
 | 
			
		||||
@@ -277,60 +301,84 @@ module.exports.setAdmin = function (user) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports.removeUser = function (token) {
 | 
			
		||||
 | 
			
		||||
    if(!fs.existsSync(__glob.USERS)){
 | 
			
		||||
 | 
			
		||||
        fs.writeFileSync(__glob.USERS, '[]')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    const userDB = JSON.parse(fs.readFileSync(__glob.USERS))
 | 
			
		||||
    var selectedUser = null
 | 
			
		||||
    for (const user of userDB) {
 | 
			
		||||
        if(user.token == token) {
 | 
			
		||||
 | 
			
		||||
            selectedUser = user
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    const index = userDB.indexOf(selectedUser)
 | 
			
		||||
    alog.log("Supression de " + selectedUser.user.username + " en tant qu'utilisateur avec le token : " + selectedUser.token)
 | 
			
		||||
 | 
			
		||||
    userDB.splice(index, 1)
 | 
			
		||||
    fs.writeFileSync(__glob.USERS, JSON.stringify(userDB, null, 2))
 | 
			
		||||
 | 
			
		||||
    updateUsers()
 | 
			
		||||
    
 | 
			
		||||
}  
 | 
			
		||||
 | 
			
		||||
function updateUsers() {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(!fs.existsSync(__glob.BETA_USERS)){
 | 
			
		||||
 | 
			
		||||
        fs.writeFileSync(__glob.BETA_USERS, '[]')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(!fs.existsSync(__glob.USERS)){
 | 
			
		||||
 | 
			
		||||
        fs.writeFileSync(__glob.USERS, '[]')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const userDB = JSON.parse(fs.readFileSync(__glob.USERS))
 | 
			
		||||
    const betausersDB = JSON.parse(fs.readFileSync(__glob.BETA_USERS))
 | 
			
		||||
 | 
			
		||||
    const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    for (const user of userDB) {
 | 
			
		||||
        
 | 
			
		||||
        users.set(user.token, user)
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const id of betausersDB) {
 | 
			
		||||
    
 | 
			
		||||
        betausers.push(id)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    alog.log("Actualisation de " + userDB.length + " utilisateurs depuis : " + __glob.USERS)
 | 
			
		||||
    alog.log("Actualisation de " + betausersDB.length + " utilisateurs bêtas depuis : " + __glob.BETA_USERS)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function readUsersFile(file) {
 | 
			
		||||
 | 
			
		||||
    return JSON.parse(fs.readFileSync(file, 'utf8'))
 | 
			
		||||
    
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
function saveUsersFile(data) {    
 | 
			
		||||
 | 
			
		||||
    fs.writeFileSync(__glob.USERS, JSON.stringify(data, null, 2))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkAllPictures() {
 | 
			
		||||
 | 
			
		||||
    const userDB = readUsersFile(__glob.USERS)
 | 
			
		||||
 | 
			
		||||
    for (const user of userDB) {
 | 
			
		||||
 | 
			
		||||
        if(!fs.existsSync(__glob.PICTURE_DIR + "/" + user.user.id + ".png")) {
 | 
			
		||||
 | 
			
		||||
            userDB[userDB.indexOf(user)].picture = "/userspictures/" + user.user.id + ".png"
 | 
			
		||||
 | 
			
		||||
            downloadPicture(`https://cdn.discordapp.com/avatars/${user.user.id}/${user.user.avatar}`, __glob.PICTURE_DIR + "/" + user.user.id + ".png")
 | 
			
		||||
           
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    saveUsersFile(userDB)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ilog = new LogType("ImageDownloader")
 | 
			
		||||
 | 
			
		||||
function downloadPicture(url, dest) {
 | 
			
		||||
    const fs = require('fs');
 | 
			
		||||
    const request = require('request');
 | 
			
		||||
    //Check if path exist and delete it
 | 
			
		||||
    if (fs.existsSync(dest)) {
 | 
			
		||||
        fs.rmSync(dest);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const download = (url, path, callback) => {
 | 
			
		||||
        request.head(url, (err, res, body) => {
 | 
			
		||||
            request(url)
 | 
			
		||||
                .pipe(fs.createWriteStream(path))
 | 
			
		||||
                .on('close', callback)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    download(url, dest, () => {
 | 
			
		||||
        // Say for each user that the picture is downloaded
 | 
			
		||||
        ilog.log("Picture downloaded for " + dest)
 | 
			
		||||
 | 
			
		||||
        process.emit("UPDATE_SELF")
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require('./sub-log');
 | 
			
		||||
const { LogType } = require('loguix');
 | 
			
		||||
const discord = require("./discord-bot")
 | 
			
		||||
 | 
			
		||||
const dlog = new LogType("Queue-List")
 | 
			
		||||
@@ -12,10 +12,6 @@ var shuffle = false
 | 
			
		||||
 | 
			
		||||
module.exports.List = class {
 | 
			
		||||
 | 
			
		||||
    constructor() { 
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getList() {
 | 
			
		||||
 | 
			
		||||
        return next
 | 
			
		||||
@@ -48,8 +44,6 @@ module.exports.List = class {
 | 
			
		||||
            return song
 | 
			
		||||
           
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
           
 | 
			
		||||
            const randomIndex = Math.floor(Math.random() * next.length);
 | 
			
		||||
            const song = next[randomIndex]
 | 
			
		||||
            next.splice(randomIndex, 1)
 | 
			
		||||
@@ -194,32 +188,12 @@ module.exports.List = class {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fpPlaylistAdd(playlist, client) {
 | 
			
		||||
 | 
			
		||||
        let player = client.manager.players.get("137291455336022018")
 | 
			
		||||
 | 
			
		||||
            for(var song of playlist.videos) {
 | 
			
		||||
        
 | 
			
		||||
                const song_finded = await client.manager.search(song.url)
 | 
			
		||||
                next.push(song_finded.tracks[0])
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(!player.playing) {
 | 
			
		||||
 | 
			
		||||
               player.play(next[0])
 | 
			
		||||
               this.remove(next[0])
 | 
			
		||||
            
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            process.emit("MUSIC_UPDATE_STATE")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async playlistAdd(playlist, interaction, userId, ) {
 | 
			
		||||
 | 
			
		||||
        if(interaction) {
 | 
			
		||||
        var client = discord.getClient()
 | 
			
		||||
        let player = client.manager.players.get("137291455336022018")
 | 
			
		||||
 | 
			
		||||
            const client = interaction.client
 | 
			
		||||
        if(interaction) {
 | 
			
		||||
 | 
			
		||||
            var author = "Artiste inconnu !"
 | 
			
		||||
 | 
			
		||||
@@ -240,35 +214,22 @@ module.exports.List = class {
 | 
			
		||||
            .setTimestamp();
 | 
			
		||||
 | 
			
		||||
            interaction.reply({embeds: [embed]})
 | 
			
		||||
            player = client.manager.players.get(interaction.guild.id)
 | 
			
		||||
 | 
			
		||||
            let player = client.manager.players.get(interaction.guild.id)
 | 
			
		||||
            userId = interaction.member.user.id
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            for(var song of playlist.videos) {
 | 
			
		||||
        
 | 
			
		||||
                if(song.uri) {
 | 
			
		||||
                    song.url = song.uri
 | 
			
		||||
                } 
 | 
			
		||||
                const song_finded = await client.manager.search(song.url)
 | 
			
		||||
                next.push(song_finded.tracks[0])
 | 
			
		||||
 | 
			
		||||
                process.emit("MUSIC_UPDATE_STATE")
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(!player.playing) {
 | 
			
		||||
 | 
			
		||||
               player.play(next[0])
 | 
			
		||||
               this.remove(next[0])
 | 
			
		||||
            
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
           
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            var client = null
 | 
			
		||||
 | 
			
		||||
            if(!client) {
 | 
			
		||||
 | 
			
		||||
                client = discord.getClient()
 | 
			
		||||
            }
 | 
			
		||||
        
 | 
			
		||||
            let player = client.manager.players.get("137291455336022018")
 | 
			
		||||
        
 | 
			
		||||
            if(!player) { 
 | 
			
		||||
 | 
			
		||||
                var channelId = discord.getMemberVoices().get(userId)
 | 
			
		||||
@@ -289,20 +250,17 @@ module.exports.List = class {
 | 
			
		||||
                player.connect();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for(var song of playlist) {
 | 
			
		||||
    
 | 
			
		||||
                const song_finded = await client.manager.search(song.uri)
 | 
			
		||||
                next.push(song_finded.tracks[0])
 | 
			
		||||
                process.emit("MUSIC_UPDATE_STATE")
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(!player.playing) {
 | 
			
		||||
 | 
			
		||||
               player.play(next[0])
 | 
			
		||||
               this.remove(next[0])
 | 
			
		||||
                player.play(next[0])
 | 
			
		||||
                this.remove(next[0])
 | 
			
		||||
             
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
          
 | 
			
		||||
 | 
			
		||||
           
 | 
			
		||||
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,217 +0,0 @@
 | 
			
		||||
const fs = require("fs")
 | 
			
		||||
const path = require("path")
 | 
			
		||||
 | 
			
		||||
var logStream = null
 | 
			
		||||
var logInstance = new Map()
 | 
			
		||||
 | 
			
		||||
setup()
 | 
			
		||||
 | 
			
		||||
function getDate(formated) {
 | 
			
		||||
 | 
			
		||||
    var date = new Date()
 | 
			
		||||
 | 
			
		||||
    // [Date Format] - Format de la date
 | 
			
		||||
 | 
			
		||||
    var gmonth = date.getMonth()
 | 
			
		||||
    var gday = date.getDate()
 | 
			
		||||
    var gHour = date.getHours()
 | 
			
		||||
    var gMinute = date.getMinutes()
 | 
			
		||||
    var gSecondes = date.getSeconds()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(date.getMonth() + 1 <= 10) {
 | 
			
		||||
        gmonth = "0" + (date.getMonth() + 1)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(date.getDate() + 1 <= 10) {
 | 
			
		||||
        gday = "0" + date.getDate()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(date.getHours() + 1 <= 10) {
 | 
			
		||||
        gHour = "0" + date.getHours()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(date.getMinutes() + 1 <= 10) {
 | 
			
		||||
        gMinute = "0" + date.getMinutes()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(date.getSeconds() + 1 <= 10) {
 | 
			
		||||
        gSecondes = "0" + date.getSeconds()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(!formated) {
 | 
			
		||||
        return gday + "/" + gmonth +  " - " + gHour + "h"  + "-" + gMinute + "m" + "-" + gSecondes + "s" 
 | 
			
		||||
    } else {
 | 
			
		||||
        return date.getFullYear() + "-" + gmonth + "-" + gday + "-" + gHour + "h"  + "-" + gMinute + "m" + "-" + gSecondes + "s" 
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function setup() {
 | 
			
		||||
 | 
			
		||||
    if(!fs.existsSync(__dirname + path.sep + "logs" + path.sep)) { 
 | 
			
		||||
        fs.mkdir(__dirname + path.sep + "logs", (err) => {
 | 
			
		||||
            if(!err) {
 | 
			
		||||
               
 | 
			
		||||
 | 
			
		||||
                console.log("[Logs] - Dossier de logs crée ! !")
 | 
			
		||||
 
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                console.log("[Logs] -Erreur d'écriture par manque de permission ")
 | 
			
		||||
                console.log(err)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        })
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    logStream = fs.createWriteStream(__dirname + path.sep + "logs" + path.sep + getDate(true) + ".log", {
 | 
			
		||||
        flags: 'a'
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
  
 | 
			
		||||
    logStream.write("[" + require("../../package.json").name + "@"+ require("../../package.json").version + "] - [" + getDate(true) + "]" + "\n")
 | 
			
		||||
    logStream.write("Subsonics-Web by Raphix" + "\n")
 | 
			
		||||
    logStream.write("----------------------------------------------------------------" + "\n")
 | 
			
		||||
 | 
			
		||||
    process.on('uncaughtException', (err) => {
 | 
			
		||||
        console.error("["+ "FATAL" + "] - The application has encountered an error ! Please Restart ! #E = " + err + "\n")
 | 
			
		||||
        console.error(err)
 | 
			
		||||
        logStream.write("[" + getDate() + "] - ["+ "FATAL" + "] - The application has encountered an error ! Please Restart ! #E = " + err + "\n")
 | 
			
		||||
        logStream.end( "["+ "UNCAUGHT_EXCEPTION" + "]" + " - [END OF LOGS] - [" + getDate()  + ']')
 | 
			
		||||
        logStream.close()
 | 
			
		||||
         
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    process.on('beforeExit', (err) => {
 | 
			
		||||
        logStream.end( "["+ "BEFORE_EXIT" + "]" + " - [END OF LOGS] - [" + getDate(true)  + ']')
 | 
			
		||||
        logStream.close()
 | 
			
		||||
         
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.getInstance = function (name) {
 | 
			
		||||
 | 
			
		||||
    if(logInstance.has(name)) {
 | 
			
		||||
 | 
			
		||||
        return logInstance.get(name)
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        var logtext = "[Logs] - [ERROR] - '" + name +  "' n'est pas enregistré en tant qu'instance de log !"
 | 
			
		||||
        logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
        console.log(logtext)
 | 
			
		||||
 | 
			
		||||
        return null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.LogType = class {
 | 
			
		||||
 | 
			
		||||
    constructor(typeName) {
 | 
			
		||||
        this.type = typeName;
 | 
			
		||||
        this.steps = new Map()
 | 
			
		||||
        this.step = this.initializeStep()
 | 
			
		||||
        logInstance.set(typeName, this)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    log(txt) {
 | 
			
		||||
 | 
			
		||||
       
 | 
			
		||||
        
 | 
			
		||||
        var logtext = "[" + this.type + "] - [INFO] - " + txt
 | 
			
		||||
        logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
        console.log(logtext)
 | 
			
		||||
        
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    warn(txt) {
 | 
			
		||||
        
 | 
			
		||||
        var logtext = "[" + this.type + "] - [WARN] - " + txt
 | 
			
		||||
        logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
        console.log(logtext)
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    error(txt) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        var logtext = "[" + this.type + "] - [ERROR] - " + txt
 | 
			
		||||
        logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
        console.log(logtext)
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
       
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    initializeStep() {
 | 
			
		||||
        const parent = this;
 | 
			
		||||
        return { 
 | 
			
		||||
            init: function(id, desc) {
 | 
			
		||||
                parent.steps.set(id, desc)
 | 
			
		||||
                var logtext = "[" + parent.type + "] - [INFO] - [STEP] - " + desc + " - En cours ..."
 | 
			
		||||
                logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
                console.log(logtext)
 | 
			
		||||
            
 | 
			
		||||
            },
 | 
			
		||||
            end: function(id) {
 | 
			
		||||
                
 | 
			
		||||
                if(parent.steps.has(id)) {
 | 
			
		||||
                    
 | 
			
		||||
                    var logtext = "[" + parent.type + "] - [INFO] - [STEP] - " + parent.steps.get(id) + " - Terminé !"
 | 
			
		||||
                    logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
                    console.log(logtext)
 | 
			
		||||
                    parent.steps.delete(id)
 | 
			
		||||
                } else {
 | 
			
		||||
                    
 | 
			
		||||
                    var logtext = "[" + parent.type + "] - [WARN] - [STEP] - '" + id +  "' n'est pas enregistré en tant qu'étape !"
 | 
			
		||||
                    logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
                    console.log(logtext)
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            
 | 
			
		||||
            },
 | 
			
		||||
            error: function(id, errorDesc) {
 | 
			
		||||
 | 
			
		||||
                if(parent.steps.has(id)) {
 | 
			
		||||
                   
 | 
			
		||||
                    var logtext = "[" + parent.type + "] - [ERROR] - [STEP] - " + parent.steps.get(id) + " - Une erreur a été rencontré dans l'étape ! : #E = " + errorDesc
 | 
			
		||||
                    logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
                    console.log(logtext)
 | 
			
		||||
                    parent.steps.delete(id)
 | 
			
		||||
                } else {
 | 
			
		||||
                    
 | 
			
		||||
                    var logtext = "[" + parent.type + "] - [WARN] - [STEP] - '" + id +  "' n'est pas enregistré en tant qu'étape !"
 | 
			
		||||
                    logStream.write("[" + getDate() + "] - " + logtext + "\n")
 | 
			
		||||
                    console.log(logtext)
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
const { SlashCommandBuilder, EmbedBuilder, DefaultWebSocketManagerOptions, discordSort } = require("discord.js");
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require("./sub-log");
 | 
			
		||||
const { LogType } = require("loguix");
 | 
			
		||||
var { List } = require("./sub-list")
 | 
			
		||||
const discord = require("./discord-bot")
 | 
			
		||||
var ytfps = require("ytfps");
 | 
			
		||||
const packageJson = require(__glob.PACKAGE);
 | 
			
		||||
 | 
			
		||||
const { Metric } = require("webmetrik");
 | 
			
		||||
 | 
			
		||||
const list = new List()
 | 
			
		||||
 | 
			
		||||
@@ -61,8 +61,8 @@ module.exports.play = async function (client, interaction) {
 | 
			
		||||
                    .setColor(0x15e6ed)
 | 
			
		||||
                    .setTitle('**Lecture de : **' + songs.tracks[0].title)
 | 
			
		||||
                    .setDescription('**Demandé par **' + interaction.member.user.username)
 | 
			
		||||
                    .addFields({name: "Auteur", value: son.tracks[0].author},
 | 
			
		||||
                               {name: "URL", value:songs.tragscks[0].uri})
 | 
			
		||||
                    .addFields({name: "Auteur", value: songs.tracks[0].author},
 | 
			
		||||
                               {name: "URL", value: songs.tracks[0].uri})
 | 
			
		||||
                    .setThumbnail(songs.tracks[0].thumbnail)
 | 
			
		||||
                    .setTimestamp();
 | 
			
		||||
        
 | 
			
		||||
@@ -79,11 +79,8 @@ module.exports.play = async function (client, interaction) {
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        playStats(interaction.member.user.username)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
            // [A FINIR POUR WEB]
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
@@ -193,71 +190,19 @@ module.exports.getState = function(client, interaction) {
 | 
			
		||||
module.exports.playPlaylist = function (id, data) {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    list.playlistAdd(data, null, id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.SPECIAL_MJ = async function (client, userId) {
 | 
			
		||||
 | 
			
		||||
    if(!client) {
 | 
			
		||||
 | 
			
		||||
        client = discord.getClient()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let player = client.manager.players.get("137291455336022018")
 | 
			
		||||
 | 
			
		||||
    var memberVoices = discord.getMemberVoices()
 | 
			
		||||
    var channelId = memberVoices.get(userId)
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    if(!channelId) {
 | 
			
		||||
        
 | 
			
		||||
        channelId = "664355808250953739"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(!player) { 
 | 
			
		||||
            
 | 
			
		||||
        player = client.manager.create({
 | 
			
		||||
            guild: "137291455336022018",
 | 
			
		||||
            voiceChannel: channelId,
 | 
			
		||||
            textChannel: "664355637685256203",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        player.connect();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    const songs = await client.manager.search("Earth MJ")
 | 
			
		||||
    const songs2 = await client.manager.search("https://www.youtube.com/watch?v=_mwsc6xqb3w")
 | 
			
		||||
    const songs3 = await client.manager.search("https://www.youtube.com/watch?v=IdjgmRa3k-g")
 | 
			
		||||
 | 
			
		||||
    if(!player.playing) {
 | 
			
		||||
        player.play(songs.tracks[0])
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        
 | 
			
		||||
        list.add(songs.tracks[0])
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
    list.add(songs2.tracks[0])
 | 
			
		||||
    list.add(songs3.tracks[0])
 | 
			
		||||
    const playlist = {}
 | 
			
		||||
    playlist.videos = data
 | 
			
		||||
    list.playlistAdd(playlist, null, id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.addSong = async function (data, client, userId, quick, playlist) {
 | 
			
		||||
 | 
			
		||||
    if(!client) {
 | 
			
		||||
module.exports.addSong = async function (data, userId, quick, playlist) {
 | 
			
		||||
 | 
			
		||||
        client = discord.getClient()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    var client = discord.getClient()
 | 
			
		||||
    
 | 
			
		||||
    let player = client.manager.players.get("137291455336022018")
 | 
			
		||||
 | 
			
		||||
@@ -315,41 +260,15 @@ module.exports.addSong = async function (data, client, userId, quick, playlist)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.addSongsFromPlaylist = async function (data, client, userId, quick, playlist) {
 | 
			
		||||
 | 
			
		||||
    if(!client) {
 | 
			
		||||
 | 
			
		||||
        client = discord.getClient()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let player = client.manager.players.get("137291455336022018")
 | 
			
		||||
 | 
			
		||||
    var memberVoices = discord.getMemberVoices()
 | 
			
		||||
    var channelId = memberVoices.get(userId)
 | 
			
		||||
 | 
			
		||||
    if(!channelId) {
 | 
			
		||||
        
 | 
			
		||||
        channelId = "664355808250953739"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(!player) { 
 | 
			
		||||
            
 | 
			
		||||
        player = client.manager.create({
 | 
			
		||||
            guild: "137291455336022018",
 | 
			
		||||
            voiceChannel: channelId,
 | 
			
		||||
            textChannel: "664355637685256203",
 | 
			
		||||
        });
 | 
			
		||||
module.exports.addSongsFromPlaylist = async function (data, userId) {
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
        player.connect();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var playlist = await checkPlaylist(data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(playlist) {
 | 
			
		||||
 | 
			
		||||
        list.fpPlaylistAdd(playlist, client)
 | 
			
		||||
        list.playlistAdd(playlist, null, userId)
 | 
			
		||||
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
@@ -834,3 +753,9 @@ async function checkPlaylist (song_name) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function playStats(username) {
 | 
			
		||||
    var userMusicPlayed = new Metric("userMusicPlayed_" + username, "Nombre de musiques jouées par l'utilisateur : " + username)
 | 
			
		||||
    userMusicPlayed.setValue(userMusicPlayed.getValue() + 1)
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,8 @@
 | 
			
		||||
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 { LogType } = require("loguix");
 | 
			
		||||
const subplayer = require("./sub-player")
 | 
			
		||||
const fs = require("fs");
 | 
			
		||||
const { type } = require("os");
 | 
			
		||||
var playlists = {}
 | 
			
		||||
const plog = new LogType("Playlist-Manager")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
const { __glob } = require("../modules/global-variables");
 | 
			
		||||
const { LogType } = require("./sub-log");
 | 
			
		||||
const { LogType } = require("loguix");
 | 
			
		||||
var { List } = require("./sub-list")
 | 
			
		||||
const discord = require("./discord-bot")
 | 
			
		||||
const subplayer = require("./sub-player")
 | 
			
		||||
@@ -8,19 +8,19 @@ const { type } = require("os");
 | 
			
		||||
var radios = []
 | 
			
		||||
const plog = new LogType("Radio-Manager")
 | 
			
		||||
 | 
			
		||||
check()
 | 
			
		||||
checkRadioFile()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports.get = function () {
 | 
			
		||||
 | 
			
		||||
    check()
 | 
			
		||||
    checkRadioFile()
 | 
			
		||||
    return radios
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.add = function (data) {
 | 
			
		||||
    
 | 
			
		||||
    var radios_data = JSON.parse(fs.readFileSync(__glob.RADIO))
 | 
			
		||||
    var radios_data = readRadioFile()
 | 
			
		||||
            
 | 
			
		||||
    radios_data.push(data)
 | 
			
		||||
    fs.writeFileSync(__glob.RADIO, JSON.stringify(radios_data, null, 2))
 | 
			
		||||
@@ -31,7 +31,7 @@ module.exports.add = function (data) {
 | 
			
		||||
 | 
			
		||||
module.exports.remove = function(data) {
 | 
			
		||||
 | 
			
		||||
            var radios_data = JSON.parse(fs.readFileSync(__glob.RADIO))
 | 
			
		||||
            var radios_data = readRadioFile()
 | 
			
		||||
 | 
			
		||||
            var radIndex = -1
 | 
			
		||||
 | 
			
		||||
@@ -48,11 +48,26 @@ module.exports.remove = function(data) {
 | 
			
		||||
 | 
			
		||||
            radios_data.splice(radIndex, 1)
 | 
			
		||||
            
 | 
			
		||||
            fs.writeFileSync(__glob.RADIO, JSON.stringify(radios_data, null, 2))
 | 
			
		||||
           saveRadioFile(radios_data)
 | 
			
		||||
           
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function check() {
 | 
			
		||||
function saveRadioFile(data) {
 | 
			
		||||
 | 
			
		||||
    fs.writeFileSync(__glob.RADIO, JSON.stringify(data, null, 2))
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
function readRadioFile() {
 | 
			
		||||
 | 
			
		||||
    if(fs.existsSync(__glob.RADIO)) {
 | 
			
		||||
            
 | 
			
		||||
        return JSON.parse(fs.readFileSync(__glob.RADIO))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function checkRadioFile() {
 | 
			
		||||
 | 
			
		||||
    if(fs.existsSync(__glob.RADIO)) {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,10 @@ socket.on("connect", () => {
 | 
			
		||||
    get("MUSIC_STATE")
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
socket.on("disconnect", () => {
 | 
			
		||||
    window.location.href = "/"
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function get(request) {
 | 
			
		||||
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
@@ -20,7 +24,7 @@ function get(request) {
 | 
			
		||||
        
 | 
			
		||||
        socket.once("ANSWER/GET/" + request, (answer) => {
 | 
			
		||||
            
 | 
			
		||||
            console.log("Réponse pour la requête : " + request)
 | 
			
		||||
            console.log("Réponse pour la requête GET : " + request)
 | 
			
		||||
       
 | 
			
		||||
            resolve(answer)
 | 
			
		||||
                    
 | 
			
		||||
@@ -30,16 +34,16 @@ function get(request) {
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function send(request, data, secondata, thirddata) {
 | 
			
		||||
function post(request, data, secondata, thirddata) {
 | 
			
		||||
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
        socket.emit("SEND/" + request, data, secondata, thirddata)
 | 
			
		||||
        console.log("Envoi de la requête SEND : " + request)
 | 
			
		||||
        socket.emit("POST/" + request, data, secondata, thirddata)
 | 
			
		||||
        console.log("Envoi de la requête POST : " + request)
 | 
			
		||||
        
 | 
			
		||||
        socket.once("ANSWER/SEND/" + request, (answer) => {
 | 
			
		||||
        socket.once("ANSWER/POST/" + request, (answer) => {
 | 
			
		||||
            
 | 
			
		||||
            console.log("Réponse pour la requête : " + request)
 | 
			
		||||
            console.log("Réponse pour la requête POST : " + request)
 | 
			
		||||
            
 | 
			
		||||
            resolve(answer)
 | 
			
		||||
                    
 | 
			
		||||
@@ -49,6 +53,15 @@ function send(request, data, secondata, thirddata) {
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function AlwaysRequest(GQname, GQcallback) {
 | 
			
		||||
    socket.on("ALWAYS/" + GQname, (data) => {
 | 
			
		||||
    
 | 
			
		||||
        console.log("Récéption pour la requête ALWAYS : " + GQname)
 | 
			
		||||
        GQcallback(data)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getSocket() {
 | 
			
		||||
 | 
			
		||||
    return socket
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
const loginBtn = document.getElementById("loginBtn")
 | 
			
		||||
 | 
			
		||||
loginBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    const discordLink = get("DISCORD_LOGIN_LINK")
 | 
			
		||||
    discordLink.then(link => {
 | 
			
		||||
 | 
			
		||||
        window.location.href = link
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										187
									
								
								src/web/public/javascript/basics.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,187 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @param {string} id 
 | 
			
		||||
 * @returns element
 | 
			
		||||
 */
 | 
			
		||||
function getID(id) {
 | 
			
		||||
    return document.getElementById(id);
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
// Get The position of the mouse
 | 
			
		||||
 | 
			
		||||
var xMousePos = 0;
 | 
			
		||||
var yMousePos = 0;
 | 
			
		||||
 | 
			
		||||
document.onmousemove = function(e)
 | 
			
		||||
{
 | 
			
		||||
  xMousePos = e.clientX + window.scrollX;
 | 
			
		||||
  yMousePos = e.clientY + window.scrollY;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function disableDrag() {
 | 
			
		||||
  // Ajoutez un gestionnaire d'événement pour l'événement dragover
 | 
			
		||||
  document.addEventListener('dragover', function (e) {
 | 
			
		||||
      e.preventDefault(); // Empêche le comportement par défaut du navigateur
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Ajoutez un gestionnaire d'événement pour l'événement drop
 | 
			
		||||
  document.addEventListener('drop', function (e) {
 | 
			
		||||
      e.preventDefault(); // Empêche le comportement par défaut du navigateur
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Pour réactiver le drag-and-drop, vous pouvez supprimer les gestionnaires d'événements
 | 
			
		||||
function enableDrag() {
 | 
			
		||||
  // Supprimez le gestionnaire d'événement pour l'événement dragover
 | 
			
		||||
  document.removeEventListener('dragover', function (e) {
 | 
			
		||||
      e.preventDefault(); // Empêche le comportement par défaut du navigateur
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Supprimez le gestionnaire d'événement pour l'événement drop
 | 
			
		||||
  document.removeEventListener('drop', function (e) {
 | 
			
		||||
      e.preventDefault(); // Empêche le comportement par défaut du navigateur
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function startInterval() {
 | 
			
		||||
  interval = setInterval(() => {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      if(isPlaying == true) {
 | 
			
		||||
          setTime()
 | 
			
		||||
  
 | 
			
		||||
      } 
 | 
			
		||||
  
 | 
			
		||||
  }, 1000)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function stopInterval() {
 | 
			
		||||
  clearInterval(interval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function setTime() {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  durationBar.max = durationAll
 | 
			
		||||
  durationProgress += 1000 
 | 
			
		||||
  durationBar.value = durationProgress
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  const maxhours = Math.floor(durationAll / 3600000);
 | 
			
		||||
  const nowhours = Math.floor(durationProgress / 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);
 | 
			
		||||
  var nowmin = Math.trunc(durationProgress / 60000) - (Math.floor(durationProgress / 60000 / 60) * 60);
 | 
			
		||||
  var nowsec = Math.floor(durationProgress / 1000) - (Math.floor(durationProgress / 1000 / 60) * 60);
 | 
			
		||||
 | 
			
		||||
  console.log(durationAll)
 | 
			
		||||
  console.log(durationProgress)
 | 
			
		||||
  console.log("---------------------")
 | 
			
		||||
 | 
			
		||||
  var now = ""
 | 
			
		||||
  var max = ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  if (maxmin < 10) {
 | 
			
		||||
      maxmin = `0${maxmin}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (nowmin < 10) {
 | 
			
		||||
      nowmin = `0${nowmin}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (maxsec < 10) {
 | 
			
		||||
      maxsec = `0${maxsec}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (nowsec < 10) {
 | 
			
		||||
      nowsec = `0${nowsec}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(maxhours != 0) {
 | 
			
		||||
     
 | 
			
		||||
      max =  maxhours + ":" + maxmin + ":" + maxsec
 | 
			
		||||
  } else {
 | 
			
		||||
      max =  maxmin + ":" + maxsec
 | 
			
		||||
     
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(nowhours != 0) {
 | 
			
		||||
     
 | 
			
		||||
      now =  nowhours + ":" + nowmin + ":" + nowsec
 | 
			
		||||
  } else {
 | 
			
		||||
      now =  nowmin + ":" + nowsec
 | 
			
		||||
     
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
 durationTextAct.innerHTML = now
 | 
			
		||||
 durationTextTotal.innerHTML = max
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getTimeCode(pdurationAll) {
 | 
			
		||||
    var pmax = ""
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
    const pmaxhours = Math.floor(pdurationAll / 3600000);
 | 
			
		||||
 | 
			
		||||
    var pmaxmin = Math.trunc(pdurationAll / 60000) - (Math.floor(pdurationAll / 60000 / 60) * 60);
 | 
			
		||||
    var pmaxsec = Math.floor(pdurationAll / 1000) - (Math.floor(pdurationAll / 1000 / 60) * 60);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (pmaxsec < 10) {
 | 
			
		||||
        pmaxsec = `0${pmaxsec}`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(pmaxhours != 0) {
 | 
			
		||||
 | 
			
		||||
        if (pmaxmin < 10) {
 | 
			
		||||
            pmaxmin = `0${pmaxmin}`;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        pmax = pmaxhours + ":" + pmaxmin + ":" + pmaxsec
 | 
			
		||||
    } else {
 | 
			
		||||
        pmax =  pmaxmin + ":" + pmaxsec
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
    return pmax
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function loadHome() {
 | 
			
		||||
 | 
			
		||||
  userLocation = "home"
 | 
			
		||||
 | 
			
		||||
  mainView.innerHTML = WelcomeContent
 | 
			
		||||
 | 
			
		||||
  get("ALL_CONNECTED_USER")
 | 
			
		||||
  get("ALL_RADIO")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const buttons = document.querySelectorAll(".sside_line");
 | 
			
		||||
 | 
			
		||||
    buttons.forEach(button => {
 | 
			
		||||
        button.addEventListener("click", function () {
 | 
			
		||||
            buttons.forEach(btn => {
 | 
			
		||||
                if (btn === button) {
 | 
			
		||||
                    btn.style.color = "white";
 | 
			
		||||
                } else {
 | 
			
		||||
                    btn.style.color = "";
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
							
								
								
									
										137
									
								
								src/web/public/javascript/indexscript.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,137 @@
 | 
			
		||||
 | 
			
		||||
updateUsersPictures()
 | 
			
		||||
 | 
			
		||||
AlwaysRequest("UPDATE_SELF", () => {
 | 
			
		||||
    updateUsersPictures()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function updateUsersPictures() {
 | 
			
		||||
 | 
			
		||||
    const userInfo = get("USER_INFO")
 | 
			
		||||
 | 
			
		||||
    userInfo.then(user => {
 | 
			
		||||
 | 
			
		||||
        settingsBtn.style.display = "none"
 | 
			
		||||
    
 | 
			
		||||
        if(user.admin == true) {
 | 
			
		||||
 | 
			
		||||
            settingsBtn.style.display = "flex"
 | 
			
		||||
            userAdmin = true
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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='" + user.picture +"'>" + "</div>"
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
userInfoDiv.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    if(userInfoPopup.classList.contains("invisible")) {
 | 
			
		||||
 | 
			
		||||
        userInfoPopup.classList.remove("invisible")
 | 
			
		||||
        userInfoPopup.style.left = (xMousePos - 110) + "px"
 | 
			
		||||
        userInfoPopup.style.top = yMousePos + "px"
 | 
			
		||||
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
userInfoPopup.classList.add("invisible")
 | 
			
		||||
 | 
			
		||||
userInfoPopup.addEventListener("mouseleave", () => {
 | 
			
		||||
 | 
			
		||||
    userInfoPopup.classList.add("invisible")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// Load users connected
 | 
			
		||||
 | 
			
		||||
AlwaysRequest("ALL_CONNECTED_USER", (data) => {
 | 
			
		||||
    if(userLocation == "home") {
 | 
			
		||||
        
 | 
			
		||||
        const website_list = document.getElementById("website_list")
 | 
			
		||||
        const userToPush = new Array()
 | 
			
		||||
    
 | 
			
		||||
        userToPush.push("<p style=' padding-bottom: 1%; font-family: Gunship, sans-serif;'><i class='fa fa-users'></i> Utilisateurs connecté(es)</p>")
 | 
			
		||||
    
 | 
			
		||||
        for(var user of data) {
 | 
			
		||||
     
 | 
			
		||||
           userToPush.push(`<div style=' padding-bottom: 2%; padding-top: 1%;' class="set_user_info"><img  style='margin-right: 3%;' src="${user.picture}"><div style="display: flex; flex-direction: column; justify-content: center;"><p class="INDEX_gbname">${user.global_name}</p><p class="INDEX_usrname">${user.username}</p></div></div>`)
 | 
			
		||||
    
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        website_list.innerHTML = userToPush.join("")
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var timeoutId = null
 | 
			
		||||
 | 
			
		||||
socket.on("NOTIFICATION", (data) => {
 | 
			
		||||
 | 
			
		||||
    if(timeoutId) {
 | 
			
		||||
 | 
			
		||||
        clearTimeout(timeoutId)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const notifDiv = document.getElementById("notif")
 | 
			
		||||
    const notif_image = document.getElementById("notif_image")
 | 
			
		||||
    const notif_text = document.getElementById("notif_text")
 | 
			
		||||
 | 
			
		||||
    notif_image.src = data.image_src
 | 
			
		||||
    notif_text.innerHTML = data.text
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    notifDiv.classList.add("notif_div_on")
 | 
			
		||||
 | 
			
		||||
    timeoutId = setTimeout(() => {
 | 
			
		||||
 | 
			
		||||
        notifDiv.classList.remove("notif_div_on")
 | 
			
		||||
    }, 4000)
 | 
			
		||||
 | 
			
		||||
    notifDiv.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        if(timeoutId) {
 | 
			
		||||
 | 
			
		||||
            clearTimeout(timeoutId)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        notifDiv.classList.remove("notif_div_on")
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Window Selector
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
homeBtn.style.color = "white"
 | 
			
		||||
 | 
			
		||||
homeBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    loadHome()
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// Restart
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
restartBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    get("RESTART")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Start Operation
 | 
			
		||||
 | 
			
		||||
loadHome()
 | 
			
		||||
							
								
								
									
										9
									
								
								src/web/public/javascript/login-script.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
			
		||||
const loginBtn = document.getElementById("loginBtn")
 | 
			
		||||
 | 
			
		||||
loginBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
    window.location.href = "/internal/discordlink"
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										68
									
								
								src/web/public/javascript/middle.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,68 @@
 | 
			
		||||
const userInfoDiv = getID("userInfo")
 | 
			
		||||
const userInfoPopup = getID("userPopup")
 | 
			
		||||
const userInfoglobal = getID("userInfoglobal")
 | 
			
		||||
 | 
			
		||||
const musicTitle = getID("music_title")
 | 
			
		||||
const musicURL = getID("music_img")
 | 
			
		||||
 | 
			
		||||
const durationBar = getID("duration")
 | 
			
		||||
const durationTextAct = getID("durationTextAct")
 | 
			
		||||
const durationTextTotal = getID("durationTextTotal")
 | 
			
		||||
 | 
			
		||||
const backward = getID("backward")
 | 
			
		||||
const play = getID("play")
 | 
			
		||||
const forward = getID("forward")
 | 
			
		||||
 | 
			
		||||
const settingsBtn = getID("settings_btn")
 | 
			
		||||
 | 
			
		||||
const loop = getID("loop")
 | 
			
		||||
const vol = getID("volbtn")
 | 
			
		||||
const shuffle = getID("shuffle")
 | 
			
		||||
const list = getID("list_btn")
 | 
			
		||||
const takeCurrent =  getID("takeCurrent")
 | 
			
		||||
 | 
			
		||||
const volBox = getID("volumeBox")
 | 
			
		||||
const volTxt = getID("volumeTxt")
 | 
			
		||||
const volDiv = getID("volDiv")
 | 
			
		||||
const volRange = getID("volumeInput")
 | 
			
		||||
 | 
			
		||||
const listBox = getID("listBox")
 | 
			
		||||
const listNumber = getID("listNumber")
 | 
			
		||||
 | 
			
		||||
const disconnect = getID("disconnect")
 | 
			
		||||
 | 
			
		||||
const report_dialog = getID("report_dialog")
 | 
			
		||||
const report_close = getID("report_close")
 | 
			
		||||
const reportBtn = getID("reportBtn")
 | 
			
		||||
const report_level =  getID("report_level")
 | 
			
		||||
const report_desc =  getID("report_desc")
 | 
			
		||||
const report_send =  getID("report_send")
 | 
			
		||||
 | 
			
		||||
const searchBtn = getID("search_btn")
 | 
			
		||||
const homeBtn = getID("home_btn")
 | 
			
		||||
const mainView = getID("mainView")
 | 
			
		||||
 | 
			
		||||
const restartBtn = getID("restartBtn")
 | 
			
		||||
const WelcomeContent = mainView.firstElementChild.outerHTML
 | 
			
		||||
const playlistContent = getID("playlist-content")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Get the current location of the user
 | 
			
		||||
var userLocation = "home"
 | 
			
		||||
var userAdmin = false
 | 
			
		||||
 | 
			
		||||
// Player 
 | 
			
		||||
 | 
			
		||||
var durationAll = 0
 | 
			
		||||
var durationProgress = 0
 | 
			
		||||
var isPlaying = false
 | 
			
		||||
let interval;
 | 
			
		||||
 | 
			
		||||
// Playlist
 | 
			
		||||
 | 
			
		||||
var playlistSelected = null
 | 
			
		||||
var playlistValue = null
 | 
			
		||||
var deleteJustBefore = null
 | 
			
		||||
var currentSong = null
 | 
			
		||||
var playlistAvailable = null
 | 
			
		||||
							
								
								
									
										371
									
								
								src/web/public/javascript/player.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,371 @@
 | 
			
		||||
AlwaysRequest("MUSIC_STATE", async (data) => {
 | 
			
		||||
    await disableDrag()
 | 
			
		||||
    await enableDrag()
 | 
			
		||||
 | 
			
		||||
    stopInterval()
 | 
			
		||||
    console.log(data)
 | 
			
		||||
 | 
			
		||||
    durationAll = 0
 | 
			
		||||
    durationProgress = 0
 | 
			
		||||
    isPlaying = false
 | 
			
		||||
 | 
			
		||||
    if(data.isOnline) {
 | 
			
		||||
       
 | 
			
		||||
        vol.classList.remove("disabled")
 | 
			
		||||
        shuffle.classList.remove("disabled")
 | 
			
		||||
        list.classList.remove("disabled")
 | 
			
		||||
        play.classList.remove("pri_disable")
 | 
			
		||||
        disconnect.classList.remove("invisible")
 | 
			
		||||
        volRange.classList.add("disabled")
 | 
			
		||||
 | 
			
		||||
        volRange.disabled = false
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        vol.classList.add("disabled")
 | 
			
		||||
        shuffle.classList.add("disabled")
 | 
			
		||||
        list.classList.add("disabled")
 | 
			
		||||
        play.classList.add("pri_disable")
 | 
			
		||||
        disconnect.classList.add("invisible")
 | 
			
		||||
        volRange.classList.add("disabled")
 | 
			
		||||
        volRange.disabled = true
 | 
			
		||||
        volRange.value = 0
 | 
			
		||||
        volTxt.innerHTML = "0%"
 | 
			
		||||
        volBox.classList.add("invisible")
 | 
			
		||||
      
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(data.volume) {
 | 
			
		||||
        volRange.step = 1
 | 
			
		||||
        volRange.max = 200
 | 
			
		||||
        volRange.min = 1
 | 
			
		||||
        volRange.value = Math.trunc(data.volume / 10)
 | 
			
		||||
        volTxt.innerHTML = Math.trunc(data.volume / 10) + "%"
 | 
			
		||||
 | 
			
		||||
        var volNum = Math.trunc(data.volume / 10)
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        volRange.classList.add("disabled")
 | 
			
		||||
        volRange.disabled = true
 | 
			
		||||
        volRange.value = 0
 | 
			
		||||
        volTxt.innerHTML = "0%"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(data.shuffle == true) {
 | 
			
		||||
        shuffle.innerHTML = '<i class="third-join fa fa-shuffle"></i>'
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        shuffle.innerHTML = '<i class="fa fa-shuffle"></i>'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(data.loop == true) {
 | 
			
		||||
        loop.innerHTML = '<i class="third-join fa fa-retweet"></i>'
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        loop.innerHTML = '<i class="fa fa-retweet"></i>'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(data.current == null) {
 | 
			
		||||
 | 
			
		||||
        musicURL.innerHTML = '<img class="showPicture" src="images/black-image.svg">'
 | 
			
		||||
        musicTitle.innerHTML = "<p>Aucun titre joué</p>"
 | 
			
		||||
        loop.classList.add("invisible")
 | 
			
		||||
        takeCurrent.classList.add("invisible")
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        var thumbnail = data.current.thumbnail
 | 
			
		||||
    
 | 
			
		||||
        if(!thumbnail) {
 | 
			
		||||
 | 
			
		||||
            thumbnail = "/images/black-image.svg"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        musicURL.innerHTML = '<img class="showPicture" src="' + thumbnail + '">'
 | 
			
		||||
        musicTitle.innerHTML = "<p>" + data.current.title + "</p>"
 | 
			
		||||
        currentSong = data.current
 | 
			
		||||
        takeCurrent.classList.remove("invisible")
 | 
			
		||||
        loop.classList.remove("invisible")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(data.durationAll) {
 | 
			
		||||
        durationBar.disabled = false
 | 
			
		||||
        durationBar.classList.remove("grised")
 | 
			
		||||
        setTime()
 | 
			
		||||
       
 | 
			
		||||
        durationAll = data.durationAll
 | 
			
		||||
        durationProgress = data.durationNow
 | 
			
		||||
        durationBar.value = durationProgress
 | 
			
		||||
        setTime()
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
       
 | 
			
		||||
        isPlaying = false
 | 
			
		||||
        durationAll = 0
 | 
			
		||||
        durationProgress = 0
 | 
			
		||||
        durationBar.disabled = true
 | 
			
		||||
        durationBar.classList.add("grised")
 | 
			
		||||
        durationBar.value = 0
 | 
			
		||||
        durationTextAct.innerHTML = "-:--"
 | 
			
		||||
        durationTextTotal.innerHTML = "-:--"
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(data.playing == 1) {
 | 
			
		||||
        play.innerHTML = '<i class="fas fa-pause"></i>'
 | 
			
		||||
        isPlaying = true
 | 
			
		||||
        startInterval()
 | 
			
		||||
    } else {
 | 
			
		||||
        
 | 
			
		||||
        play.innerHTML = '<i class="fas fa-play"></i>'
 | 
			
		||||
        isPlaying = false
 | 
			
		||||
       
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
  
 | 
			
		||||
    if(data.current && data.playing == 0) {
 | 
			
		||||
        setTime()
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(data.durationAll == 9223372036854776000) {
 | 
			
		||||
 | 
			
		||||
        isPlaying = false
 | 
			
		||||
        durationAll = 0
 | 
			
		||||
        durationProgress = 0
 | 
			
		||||
        durationBar.disabled = true
 | 
			
		||||
        durationBar.classList.add("grised")
 | 
			
		||||
        durationBar.style.display = "none"
 | 
			
		||||
        durationBar.value = 0
 | 
			
		||||
        durationTextAct.innerHTML = ""
 | 
			
		||||
        durationTextTotal.innerHTML = "<i style='color: red;' class='fa-solid fa-circle'></i> LIVE"
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        durationBar.style.display = "unset"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(data.queue != null) {
 | 
			
		||||
 | 
			
		||||
        var contentToPush = new Array()
 | 
			
		||||
        var queueNum = 0
 | 
			
		||||
 | 
			
		||||
        for(var title of data.queue) {
 | 
			
		||||
            queueNum += 1
 | 
			
		||||
            console.log(queueNum)
 | 
			
		||||
            console.log(data.queue.indexOf(title) + " - " + title.title)
 | 
			
		||||
            var thumbnail = title.thumbnail
 | 
			
		||||
            if(!thumbnail) {
 | 
			
		||||
    
 | 
			
		||||
            thumbnail = "/images/black-image.svg"
 | 
			
		||||
                            
 | 
			
		||||
            }
 | 
			
		||||
            contentToPush.push(' <div class="draggable song" id="' + data.queue.indexOf(title) + '_queue_song"> <img class="list_thumbnail" src="' + thumbnail + '"><div class="list_titleSong"> <p class="list_title">' + title.title + '</p></div> <button id="' + data.queue.indexOf(title) + '_lmove" class="list_upSong"><i class="fa fa-arrow-up"></i></button> <button id="' + data.queue.indexOf(title) + '_ldelete" class="list_delete"><i class="fa fa-trash"></i></button> </div>')
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(contentToPush.join("") == "") {
 | 
			
		||||
           
 | 
			
		||||
            listNumber.classList.add("invisible")
 | 
			
		||||
            listBox.innerHTML = '<p class="list_error">Aucun morceau dans la liste de lecture !</p>'
 | 
			
		||||
        
 | 
			
		||||
        } else {
 | 
			
		||||
            listNumber.innerHTML = '<span class="numtext">' + queueNum + '</span>'
 | 
			
		||||
            listNumber.classList.remove("invisible")
 | 
			
		||||
            listBox.innerHTML = contentToPush.join("")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //CODE INTEGER QUEUE LIST MOVE
 | 
			
		||||
 | 
			
		||||
            const container = document.getElementById('listBox');
 | 
			
		||||
            const draggableItems = document.querySelectorAll('.draggable');
 | 
			
		||||
 | 
			
		||||
            let draggingElement = null;
 | 
			
		||||
 | 
			
		||||
            draggableItems.forEach(item => {
 | 
			
		||||
                item.addEventListener('dragstart', (e) => {
 | 
			
		||||
                e.dataTransfer.setData('text/plain', item.innerHTML);
 | 
			
		||||
                draggingElement = item;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                item.addEventListener('dragend', () => {
 | 
			
		||||
                draggingElement = null;
 | 
			
		||||
                setTimeout(() => {
 | 
			
		||||
                    item.style.display = 'flex'; // Restaure l'affichage de l'élément
 | 
			
		||||
                }, 0);
 | 
			
		||||
                updateOrder();
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            container.addEventListener('dragover', (e) => {
 | 
			
		||||
                e.preventDefault();
 | 
			
		||||
                const afterElement = getDragAfterElement(container, e.clientY);
 | 
			
		||||
                if (draggingElement !== null) {
 | 
			
		||||
                if (afterElement == null) {
 | 
			
		||||
                    container.appendChild(draggingElement);
 | 
			
		||||
                } else {
 | 
			
		||||
                    const rect = afterElement.getBoundingClientRect();
 | 
			
		||||
                    if (e.clientY < rect.top + rect.height / 2) {
 | 
			
		||||
                    container.insertBefore(draggingElement, afterElement);
 | 
			
		||||
                    } else {
 | 
			
		||||
                    container.insertBefore(draggingElement, afterElement.nextElementSibling);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            function getDragAfterElement(container, y) {
 | 
			
		||||
                const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')];
 | 
			
		||||
                return draggableElements.reduce((closest, child) => {
 | 
			
		||||
                const box = child.getBoundingClientRect();
 | 
			
		||||
                const offset = y - box.top - box.height / 2;
 | 
			
		||||
                if (offset < 0 && offset > closest.offset) {
 | 
			
		||||
                    return { offset: offset, element: child };
 | 
			
		||||
                } else {
 | 
			
		||||
                    return closest;
 | 
			
		||||
                }
 | 
			
		||||
                }, { offset: Number.NEGATIVE_INFINITY, element: null }).element;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function updateOrder() {
 | 
			
		||||
                const draggableItems = document.querySelectorAll('.draggable');
 | 
			
		||||
                const order = [];
 | 
			
		||||
                draggableItems.forEach(item => {
 | 
			
		||||
                order.push(item.id.replace("_queue_song", ""));
 | 
			
		||||
                });
 | 
			
		||||
                console.log('Ordre des divs:', order);
 | 
			
		||||
                post("MOVE_QUEUE_BY_ENTIRE", order)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // END OF CODE INTEGER
 | 
			
		||||
 | 
			
		||||
        for(var title of data.queue) {
 | 
			
		||||
 | 
			
		||||
            console.log(data.queue.indexOf(title) + " - " + title.title)
 | 
			
		||||
            
 | 
			
		||||
            const titleBtn = document.getElementById(data.queue.indexOf(title)+ "_ldelete")
 | 
			
		||||
            const moveBtn = document.getElementById(data.queue.indexOf(title)+ "_lmove")
 | 
			
		||||
            
 | 
			
		||||
            titleBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
                post("DELETE_QUEUE", titleBtn.id.replace("_ldelete", ""), data.queue[moveBtn.id.replace("_lmove", "")].title )
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            moveBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
                post("MOVE_QUEUE", moveBtn.id.replace("_lmove", ""))
 | 
			
		||||
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        listBox.innerHTML = '<p class="list_error">Lancez un titre et ajoutez vos morceaux ici !</p>'
 | 
			
		||||
        listNumber.classList.add("invisible")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
play.addEventListener('click', () => {
 | 
			
		||||
 | 
			
		||||
    get("PAUSE")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
document.body.onkeyup = function(e) {
 | 
			
		||||
 | 
			
		||||
    if ((e.key == " " ||
 | 
			
		||||
        e.code == "Space" ||      
 | 
			
		||||
        e.keyCode == 32) &&
 | 
			
		||||
        e.srcElement.localName != "input" && e.srcElement.localName != "textarea"   
 | 
			
		||||
    ) {
 | 
			
		||||
        play.click()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
backward.addEventListener('click', () => {
 | 
			
		||||
 | 
			
		||||
    get("BACKWARD")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
forward.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    get("FORWARD")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
volBox.classList.add("invisible")
 | 
			
		||||
listBox.classList.add("invisible")
 | 
			
		||||
 | 
			
		||||
list.addEventListener("click" , () => {
 | 
			
		||||
 | 
			
		||||
    volBox.classList.add("invisible")
 | 
			
		||||
 | 
			
		||||
    if(listBox.classList.contains('invisible')) {
 | 
			
		||||
        listBox.classList.remove("invisible")
 | 
			
		||||
      
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        listBox.classList.add("invisible")
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
vol.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    listBox.classList.add("invisible")
 | 
			
		||||
 | 
			
		||||
    if(volBox.classList.contains('invisible')) {
 | 
			
		||||
        volBox.classList.remove("invisible")
 | 
			
		||||
      
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        volBox.classList.add("invisible")
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
volRange.addEventListener("click", () => {
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    post("VOLUME", volRange.value)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
volRange.addEventListener("input", () => {
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
    volTxt.innerHTML = volRange.value + "%"
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
loop.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    get("LOOP")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
shuffle.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    get("SHUFFLE")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
disconnect.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    get("DISCONNECT")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
durationBar.addEventListener("change", () => {
 | 
			
		||||
 | 
			
		||||
    post("SEEK", durationBar.value)
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										312
									
								
								src/web/public/javascript/playlist.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,312 @@
 | 
			
		||||
function delPlayList(key) {
 | 
			
		||||
 | 
			
		||||
    post("DELETE_PLAYLIST", key)
 | 
			
		||||
    mainView.innerHTML = WelcomeContent
 | 
			
		||||
    playlistSelected = null
 | 
			
		||||
    playlistValue = null
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function playPlayList(key) {
 | 
			
		||||
 | 
			
		||||
    post("PLAY_PLAYLIST", key)
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sendPlayList(key) {
 | 
			
		||||
 | 
			
		||||
    const playlist_popup = document.getElementById("playlist_popup")
 | 
			
		||||
 | 
			
		||||
    if(playlist_popup) {
 | 
			
		||||
 | 
			
		||||
        get("USER_LIST").then(resp => {
 | 
			
		||||
 | 
			
		||||
            const userToPush = new Array()
 | 
			
		||||
 | 
			
		||||
            for(var user of resp) {
 | 
			
		||||
 | 
			
		||||
                userToPush.push(`<div id='${resp.indexOf(user)}' class="popup_line"><img src="${user.picture}"><div style="display: flex; flex-direction: column; justify-content: start; text-align: start;"><p class="INDEX_gbname">${user.global_name}</p><p class="INDEX_usrname">${user.username}</p></div></div>`)
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            playlist_popup.innerHTML = userToPush.join("")
 | 
			
		||||
            playlist_popup.style.width = '170px'
 | 
			
		||||
            playlist_popup.style.top = (yMousePos - 30) + "px"
 | 
			
		||||
            playlist_popup.style.left = (xMousePos - 165) + "px"
 | 
			
		||||
            playlist_popup.style.overflowY = "auto";
 | 
			
		||||
            playlist_popup.style.height = "250px"
 | 
			
		||||
            playlist_popup.classList.remove("invisible")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            playlist_popup.addEventListener("mouseleave", () => {
 | 
			
		||||
            
 | 
			
		||||
                playlist_popup.classList.add("invisible")
 | 
			
		||||
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            for(var user of resp) {
 | 
			
		||||
 | 
			
		||||
                const userElement = document.getElementById(resp.indexOf(user))
 | 
			
		||||
 | 
			
		||||
                userElement.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
                    playlist_popup.classList.add("invisible")
 | 
			
		||||
                    post("SEND_PLAYLIST", {key: key, dest: resp[userElement.id].id})
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
    
 | 
			
		||||
            //post("SEND_PLAYLIST", key, user.id)
 | 
			
		||||
    
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function loadPlaylist(key, value) {
 | 
			
		||||
 | 
			
		||||
    userLocation = "playlist"   
 | 
			
		||||
 | 
			
		||||
    var playlistToPush = new Array()
 | 
			
		||||
    var playlist_songs = new Array()
 | 
			
		||||
 | 
			
		||||
    playlistSelected = key
 | 
			
		||||
    playlistValue = value
 | 
			
		||||
 | 
			
		||||
    for(var title of value) {
 | 
			
		||||
 | 
			
		||||
            var PFormatduration = getTimeCode(title.duration)
 | 
			
		||||
 | 
			
		||||
            var thumbnail = title.thumbnail
 | 
			
		||||
    
 | 
			
		||||
            if(!thumbnail) {
 | 
			
		||||
 | 
			
		||||
                thumbnail = "/images/black-image.svg"
 | 
			
		||||
                        
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(title.duration == 9223372036854776000) {
 | 
			
		||||
 | 
			
		||||
                PFormatduration = "<i style='color: red;' class='fa-solid fa-circle'></i> LIVE"
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        playlist_songs.push('<div class="search_song"> <img class="search_thumbnail" src="' + thumbnail + '"><div class="search_titleSong"> <p class="search_title">' + title.title + '</p></div> <p>' + title.author + '</p><p>' + PFormatduration + '</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="INDEX_userPopup invisible" id="playlist_popup"></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 onclick="playPlayList(\''+ key +'\')" id="'+ key +'_playlistplay" class="primary"><i class="fas fa-play"></i><button onclick="sendPlayList(\''+ key +'\')" id="sendplaylist" class="list_upSong"><i class="fas fa-paper-plane"></i></button></button><button onclick="delPlayList(\''+ key +'\')" id="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", () => {
 | 
			
		||||
 | 
			
		||||
            post("ADD_SONG", value[add_to.id.replace("_padd", "")])
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        playNow.addEventListener("click", () => {
 | 
			
		||||
     
 | 
			
		||||
            post("ADD_SONG_NOW", value[add_to.id.replace("_padd", "")])
 | 
			
		||||
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        deleteBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
            deleteJustBefore = true
 | 
			
		||||
            post("DELETE_SONG_TO_PLAYLIST", {data: key, song: value[add_to.id.replace("_padd", "")]})
 | 
			
		||||
            
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function fp_play_playlist(key) {
 | 
			
		||||
    
 | 
			
		||||
    post("FP_PLAY_PLAYLIST", key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
socket.on("DO_UPDATE_PLAYLIST", () => {
 | 
			
		||||
 | 
			
		||||
    get("PLAYLIST")
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
get("PLAYLIST")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
socket.on("ANSWER/GET/PLAYLIST", (data) => {
 | 
			
		||||
    var contentToPush = new Array()
 | 
			
		||||
    var selectionData = new Array()
 | 
			
		||||
 | 
			
		||||
    contentToPush.push(`<p>Mes Playlists</p>`)
 | 
			
		||||
    contentToPush.push('<div id="createPlaylist" class="playlist_div"><i class="fa-solid fa-plus"></i> Créer une playlist</div>')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    for (const [key, value] of Object.entries(data)) {
 | 
			
		||||
 | 
			
		||||
        contentToPush.push('<div id="' + key + '_playlist" class="playlist_div checker"><img class="tile" src="/images/playlist-tile.svg"><p>' + key + '</p></div>')
 | 
			
		||||
        selectionData.push('<option style="color: black;">' + key +  '</option>')
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if(contentToPush.join("") == "") {
 | 
			
		||||
        
 | 
			
		||||
        playlistContent.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
 | 
			
		||||
    
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        playlistContent.innerHTML = contentToPush.join("")
 | 
			
		||||
        playlistAvailable = selectionData
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(playlistSelected && deleteJustBefore || playlistSelected && userLocation == "playlist") {
 | 
			
		||||
        deleteJustBefore = null
 | 
			
		||||
        loadPlaylist(playlistSelected, data[playlistSelected])   
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const [key, value] of Object.entries(data)) {
 | 
			
		||||
 | 
			
		||||
        const playlist_selector = document.getElementById(key + '_playlist')
 | 
			
		||||
 | 
			
		||||
        playlist_selector.addEventListener("click", () => {
 | 
			
		||||
            
 | 
			
		||||
            loadPlaylist(key, value) 
 | 
			
		||||
            userLocation = "playlist"         
 | 
			
		||||
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 addPlaylist = document.getElementById("createPlaylist")
 | 
			
		||||
    const addPlaylist_dialog = document.getElementById("createPlaylist_dialog")
 | 
			
		||||
    const addPlaylist_close = document.getElementById("createPlaylist_close")
 | 
			
		||||
    const apText = document.getElementById("apText")
 | 
			
		||||
    const apInfo = document.getElementById("apInfo")
 | 
			
		||||
    const apCreate = document.getElementById("apCreate")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    addPlaylist_close.addEventListener("click", () => {
 | 
			
		||||
        apInfo.innerHTML = ""
 | 
			
		||||
        addPlaylist_dialog.close()
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    addPlaylist.addEventListener("click", () => {
 | 
			
		||||
        
 | 
			
		||||
        apText.innerHTML = ""
 | 
			
		||||
        addPlaylist_dialog.showModal()
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    apCreate.addEventListener("click", () => {
 | 
			
		||||
        apInfo.innerHTML = ""
 | 
			
		||||
        var wrongName = true
 | 
			
		||||
 | 
			
		||||
        const refusedChar = ['\\','/' ,':' ,'*','?' ,'"','<','>','|']
 | 
			
		||||
 | 
			
		||||
            for(var char of refusedChar) {
 | 
			
		||||
 | 
			
		||||
                if(apText.value.includes(char)) {
 | 
			
		||||
                    wrongName = false
 | 
			
		||||
 | 
			
		||||
                } 
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        if(apText.value != "" && apText.value != " " && wrongName) {
 | 
			
		||||
 | 
			
		||||
            addPlaylist_dialog.close()
 | 
			
		||||
            post("CREATE_PLAYLIST", apText.value)
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            apInfo.innerHTML = "<span style='red'>Le nom n'est pas valide !</style>"
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
    
 | 
			
		||||
    console.log(data)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Current Playlist and Song 
 | 
			
		||||
 | 
			
		||||
const cPlaylistManager = document.getElementById("current_playlistManager")
 | 
			
		||||
const cplaylistManager_close = document.getElementById("current_playlistManager_close")
 | 
			
		||||
const cplaylistSelection = document.getElementById("current_playlistSelection")
 | 
			
		||||
const cplaylist_add_music = document.getElementById("current_playlist_add_music")
 | 
			
		||||
const cplaylist_add_img = document.getElementById("current_playlist_add_img")
 | 
			
		||||
const cplaylistAddSong = document.getElementById("current_playlistAddSong")
 | 
			
		||||
 | 
			
		||||
takeCurrent.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    if(currentSong != null) {
 | 
			
		||||
 | 
			
		||||
        var thumbnail = currentSong.thumbnail
 | 
			
		||||
 | 
			
		||||
        if(!thumbnail) {
 | 
			
		||||
 | 
			
		||||
            thumbnail = "/images/black-image.svg"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cPlaylistManager.showModal()
 | 
			
		||||
        cplaylist_add_music.innerHTML = currentSong.title
 | 
			
		||||
        cplaylist_add_img.src = thumbnail
 | 
			
		||||
        cplaylistSelection.innerHTML = playlistAvailable
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
cplaylistManager_close.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    cPlaylistManager.close()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
cplaylistAddSong.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
                        
 | 
			
		||||
    cPlaylistManager.close()
 | 
			
		||||
    post("ADD_SONG_TO_PLAYLIST", {data: cplaylistSelection.value , song: currentSong} )
 | 
			
		||||
    
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										100
									
								
								src/web/public/javascript/radios.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,100 @@
 | 
			
		||||
AlwaysRequest("ALL_RADIO", (resp) => {
 | 
			
		||||
    if(userLocation == "home") {
 | 
			
		||||
 | 
			
		||||
        const radio_list = document.getElementById("radio_list")
 | 
			
		||||
        const radioToPush = new Array()
 | 
			
		||||
    
 | 
			
		||||
        radioToPush.push("<p style='font-family: Gunship, sans-serif;'><i class='fa fa-radio'></i> Radio</p>")
 | 
			
		||||
        radioToPush.push(`
 | 
			
		||||
        <dialog class="report_dialog" id="radio_dialog">
 | 
			
		||||
                <div class="rlineclose">
 | 
			
		||||
                    <p class="rtitle"><i class="fa fa-radio"></i> Ajout d'une radio</p>
 | 
			
		||||
                    <button id="radio_close" class="report_close"><i class="fa-solid fa-xmark"></i></button>
 | 
			
		||||
                </div>
 | 
			
		||||
                <p id='radio_info' style='text-align: center; color: red;'></p>
 | 
			
		||||
    
 | 
			
		||||
                <div class="rcontent">
 | 
			
		||||
                    <p class="runder">URL</p>
 | 
			
		||||
                    <input type='text' id="radio_host">
 | 
			
		||||
                    <button id="radio_send" class="rsend"><i class="fa-solid fa-plus"></i> Ajouter</button>
 | 
			
		||||
                </div>
 | 
			
		||||
        </dialog>
 | 
			
		||||
    `)
 | 
			
		||||
    
 | 
			
		||||
       
 | 
			
		||||
    
 | 
			
		||||
        for(var title of resp ) {
 | 
			
		||||
    
 | 
			
		||||
            var thumbnail = title.thumbnail
 | 
			
		||||
            if(!thumbnail) {
 | 
			
		||||
       
 | 
			
		||||
               thumbnail = "/images/black-image.svg"
 | 
			
		||||
                               
 | 
			
		||||
             }
 | 
			
		||||
    
 | 
			
		||||
            radioToPush.push(`<div style='grid-template-columns: 0.5fr 7fr 1fr !important;' class="search_song"> <img style='width: 60px;height: 45px; margin-right: 10px;' src="${thumbnail}"><div class="search_titleSong"> <p class="search_title">${title.title} - ${title.author}</p></div><button id='${resp.indexOf(title)}_radio_pplay' class='primary'><i class='fa fa-play'></i></button></div>`)
 | 
			
		||||
    
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        if(userAdmin) {
 | 
			
		||||
    
 | 
			
		||||
            radioToPush.push(`
 | 
			
		||||
            <div id="radio_add" class="playlist_div"><i style='margin-right: 10px;' class='fa fa-plus'></i> Ajouter une radio</div>`)
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        radio_list.innerHTML = radioToPush.join("")
 | 
			
		||||
    
 | 
			
		||||
        if(userAdmin) {
 | 
			
		||||
    
 | 
			
		||||
            const radio_dialog = document.getElementById("radio_dialog")
 | 
			
		||||
            const radio_close = document.getElementById("radio_close")
 | 
			
		||||
            const radio_send = document.getElementById("radio_send")
 | 
			
		||||
            const radio_add = document.getElementById("radio_add")
 | 
			
		||||
            const radio_info = document.getElementById("radio_info")
 | 
			
		||||
            const radio_host = document.getElementById("radio_host")
 | 
			
		||||
        
 | 
			
		||||
            if(radio_add) {
 | 
			
		||||
                radio_add.addEventListener("click", () => {
 | 
			
		||||
                    radio_info.innerHTML = ""
 | 
			
		||||
                    radio_host.value = ""
 | 
			
		||||
                    radio_dialog.showModal()
 | 
			
		||||
                })
 | 
			
		||||
            
 | 
			
		||||
                radio_close.addEventListener("click", () => {
 | 
			
		||||
                    radio_info.innerHTML = ""
 | 
			
		||||
                    radio_dialog.close()
 | 
			
		||||
                })
 | 
			
		||||
            
 | 
			
		||||
                radio_send.addEventListener("click", () => {
 | 
			
		||||
                    if(radio_host.value != '') {
 | 
			
		||||
            
 | 
			
		||||
                        post("RADIO/ADD", radio_host.value)
 | 
			
		||||
                        radio_dialog.close()
 | 
			
		||||
                    } else {
 | 
			
		||||
                    
 | 
			
		||||
                        radio_info.innerHTML = "Remplissez une URL !"
 | 
			
		||||
                    }
 | 
			
		||||
            
 | 
			
		||||
                })
 | 
			
		||||
        
 | 
			
		||||
            }
 | 
			
		||||
    
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        for(var title of resp ) {
 | 
			
		||||
    
 | 
			
		||||
            const playBtn = document.getElementById(resp.indexOf(title) +'_radio_pplay')
 | 
			
		||||
        
 | 
			
		||||
            playBtn.addEventListener("click", () => {
 | 
			
		||||
    
 | 
			
		||||
                post("ADD_SONG_NOW", resp[playBtn.id.replace("_radio_pplay", "")])
 | 
			
		||||
    
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								src/web/public/javascript/report.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,18 @@
 | 
			
		||||
 | 
			
		||||
reportBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    report_desc.value = ""
 | 
			
		||||
    report_level.value = "Majeur"
 | 
			
		||||
    report_dialog.showModal()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
report_close.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    report_dialog.close()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
report_send.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    post("REPORT", {"level":report_level.value, "desc": report_desc.value})
 | 
			
		||||
    report_dialog.close()
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										214
									
								
								src/web/public/javascript/search.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,214 @@
 | 
			
		||||
 | 
			
		||||
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", () => {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
        post("SEARCH", searchBar.value).then(answerOfResult => {
 | 
			
		||||
            
 | 
			
		||||
            var results = answerOfResult.results
 | 
			
		||||
            var playlistReconnised = answerOfResult.playlist
 | 
			
		||||
 | 
			
		||||
            if(searchBar.value.includes("https://") || searchBar.value.includes("http://")) {
 | 
			
		||||
 | 
			
		||||
                searchBar.value= ""
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(!playlistReconnised) {
 | 
			
		||||
 | 
			
		||||
            if(results.tracks != null) {
 | 
			
		||||
                const data = results.tracks
 | 
			
		||||
             
 | 
			
		||||
                console.log(data)
 | 
			
		||||
                var contentToPush = new Array()
 | 
			
		||||
        
 | 
			
		||||
                for(var title of data) {
 | 
			
		||||
                    
 | 
			
		||||
                   
 | 
			
		||||
 | 
			
		||||
                    var thumbnail = title.thumbnail
 | 
			
		||||
    
 | 
			
		||||
                    if(!thumbnail) {
 | 
			
		||||
 | 
			
		||||
                        thumbnail = "/images/black-image.svg"
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    
 | 
			
		||||
                    var PFormatduration = getTimeCode(title.duration)
 | 
			
		||||
 | 
			
		||||
                    if(title.duration == 9223372036854776000) {
 | 
			
		||||
 | 
			
		||||
                        PFormatduration = "<i style='color: red;' class='fa-solid fa-circle'></i> LIVE"
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    contentToPush.push(' <div class="search_song"> <img class="search_thumbnail" src="' + thumbnail + '"><div class="search_titleSong"> <p class="search_title">' + title.title + '</p></div> <p>' + title.author + '</p><p>' + PFormatduration + '</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) +'_goPlaylist" class="INDEX_line"><i class="fa-regular fa-square-plus"></i> Ajouter à une playlist</div><div id="' + data.indexOf(title) +'_copy" class="INDEX_line"><i class="fa-regular fa-copy"></i> Copier le lien</div></div></div><dialog id="' +  data.indexOf(title) + 'playlistManager" class="report_dialog"><div class="rlineclose"><p class="rtitle"><i class="fa fa-square-plus"></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 copy = document.getElementById(data.indexOf(title) + "_copy")
 | 
			
		||||
                    const addPlaylist = document.getElementById(data.indexOf(title) + "_goPlaylist")  
 | 
			
		||||
 | 
			
		||||
                    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")
 | 
			
		||||
 | 
			
		||||
                    var thumbnail = data[add_to.id.replace("_ladd", "")].thumbnail
 | 
			
		||||
    
 | 
			
		||||
                    if(!thumbnail) {
 | 
			
		||||
 | 
			
		||||
                        thumbnail = "/images/black-image.svg"
 | 
			
		||||
                    }
 | 
			
		||||
                  
 | 
			
		||||
                    testPopup.style.display = "none"
 | 
			
		||||
    
 | 
			
		||||
                    add_to.addEventListener("click", () => {
 | 
			
		||||
    
 | 
			
		||||
                        post("ADD_SONG", data[add_to.id.replace("_ladd", "")])
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                    copy.addEventListener("click", () => {
 | 
			
		||||
                        navigator.clipboard.writeText(data[add_to.id.replace("_ladd", "")].uri)
 | 
			
		||||
                        testPopup.style.display = "none"
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                    addPlaylist.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
                        PlaylistManager.showModal()
 | 
			
		||||
                        playlist_add_music.innerHTML = data[add_to.id.replace("_ladd", "")].title
 | 
			
		||||
                        playlist_add_img.src = thumbnail
 | 
			
		||||
                        playlistSelection.innerHTML = playlistAvailable
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                    playlistManager_close.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
                        PlaylistManager.close()
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                    playlistAddSong.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
                        
 | 
			
		||||
                        PlaylistManager.close()
 | 
			
		||||
                    
 | 
			
		||||
                        post("ADD_SONG_TO_PLAYLIST", {data: playlistSelection.value , song: 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", () => {
 | 
			
		||||
    
 | 
			
		||||
                        post("ADD_SONG_NOW", data[add_to.id.replace("_ladd", "")])
 | 
			
		||||
    
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                  
 | 
			
		||||
        
 | 
			
		||||
                   
 | 
			
		||||
                }
 | 
			
		||||
               
 | 
			
		||||
        
 | 
			
		||||
            } else {
 | 
			
		||||
        
 | 
			
		||||
                searchcontent.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
 | 
			
		||||
        
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                //https://www.youtube.com/playlist?list=PLA8VHLKYzqTvCcIKhsjGS41nG1zBpRZPy
 | 
			
		||||
       
 | 
			
		||||
                
 | 
			
		||||
                var playlistToPush = new Array()
 | 
			
		||||
                var playlist_songs = new Array()
 | 
			
		||||
        
 | 
			
		||||
            
 | 
			
		||||
                for(var title of results.videos) {
 | 
			
		||||
            
 | 
			
		||||
                        var PFormatduration = getTimeCode(title.milis_length)
 | 
			
		||||
 | 
			
		||||
                        if(title.milis_length == 9223372036854776000) {
 | 
			
		||||
 | 
			
		||||
                            PFormatduration = "<i style='color: red;' class='fa-solid fa-circle'></i> LIVE"
 | 
			
		||||
                        }
 | 
			
		||||
            
 | 
			
		||||
            
 | 
			
		||||
                    playlist_songs.push('<div class="search_song"> <img class="search_thumbnail" src="' + title.thumbnail_url + '"><div class="search_titleSong"> <p class="search_title">' + title.title + '</p></div> <p>' + title.author.name + '</p><p>' + PFormatduration + '</p> <div class="search_buttons"><button id="' + results.videos.indexOf(title) +  '_padd" class="search_add"><i class="fa fa-plus"></i></button><button id="' + results.videos.indexOf(title) +  '_pplay" class="search_lmore"><i class="fa fa-play"></i></button></div></div>')
 | 
			
		||||
            
 | 
			
		||||
                }
 | 
			
		||||
            
 | 
			
		||||
                playlistToPush.push('<div class="apPres"><div class="apTitle"><img style="width: 20%" class="" src="' +results.thumbnail_url + '"><div style=""><p style="margin-left: 2% !important;">' + results.author.name + " - (" + results.videos.length + " titres)" +  '</p><p class="apName">' + results.title + '</p></div></div><div class="apButtons"><button  onclick="fp_play_playlist(\'' + results.url + '\')" id="'+ results.id +'_playlistplay" class="primary"><i class="fas fa-play"></i></button></div></div><hr>' + playlist_songs.join(""))
 | 
			
		||||
                
 | 
			
		||||
                if(playlistToPush.join("") == "") {
 | 
			
		||||
            
 | 
			
		||||
                    searchcontent.innerHTML = '<p class="error">Aucun morceau trouvé !</p>'
 | 
			
		||||
                
 | 
			
		||||
                } else {
 | 
			
		||||
            
 | 
			
		||||
                    searchcontent.innerHTML = playlistToPush.join("")
 | 
			
		||||
            
 | 
			
		||||
                    
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
                
 | 
			
		||||
                
 | 
			
		||||
                for(var title of results.videos) {
 | 
			
		||||
            
 | 
			
		||||
                    const add_to = document.getElementById(results.videos.indexOf(title) + "_padd")
 | 
			
		||||
                    const playNow = document.getElementById(results.videos.indexOf(title) + "_pplay")
 | 
			
		||||
                    
 | 
			
		||||
            
 | 
			
		||||
                    add_to.addEventListener("click", () => {
 | 
			
		||||
            
 | 
			
		||||
                        post("FP_ADD_SONG", results.videos[add_to.id.replace("_padd", "")].url)
 | 
			
		||||
                    })
 | 
			
		||||
            
 | 
			
		||||
                    playNow.addEventListener("click", () => {
 | 
			
		||||
            
 | 
			
		||||
                        post("FP_ADD_SONG_NOW", results.videos[add_to.id.replace("_padd", "")].url)
 | 
			
		||||
            
 | 
			
		||||
                    })
 | 
			
		||||
            
 | 
			
		||||
                    
 | 
			
		||||
            
 | 
			
		||||
                
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
    
 | 
			
		||||
        }) 
 | 
			
		||||
    
 | 
			
		||||
    })
 | 
			
		||||
})
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
var wasOnNodes = false
 | 
			
		||||
 | 
			
		||||
settingsBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    wasOnHome = false
 | 
			
		||||
    
 | 
			
		||||
    mainView.innerHTML = `
 | 
			
		||||
    <div class="SETTINGS">
 | 
			
		||||
@@ -17,40 +15,53 @@ settingsBtn.addEventListener("click", () => {
 | 
			
		||||
    </div>
 | 
			
		||||
    `
 | 
			
		||||
 | 
			
		||||
    const settings_logs = document.getElementById("settings_logs")
 | 
			
		||||
    const settings_connexion = document.getElementById("settings_connexion")
 | 
			
		||||
    const settings_users = document.getElementById("settings_users")
 | 
			
		||||
    const settings_content = document.getElementById("settings_content")
 | 
			
		||||
    const settings_logs = getID("settings_logs")
 | 
			
		||||
    const settings_connexion = getID("settings_connexion")
 | 
			
		||||
    const settings_users = getID("settings_users")
 | 
			
		||||
    const settings_content = getID("settings_content")
 | 
			
		||||
 | 
			
		||||
    settings_logs.style.color = "white"
 | 
			
		||||
    loadLogs()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    settings_logs.addEventListener("click", () => {
 | 
			
		||||
        loadLogs()
 | 
			
		||||
        wasOnNodes = false
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    settings_connexion.addEventListener("click", () => {
 | 
			
		||||
        loadConnexion()
 | 
			
		||||
        wasOnNodes = true
 | 
			
		||||
      
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    settings_users.addEventListener("click", () => {
 | 
			
		||||
        loadUsers()
 | 
			
		||||
        wasOnNodes = false
 | 
			
		||||
      
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    settings_logs.style.color = "white"
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    function loadUsers() {
 | 
			
		||||
       
 | 
			
		||||
        socket.emit("GET/USERS")
 | 
			
		||||
        userLocation = "users"
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function loadConnexion() {
 | 
			
		||||
        
 | 
			
		||||
        userLocation = "nodes"
 | 
			
		||||
        socket.emit("GET/NODES")
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function loadLogs() {
 | 
			
		||||
        userLocation = "logs"
 | 
			
		||||
        settings_content.innerHTML = `
 | 
			
		||||
            <select id="logs_selection">
 | 
			
		||||
                <option>NOT CONNECTED</option>
 | 
			
		||||
                <option>Chargement en cours ...</option>
 | 
			
		||||
            </select>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div id="logs_content" class="logs_content">
 | 
			
		||||
@@ -60,8 +71,8 @@ settingsBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
        `
 | 
			
		||||
 | 
			
		||||
        const logs_selection = document.getElementById("logs_selection")
 | 
			
		||||
        const logs_content = document.getElementById("logs_content")
 | 
			
		||||
        const logs_selection = getID("logs_selection")
 | 
			
		||||
        const logs_content = getID("logs_content")
 | 
			
		||||
 | 
			
		||||
        const logs_data = get("LOGS")
 | 
			
		||||
 | 
			
		||||
@@ -82,7 +93,6 @@ settingsBtn.addEventListener("click", () => {
 | 
			
		||||
                    var logToPush = new Array()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        for(var line of log.value.split("\n")) {
 | 
			
		||||
 | 
			
		||||
                            line.toString()
 | 
			
		||||
@@ -143,34 +153,12 @@ settingsBtn.addEventListener("click", () => {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function loadConnexion() {
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        socket.emit("GET/NODES")
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const buttons = document.querySelectorAll(".sside_line");
 | 
			
		||||
 | 
			
		||||
    buttons.forEach(button => {
 | 
			
		||||
        button.addEventListener("click", function () {
 | 
			
		||||
            buttons.forEach(btn => {
 | 
			
		||||
                if (btn === button) {
 | 
			
		||||
                    btn.style.color = "white";
 | 
			
		||||
                } else {
 | 
			
		||||
                    btn.style.color = "";
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
socket.on("ALWAYS/USERS",(data) => {
 | 
			
		||||
AlwaysRequest('USERS',(data) => {
 | 
			
		||||
 | 
			
		||||
    const settings_content = document.getElementById("settings_content")
 | 
			
		||||
    const settings_content = getID("settings_content")
 | 
			
		||||
 | 
			
		||||
    if(settings_content) {
 | 
			
		||||
 | 
			
		||||
@@ -182,12 +170,8 @@ socket.on("ALWAYS/USERS",(data) => {
 | 
			
		||||
    
 | 
			
		||||
            var admin_bar = ''
 | 
			
		||||
    
 | 
			
		||||
            if(user.beta == true) {
 | 
			
		||||
            
 | 
			
		||||
                admin_bar = "<div><p>BETA</p></div>"
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            userToPush.push("<div class='set_user'><div class='set_user_info'><img src='https://cdn.discordapp.com/avatars/" + user.user.id + "/" + user.user.avatar + "'><div style='display: flex; flex-direction: column; justify-content: center;'><p class='INDEX_gbname'>" + user.user.global_name + "</p><p class='INDEX_usrname'>" + user.user.username + "</p></div>" + admin_bar + "</div><div style='font-size: 25px;'><button id='" + data.indexOf(user) +  "_uadmin' style='margin: 0 !important;' class='list_upSong'><i class='fa fa-star'></i></button><button id='" + data.indexOf(user) +  "_udelete' class='list_delete'><i class='fa fa-trash'></i></button></div></div>")
 | 
			
		||||
            userToPush.push("<div class='set_user'><div class='set_user_info'><img src='" + user.picture + "'><div style='display: flex; flex-direction: column; justify-content: center;'><p class='INDEX_gbname'>" + user.user.global_name + "</p><p class='INDEX_usrname'>" + user.user.username + "</p></div>" + admin_bar + "</div><div style='font-size: 25px;'><button id='" + data.indexOf(user) +  "_uadmin' style='margin: 0 !important;' class='list_upSong'><i class='fa fa-star'></i></button><button id='" + data.indexOf(user) +  "_udelete' class='list_delete'><i class='fa fa-trash'></i></button></div></div>")
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
@@ -200,8 +184,8 @@ socket.on("ALWAYS/USERS",(data) => {
 | 
			
		||||
        for(var user of data) {
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
            let adminBtn = document.getElementById(data.indexOf(user) + "_uadmin")
 | 
			
		||||
            let deleteBtn = document.getElementById(data.indexOf(user) + "_udelete") 
 | 
			
		||||
            let adminBtn = getID(data.indexOf(user) + "_uadmin")
 | 
			
		||||
            let deleteBtn = getID(data.indexOf(user) + "_udelete") 
 | 
			
		||||
    
 | 
			
		||||
            if(data[adminBtn.id.replace("_uadmin", "")].admin == true) {
 | 
			
		||||
    
 | 
			
		||||
@@ -212,7 +196,7 @@ socket.on("ALWAYS/USERS",(data) => {
 | 
			
		||||
    
 | 
			
		||||
            adminBtn.addEventListener("click", () => { 
 | 
			
		||||
    
 | 
			
		||||
                send("USERS/ADMIN", data[adminBtn.id.replace("_uadmin", "")])
 | 
			
		||||
                post("USERS/ADMIN", data[adminBtn.id.replace("_uadmin", "")])
 | 
			
		||||
    
 | 
			
		||||
                socket.emit("GET/USERS")
 | 
			
		||||
            })
 | 
			
		||||
@@ -220,7 +204,7 @@ socket.on("ALWAYS/USERS",(data) => {
 | 
			
		||||
            deleteBtn.addEventListener("click", () => {
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
                send("USERS/DELETE", data[adminBtn.id.replace("_uadmin", "")])
 | 
			
		||||
                post("USERS/DELETE", data[adminBtn.id.replace("_uadmin", "")])
 | 
			
		||||
    
 | 
			
		||||
                socket.emit("GET/USERS")
 | 
			
		||||
            })
 | 
			
		||||
@@ -234,11 +218,11 @@ socket.on("ALWAYS/USERS",(data) => {
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
socket.on("ALWAYS/NODES",(data) => {
 | 
			
		||||
AlwaysRequest("NODES",(data) => {
 | 
			
		||||
 | 
			
		||||
    const settings_content = document.getElementById("settings_content")
 | 
			
		||||
    const settings_content = getID("settings_content")
 | 
			
		||||
 | 
			
		||||
    if(settings_content && wasOnNodes) {
 | 
			
		||||
    if(settings_content && userLocation == "nodes") {
 | 
			
		||||
 | 
			
		||||
        var dataToPush = new Array()
 | 
			
		||||
 | 
			
		||||
@@ -299,14 +283,14 @@ socket.on("ALWAYS/NODES",(data) => {
 | 
			
		||||
 | 
			
		||||
        settings_content.innerHTML = dataToPush.join("")
 | 
			
		||||
 | 
			
		||||
        const an_dialog = document.getElementById("an_dialog")
 | 
			
		||||
        const an_close = document.getElementById("an_close")
 | 
			
		||||
        const an_add = document.getElementById("an_create")
 | 
			
		||||
        const an_host = document.getElementById("an_host")
 | 
			
		||||
        const an_port = document.getElementById("an_port")
 | 
			
		||||
        const an_password = document.getElementById("an_password")
 | 
			
		||||
        const an_send = document.getElementById("an_send")
 | 
			
		||||
        const an_info = document.getElementById("an_info")
 | 
			
		||||
        const an_dialog = getID("an_dialog")
 | 
			
		||||
        const an_close = getID("an_close")
 | 
			
		||||
        const an_add = getID("an_create")
 | 
			
		||||
        const an_host = getID("an_host")
 | 
			
		||||
        const an_port = getID("an_port")
 | 
			
		||||
        const an_password = getID("an_password")
 | 
			
		||||
        const an_send = getID("an_send")
 | 
			
		||||
        const an_info = getID("an_info")
 | 
			
		||||
 | 
			
		||||
        an_add.addEventListener("click", () => {
 | 
			
		||||
            an_info.innerHTML = ""
 | 
			
		||||
@@ -332,7 +316,7 @@ socket.on("ALWAYS/NODES",(data) => {
 | 
			
		||||
                    "retryAmount": 1
 | 
			
		||||
                }
 | 
			
		||||
    
 | 
			
		||||
                send("NODES/ADD", data)
 | 
			
		||||
                post("NODES/ADD", data)
 | 
			
		||||
    
 | 
			
		||||
                an_dialog.close()
 | 
			
		||||
 | 
			
		||||
@@ -348,18 +332,18 @@ socket.on("ALWAYS/NODES",(data) => {
 | 
			
		||||
 | 
			
		||||
        for(var node of data) {
 | 
			
		||||
 | 
			
		||||
            let reloadBtn = document.getElementById(data.indexOf(node) + "_reload")
 | 
			
		||||
            let deleteBtn = document.getElementById(data.indexOf(node) + "_delete") 
 | 
			
		||||
            let reloadBtn = getID(data.indexOf(node) + "_reload")
 | 
			
		||||
            let deleteBtn = getID(data.indexOf(node) + "_delete") 
 | 
			
		||||
            
 | 
			
		||||
            reloadBtn.addEventListener("click", () => {
 | 
			
		||||
                send("NODES/RELOAD", data[reloadBtn.id.replace("_reload", "")])
 | 
			
		||||
                post("NODES/RELOAD", data[reloadBtn.id.replace("_reload", "")])
 | 
			
		||||
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            deleteBtn.addEventListener("click", () => {
 | 
			
		||||
                console.log(deleteBtn)
 | 
			
		||||
                console.log(data[reloadBtn.id.replace("_reload", "")])
 | 
			
		||||
                send("NODES/DELETE", data[reloadBtn.id.replace("_reload", "")])
 | 
			
		||||
                post("NODES/DELETE", data[reloadBtn.id.replace("_reload", "")])
 | 
			
		||||
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										80
									
								
								src/web/public/javascript/tooltip.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,80 @@
 | 
			
		||||
const tooltip = document.getElementById("tooltip")
 | 
			
		||||
 | 
			
		||||
tooltip.style.visibility = 'hidden'
 | 
			
		||||
tooltip.style.display = 'none'
 | 
			
		||||
const alreadyDeclare = new Array()
 | 
			
		||||
 | 
			
		||||
const tooltip_list = {
 | 
			
		||||
    "radio_add": "Ajouter par l'URL",
 | 
			
		||||
    "sendplaylist": "Envoyer la playlist",
 | 
			
		||||
    "playlistplay": "Jouer la playlist",
 | 
			
		||||
    "playlistdelete": "Effacer la playlist",
 | 
			
		||||
    "an_create": "Ajouter un serveur",
 | 
			
		||||
    "pplay": "Jouer maintenant",
 | 
			
		||||
    "delete": "Supprimer",
 | 
			
		||||
    "add": "Ajouter à la liste de lecture",
 | 
			
		||||
    "backward": "Précédent",
 | 
			
		||||
    "forward": "Suivant",
 | 
			
		||||
    "lmore": "Plus d'options",
 | 
			
		||||
    "loop": "Répéter le titre",
 | 
			
		||||
    "shuffle": "Mélanger la liste de lecture",
 | 
			
		||||
    "list_btn": "Liste de lecture",
 | 
			
		||||
    "disconnect": "Déconnecter le bot",
 | 
			
		||||
    "reload": "Relancer le serveur",
 | 
			
		||||
    "admin": "Donner les permissions",
 | 
			
		||||
    "takeCurrent": "Ajouter le titre à une playlist",
 | 
			
		||||
    "volbtn": "Volume"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
document.onmousemove = function(e)
 | 
			
		||||
{
 | 
			
		||||
  xMousePos = e.clientX + window.scrollX;
 | 
			
		||||
  yMousePos = e.clientY + window.scrollY;
 | 
			
		||||
  
 | 
			
		||||
    for(var key in tooltip_list) {
 | 
			
		||||
    
 | 
			
		||||
        showToolTip(key, tooltip_list[key], e)
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function showToolTip(id, text, e) {
 | 
			
		||||
 | 
			
		||||
    if(e.target) {
 | 
			
		||||
        
 | 
			
		||||
        if(e.target.id.includes(id)) {
 | 
			
		||||
 | 
			
		||||
            if(!alreadyDeclare.includes(e.target.id)) {
 | 
			
		||||
                alreadyDeclare.push(e.target.id)
 | 
			
		||||
                const elementAssociate = document.getElementById(e.target.id)
 | 
			
		||||
 | 
			
		||||
                elementAssociate.addEventListener("mousemove", () => {
 | 
			
		||||
                    tooltip.style.visibility = 'visible'
 | 
			
		||||
                    tooltip.style.display = 'unset'
 | 
			
		||||
                    tooltip.style.top = ( yMousePos - ( tooltip.offsetHeight + 20)) + "px"
 | 
			
		||||
                    tooltip.style.width = "150px"
 | 
			
		||||
                    tooltip.style.left =(xMousePos - 75 )+ "px"
 | 
			
		||||
                    tooltip.innerHTML = text
 | 
			
		||||
    
 | 
			
		||||
                })
 | 
			
		||||
                    
 | 
			
		||||
                elementAssociate.addEventListener("mouseleave", () => {
 | 
			
		||||
 | 
			
		||||
                    
 | 
			
		||||
                    alreadyDeclare.splice(alreadyDeclare.indexOf(e.target.id), 1)
 | 
			
		||||
 | 
			
		||||
                    tooltip.style.visibility = 'hidden'
 | 
			
		||||
                    tooltip.style.display = 'none'
 | 
			
		||||
                    
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
            }        
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@@ -1266,3 +1266,29 @@ p {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.tile {
 | 
			
		||||
 | 
			
		||||
  width: 60px;
 | 
			
		||||
  height: 60px;
 | 
			
		||||
  margin-right: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.playlist_div p {
 | 
			
		||||
  display: flex !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#createPlaylist {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  gap: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#createPlaylist svg {
 | 
			
		||||
 | 
			
		||||
  font-size: 52px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.playlist-content p {
 | 
			
		||||
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										209
									
								
								src/web/public/stylesheets/style_new.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,209 @@
 | 
			
		||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300&display=swap');
 | 
			
		||||
@font-face {
 | 
			
		||||
    font-family: 'Gunship';
 | 
			
		||||
    src: url(gunship.ttf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html {
 | 
			
		||||
 | 
			
		||||
    min-height: 100%;
 | 
			
		||||
    min-width: 100%;
 | 
			
		||||
    margin: 0 !important;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
    background-color: #000000 !important;
 | 
			
		||||
    color: #ffffff !important;
 | 
			
		||||
    font-family: 'Inter', sans-serif !important;
 | 
			
		||||
    font-size: 20px;
 | 
			
		||||
    margin: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Window */
 | 
			
		||||
 | 
			
		||||
.window {
 | 
			
		||||
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.content {
 | 
			
		||||
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Title */
 | 
			
		||||
 | 
			
		||||
.title {
 | 
			
		||||
 | 
			
		||||
    color:white;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.title_logo {
 | 
			
		||||
 | 
			
		||||
    width: 80px;
 | 
			
		||||
    height: 80px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.title_text {
 | 
			
		||||
 | 
			
		||||
    font-size: 30px;
 | 
			
		||||
    font-family: 'Gunship', sans-serif;
 | 
			
		||||
    text-shadow: white 0px 0px 10px;
 | 
			
		||||
    user-select: none;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*Nav bar */
 | 
			
		||||
 | 
			
		||||
.navbar {
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Player */ 
 | 
			
		||||
 | 
			
		||||
.player_box {
 | 
			
		||||
 | 
			
		||||
    background-color: rgba(0, 0, 0);
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    padding: 1.5%;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 15vh;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.player_durationbar {
 | 
			
		||||
 | 
			
		||||
    margin-top: 1vh;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.player_middle {
 | 
			
		||||
 | 
			
		||||
    display: flex; 
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
.player_title {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    width: 30vw;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.player_actionbar {
 | 
			
		||||
    text-align: right;
 | 
			
		||||
    width: 30vw;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: end;
 | 
			
		||||
    gap: 0.8vw;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
.player_duration {
 | 
			
		||||
    width: 25vw;
 | 
			
		||||
    margin-right: 0.5vw;
 | 
			
		||||
    margin-left: 0.5vw;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Images */
 | 
			
		||||
 | 
			
		||||
.tile {
 | 
			
		||||
 | 
			
		||||
    width: 60px;
 | 
			
		||||
    height: 60px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Home */
 | 
			
		||||
 | 
			
		||||
.home_view {
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Playlist */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Notification */
 | 
			
		||||
 | 
			
		||||
.notif_div {
 | 
			
		||||
 | 
			
		||||
    visibility: hidden;
 | 
			
		||||
    width: 20%;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: -10%;
 | 
			
		||||
    right: 41%;
 | 
			
		||||
    transition: all 0.8s;
 | 
			
		||||
    z-index: 2;
 | 
			
		||||
    color: white;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    background-color: #2d2d2d;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .notif_image {
 | 
			
		||||
  
 | 
			
		||||
    width: 4vw;
 | 
			
		||||
    height: 4vw;
 | 
			
		||||
    margin-right: 3% !important;
 | 
			
		||||
  
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .notif_text {
 | 
			
		||||
  
 | 
			
		||||
      width: 100%;
 | 
			
		||||
      margin-right: 1% !important;
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
  
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .notif_div_on {
 | 
			
		||||
    transition: all 0.8s;
 | 
			
		||||
    top: 4% !important;
 | 
			
		||||
    visibility: visible;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Special */
 | 
			
		||||
 | 
			
		||||
.invisible {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
* {
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.grised {
 | 
			
		||||
 | 
			
		||||
    filter : invert(50%);
 | 
			
		||||
  
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .disabled {
 | 
			
		||||
  
 | 
			
		||||
    color: rgb(47, 47, 47) !important;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
@@ -2,12 +2,10 @@ var express = require('express');
 | 
			
		||||
var router = express.Router();
 | 
			
		||||
var path = require("path")
 | 
			
		||||
var auth = require("../../modules/sub-auth")
 | 
			
		||||
var log = require("../../modules/sub-log")
 | 
			
		||||
var log = require("loguix")
 | 
			
		||||
var { __glob } = require("../../modules/global-variables")
 | 
			
		||||
var uuid = require("uuid")
 | 
			
		||||
const metric = require("webmetrik")
 | 
			
		||||
metric.setMetricFile(__glob.METRIC_FILE)
 | 
			
		||||
metric.publishMetrics("8001", "raphraph")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var fs = require("fs")
 | 
			
		||||
@@ -51,7 +49,13 @@ router.get('/', function(req, res, next) {
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        var fileMd = md.render(fs.readFileSync(__glob.README).toString())
 | 
			
		||||
        res.render("index", {welcome: fileMd})
 | 
			
		||||
        if(process.env.DEV) {
 | 
			
		||||
            res.render("index", {welcome: fileMd, dev: "<p class='yellow'>DEVELOPEMENT</p>"})
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            res.render("index", {welcome: fileMd, dev: ""})
 | 
			
		||||
        }
 | 
			
		||||
     
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ var express = require('express');
 | 
			
		||||
var router = express.Router();
 | 
			
		||||
var path = require("path")
 | 
			
		||||
var auth = require("../../modules/sub-auth")
 | 
			
		||||
var log = require("../../modules/sub-log")
 | 
			
		||||
var log = require("loguix")
 | 
			
		||||
var uuid = require("uuid")
 | 
			
		||||
var fs = require("fs");
 | 
			
		||||
const { __glob, __web } = require('../../modules/global-variables');
 | 
			
		||||
@@ -31,7 +31,12 @@ router.get('/redirect', function(req, res, next) {
 | 
			
		||||
                    
 | 
			
		||||
                    var user = data
 | 
			
		||||
                    const token = uuid.v4().toString()
 | 
			
		||||
                    user.token = token
 | 
			
		||||
                    if(typeof user.token != "object")  {
 | 
			
		||||
 | 
			
		||||
                        user.token = []
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    user.token.push(token)
 | 
			
		||||
                    auth.addUser(user)
 | 
			
		||||
 | 
			
		||||
                    res.cookie("token", token, { maxAge: 90000000000000, httpOnly: true })
 | 
			
		||||
@@ -51,11 +56,7 @@ router.get('/redirect', function(req, res, next) {
 | 
			
		||||
 | 
			
		||||
                        res.redirect('/login?error=MIGRATE_ACCOUNT_ONLY')
 | 
			
		||||
 | 
			
		||||
                    } else if(error == "NOT_IN_BETA") {
 | 
			
		||||
 | 
			
		||||
                        res.redirect('/login?error=NOT_IN_BETA')
 | 
			
		||||
                        
 | 
			
		||||
                    } else if(error == "NOT_IN_CLP") {
 | 
			
		||||
                    }  else if(error == "NOT_IN_CLP") {
 | 
			
		||||
 | 
			
		||||
                        res.redirect('/login?error=NOT_IN_CLP')
 | 
			
		||||
                        
 | 
			
		||||
@@ -92,11 +93,25 @@ router.get("/socketlink", (req,res,next) => {
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
router.get("/discordlink", (req,res,next) => {
 | 
			
		||||
    var discordlink = null
 | 
			
		||||
    if(process.env.DEV) {
 | 
			
		||||
 | 
			
		||||
        alog.log("Mode Developpeur Actif : Redirige vers LOCALHOST")
 | 
			
		||||
        discordlink = "https://discord.com/api/oauth2/authorize?client_id=1094727789682380922&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Finternal%2Fredirect&response_type=code&scope=identify%20guilds%20guilds.members.read" //DEV
 | 
			
		||||
    } else {
 | 
			
		||||
        discordlink = "https://discord.com/api/oauth2/authorize?client_id=1094727789682380922&redirect_uri=https%3A%2F%2Fsubsonics.raphix.fr%2Finternal%2Fredirect&response_type=code&scope=identify%20guilds%20guilds.members.read" //OFFICIEL
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    res.redirect(302, discordlink)
 | 
			
		||||
    
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
router.get("/logout", (req,res,next) => {
 | 
			
		||||
 | 
			
		||||
    if(auth.checkUser(req.cookies.token)) {
 | 
			
		||||
 | 
			
		||||
        auth.removeUser(req.cookies.token)
 | 
			
		||||
        auth.removeToken(req.cookies.token)
 | 
			
		||||
        res.clearCookie("token")
 | 
			
		||||
        res.redirect(302, "/login")
 | 
			
		||||
    } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ var express = require('express');
 | 
			
		||||
var router = express.Router();
 | 
			
		||||
var path = require("path")
 | 
			
		||||
var auth = require("../../modules/sub-auth")
 | 
			
		||||
var log = require("../../modules/sub-log")
 | 
			
		||||
var log = require("loguix")
 | 
			
		||||
var package = require('../../../package.json')
 | 
			
		||||
var uuid = require("uuid")
 | 
			
		||||
 | 
			
		||||
@@ -49,11 +49,6 @@ router.get('/', function(req, res, next) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(req.query.error == "NOT_IN_BETA") {
 | 
			
		||||
 | 
			
		||||
            error = "<p style='color:red; margin-bottom: 0.5vw !important;'>Demande à Raphix pour t'inscrire à la Beta !</p>"
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        res.render("login", {login: error, version: verInfo})
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -148,8 +148,19 @@
 | 
			
		||||
    
 | 
			
		||||
    <script src="/socket.io/socket.io.js"></script>
 | 
			
		||||
    <script src="/javascript/IO.js"></script>
 | 
			
		||||
    <script src="/javascript/__index_script.js"></script>
 | 
			
		||||
    <script src="/javascript/__settings_script.js"></script>
 | 
			
		||||
    <script src="/socket.io/socket.io.js"></script>
 | 
			
		||||
        <script src="/javascript/IO.js"></script>
 | 
			
		||||
        <script src="/javascript/basics.js"></script>
 | 
			
		||||
        <script src="/javascript/middle.js"></script>
 | 
			
		||||
        <script src="/javascript/indexscript.js"></script>
 | 
			
		||||
        <script src="/javascript/player.js"></script>
 | 
			
		||||
        <script src="/javascript/playlist.js"></script>
 | 
			
		||||
        <script src="/javascript/settings.js"></script>
 | 
			
		||||
        <script src="/javascript/search.js"></script>
 | 
			
		||||
        <script src="/javascript/tooltip.js"></script>
 | 
			
		||||
        <script src="/javascript/report.js"></script>
 | 
			
		||||
        <script src="/javascript/radios.js"></script>
 | 
			
		||||
 | 
			
		||||
    <script defer src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script>
 | 
			
		||||
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
 | 
			
		||||
</body>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										183
									
								
								src/web/templates/index_new.ejs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,183 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <link rel='stylesheet' href='/stylesheets/style.css'/>
 | 
			
		||||
    <title>Subsonics - Web</title>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
        <div class="window">
 | 
			
		||||
            <div class="navbar">
 | 
			
		||||
 | 
			
		||||
                <div class="title">
 | 
			
		||||
                    <img class="title_logo" src="/images/logo.svg">
 | 
			
		||||
                    <p class="title_text">Subsonics</p>
 | 
			
		||||
                </div>
 | 
			
		||||
               
 | 
			
		||||
                <div id="home_btn" class="selector checker">
 | 
			
		||||
                    
 | 
			
		||||
                    <p><i class="fa fa-home"></i> Accueil</p>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div id="search_btn" class="selector checker">
 | 
			
		||||
                    
 | 
			
		||||
                    <p><i class="fa fa-search"></i> Rechercher</p>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div id="settings_btn" class="selector checker">
 | 
			
		||||
                    
 | 
			
		||||
                    <p><i class="fa fa-gear"></i> Paramètres</p>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="playlist-content" id="playlist-content">
 | 
			
		||||
                <div id="userCard">
 | 
			
		||||
                        <div class="userCard" id="userInfo"></div>
 | 
			
		||||
                        <div class="popup" id="userPopup">
 | 
			
		||||
                            
 | 
			
		||||
                            <div id="reportBtn" class="popup_line"><i class="fa-solid fa-bug"></i> Rapport</div>
 | 
			
		||||
                            <div id="restartBtn" class="popup_line"><i class="fa-solid fa-power-off"></i> Redémarrer</div>
 | 
			
		||||
                            <a class="signout" href="/internal/logout"><i class="fa fa-sign-out " aria-hidden="true"></i> Déconnexion</a>
 | 
			
		||||
                        </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
        
 | 
			
		||||
            </div> 
 | 
			
		||||
            <div id="mainView" class="content">
 | 
			
		||||
                <div class="home_view">
 | 
			
		||||
                    <div class="home_changelog">
 | 
			
		||||
                        <%- welcome %>
 | 
			
		||||
                       
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="home_other">
 | 
			
		||||
                        <div id="website_list" class="home_online">
 | 
			
		||||
                     
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div id="radio_list" class="home_radio">
 | 
			
		||||
                           
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
       
 | 
			
		||||
       
 | 
			
		||||
                  
 | 
			
		||||
        <div class="player_box">
 | 
			
		||||
            <div class="player_title">
 | 
			
		||||
                <span id="music_img"><img class="player_title" src="/images/black-image.svg"></span>
 | 
			
		||||
                <span id="music_title" class="music_title"><p>Aucun titre joué</p></span>
 | 
			
		||||
                <%- dev %>
 | 
			
		||||
            </div>
 | 
			
		||||
      
 | 
			
		||||
            <div class="player_middle">
 | 
			
		||||
                <div class="playbar">
 | 
			
		||||
                    <button id="loop" class="icon"><i class="fa-solid fa-repeat"></i></button>
 | 
			
		||||
                    <button id="backward" class="icon"><i class="fas fa-step-backward"></i></button>
 | 
			
		||||
                    <button id="play" class="icon_play"><i class="fas fa-play"></i></button>
 | 
			
		||||
                    <button id="forward" class="icon"><i class="fas fa-step-forward"></i></button>
 | 
			
		||||
                    <button id="takeCurrent" class="icon"><i class="fa-regular fa-square-plus"></i></button>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="player_durationbar">
 | 
			
		||||
                    <p id="durationTextAct" class="durationText">0:00</p>
 | 
			
		||||
                    <input class="player_duration" id="duration" type="range" value="0" max="100">
 | 
			
		||||
                    <p id="durationTextTotal" class="durationText">0:00</p>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            
 | 
			
		||||
            <div class="player_actionbar">
 | 
			
		||||
                <button id="disconnect" class="icon-leave"><i class="fa fa-sign-out"></i></button>
 | 
			
		||||
                <div id="volDiv" class="volDiv">
 | 
			
		||||
                    <button id="volbtn" class="icon"><i class="fa fa-volume-up"></i></button>
 | 
			
		||||
                    <div id="volumeBox">
 | 
			
		||||
                        <input type="range" id="volumeInput"  >
 | 
			
		||||
                        <p id="volumeTxt">100%</p>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <button id="shuffle" class="icon"><i class="fa fa-shuffle"></i></button>
 | 
			
		||||
                <div id="listDiv" class="volume_div">
 | 
			
		||||
                    <button id="list_btn" class="list icon"><i class="fa fa-list-ol"></i><p class="number" id="listNumber"></p></button>
 | 
			
		||||
                    <div id="listBox">
 | 
			
		||||
                        
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
           
 | 
			
		||||
        </div>
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
        <!-- Dialogs -->
 | 
			
		||||
 | 
			
		||||
        <dialog id="createPlaylist_dialog" class="report_dialog">
 | 
			
		||||
            <div class="rlineclose">
 | 
			
		||||
                <p class="rtitle"><i class="fa fa-plus"></i> Créer une playlist</p>
 | 
			
		||||
                <button id="createPlaylist_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 id="apInfo"></p>
 | 
			
		||||
                <p>Nom de la playlist</p>
 | 
			
		||||
                <input type="text" id="apText">
 | 
			
		||||
                <button id="apCreate" class="btn"><i class="fa fa-plus"></i> Créer</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </dialog>
 | 
			
		||||
 | 
			
		||||
        <dialog class="report_dialog" id="report_dialog">
 | 
			
		||||
            <div class="rlineclose">
 | 
			
		||||
                <p class="rtitle"><i class="fa fa-bug"></i> Rapport de bug</p>
 | 
			
		||||
                <button id="report_close" class="report_close"><i class="fa-solid fa-xmark"></i></button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="rcontent">
 | 
			
		||||
                <p class="runder">Catégorie :</p>
 | 
			
		||||
                <select id="report_level">
 | 
			
		||||
                    <option>Majeur</option>
 | 
			
		||||
                    <option>Mineur</option>
 | 
			
		||||
                    <option>Suggestion</option>
 | 
			
		||||
                </select>
 | 
			
		||||
                <p class="runder">Description</p>
 | 
			
		||||
                <textarea id="report_desc"></textarea>
 | 
			
		||||
                <button id="report_send" class="btn"><i class="fa-solid fa-paper-plane"></i> Envoyer</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </dialog>
 | 
			
		||||
        <dialog id="current_playlistManager" class="report_dialog">
 | 
			
		||||
            <div class="rlineclose">
 | 
			
		||||
                <p class="rtitle"><i class="fa fa-list-ol"></i> Ajouter à une playlist</p>
 | 
			
		||||
                <button id="current_playlistManager_close" class="report_close"><i class="fa-solid fa-xmark"></i></button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="apContent"><img id="current_playlist_add_img" class="ppTile" src="/images/playlist-tile.svg">
 | 
			
		||||
                <p style="padding: 1%;" id="current_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="current_playlistSelection"></select>
 | 
			
		||||
                <button id="current_playlistAddSong" class="btn"><i class="fa fa-plus"></i> Ajouter</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </dialog>
 | 
			
		||||
 | 
			
		||||
        <!-- Tooltip -->
 | 
			
		||||
 | 
			
		||||
        <span id="tooltip" class="tooltip-text">Tooltip Text</span>
 | 
			
		||||
 | 
			
		||||
        <!-- Notification -->
 | 
			
		||||
 | 
			
		||||
        <div class="notif_div" id="notif">
 | 
			
		||||
            <img class="notif_image" id="notif_image" src="/images/playlist-tile.svg">
 | 
			
		||||
            <p class="notif_text" id="notif_text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. </p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <!-- Scripts -->
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
        <script src="/socket.io/socket.io.js"></script>
 | 
			
		||||
        <script src="/javascript/IO.js"></script>
 | 
			
		||||
        <script src="/javascript/basics.js"></script>
 | 
			
		||||
        <script src="/javascript/middle.js"></script>
 | 
			
		||||
        <script src="/javascript/indexscript.js"></script>
 | 
			
		||||
        <script src="/javascript/player.js"></script>
 | 
			
		||||
        <script src="/javascript/playlist.js"></script>
 | 
			
		||||
        <script src="/javascript/settings.js"></script>
 | 
			
		||||
        <script src="/javascript/search.js"></script>
 | 
			
		||||
        <script src="/javascript/tooltip.js"></script>
 | 
			
		||||
        <script src="/javascript/report.js"></script>
 | 
			
		||||
        <script src="/javascript/radios.js"></script>
 | 
			
		||||
 | 
			
		||||
        <script defer src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -21,9 +21,7 @@
 | 
			
		||||
        <div style="font-size: 12px;"><%- version %></div>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <script src="/socket.io/socket.io.js"></script>
 | 
			
		||||
    <script src="/javascript/IO.js"></script>
 | 
			
		||||
    <script src="/javascript/__login_script.js"></script>
 | 
			
		||||
    <script src="/javascript/login-script.js"></script>
 | 
			
		||||
    <script defer src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
 
 | 
			
		||||