299 lines
11 KiB
HTML
299 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>JSDoc: Source: channel.js</title>
|
||
|
||
<script src="scripts/prettify/prettify.js"> </script>
|
||
<script src="scripts/prettify/lang-css.js"> </script>
|
||
<!--[if lt IE 9]>
|
||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||
<![endif]-->
|
||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<div id="main">
|
||
|
||
<h1 class="page-title">Source: channel.js</h1>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<section>
|
||
<article>
|
||
<pre class="prettyprint source linenums"><code>/*Canopy - The next generation of stoner streaming software
|
||
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Affero General Public License as
|
||
published by the Free Software Foundation, either version 3 of the
|
||
License, or (at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Affero General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Affero General Public License
|
||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||
|
||
/**
|
||
* Class containing base code for the Canopy channel client.
|
||
*/
|
||
class channel{
|
||
/**
|
||
* Instantiates a new channel object
|
||
*/
|
||
constructor(){
|
||
//Establish connetion to the server via socket.io
|
||
this.connect();
|
||
//Define socket listeners
|
||
this.defineListeners();
|
||
|
||
/**
|
||
* Returns true once the ytEmbed API has loaded in from google (eww)
|
||
*/
|
||
this.ytEmbedAPILoaded = false;
|
||
|
||
/**
|
||
* Current connected channels name
|
||
*/
|
||
this.channelName = window.location.pathname.split('/c/')[1].split('/')[0];
|
||
|
||
/**
|
||
* Child Video Player object
|
||
*/
|
||
this.player = new player(this);
|
||
|
||
/**
|
||
* Child Chat Box Object
|
||
*/
|
||
this.chatBox = new chatBox(this);
|
||
|
||
/**
|
||
* Child User List Object
|
||
*/
|
||
this.userList = new userList(this);
|
||
|
||
/**
|
||
* Child Canopy Panel Object
|
||
*/
|
||
this.cPanel = new cPanel(this);
|
||
|
||
//Set defaults for any unset settings and run any required process steps for the current config
|
||
this.setDefaults(false, true);
|
||
|
||
//Freak out any weirdos who take a peek in the dev console for shits n gigs
|
||
console.log("👁️👄👁️ ℬℴ𝓊𝓃𝒿ℴ𝓊𝓇.");
|
||
}
|
||
|
||
/**
|
||
* Handles initial client connection
|
||
*/
|
||
connect(){
|
||
this.socket = io({
|
||
extraHeaders: {
|
||
//Include CSRF token
|
||
'x-csrf-token': utils.ajax.getCSRFToken()
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Defines network-related listeners
|
||
*/
|
||
defineListeners(){
|
||
this.socket.on("connect", () => {
|
||
document.title = `${this.channelName} - Connected`
|
||
});
|
||
|
||
this.socket.on("kick", async (data) => {
|
||
if(data.reason == "Invalid CSRF Token!"){
|
||
//Reload the CSRF token
|
||
await utils.ajax.reloadCSRFToken();
|
||
|
||
//Retry the connection
|
||
this.connect();
|
||
}else{
|
||
new canopyUXUtils.popup(`You have been ${data.type} from the channel for the following reason:<br>${data.reason}`);
|
||
}
|
||
});
|
||
|
||
this.socket.on("clientMetadata", this.handleClientInfo.bind(this));
|
||
|
||
this.socket.on("error", utils.ux.displayResponseError);
|
||
|
||
this.socket.on("queue", (data) => {
|
||
this.queue = new Map(data.queue);
|
||
});
|
||
|
||
this.socket.on("lock", (data) => {
|
||
this.queueLock = data.locked;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Handles initial client-metadata ingestion from server upon connection
|
||
* @param {Object} data - Data glob from server
|
||
*/
|
||
handleClientInfo(data){
|
||
//Ingest user data
|
||
this.user = data.user;
|
||
|
||
//Re-hydrate permission maps
|
||
this.user.permMap.site = new Map(data.user.permMap.site);
|
||
this.user.permMap.chan = new Map(data.user.permMap.chan);
|
||
|
||
//Tell the chatbox to handle client info
|
||
//should it have its own event listener instead? Guess it's a stylistic choice :P
|
||
this.chatBox.handleClientInfo(data);
|
||
|
||
//Store queue for use by the queue panel
|
||
this.queue = new Map(data.queue);
|
||
|
||
//Store queue lock status
|
||
this.queueLock = data.queueLock;
|
||
|
||
//For each chat held in the chat buffer
|
||
for(let chat of data.chatBuffer){
|
||
//Display the chat
|
||
this.chatBox.displayChat(chat);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Processes and applies default config on any unset settings
|
||
* @param {Boolean} force - Whether or not to forcefully reset already set settings
|
||
* @param {Boolean} processConfig - Whether or not to run the Process Config function once complete
|
||
*/
|
||
setDefaults(force = false, processConfig = false){
|
||
//Iterate through default config
|
||
for(let [key, value] of channel.defaultConfig){
|
||
//If the setting is unset or function was called forcefully
|
||
if(force || localStorage.getItem(key) == null){
|
||
//Set item from default map
|
||
localStorage.setItem(key, value);
|
||
}
|
||
|
||
//If we're running process steps for the config
|
||
if(processConfig){
|
||
//Process the current config value
|
||
this.processConfig(key, localStorage.getItem(key));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Run once every config change to ensure settings are properly set
|
||
* @param {String} key - Setting to change
|
||
* @param {*} value - Value to set setting to
|
||
*/
|
||
processConfig(key, value){
|
||
//Switch/case by config key
|
||
switch(key){
|
||
case 'ytPlayerType':
|
||
const embedScript = document.querySelector(".yt-embed-api");
|
||
//If the user is running the embedded player and we don't have en embed script loaded
|
||
if(value == 'embed' && embedScript == null){
|
||
//Find our footer
|
||
const footer = document.querySelector('footer');
|
||
|
||
//Create new script tag
|
||
const ytEmbedAPI = document.createElement('script');
|
||
//Link the iframe api from youtube
|
||
ytEmbedAPI.src = "https://www.youtube.com/iframe_api";
|
||
//set the iframe api script id
|
||
ytEmbedAPI.classList.add('yt-embed-api');
|
||
|
||
//Append the script tag to the top of the footer to give everything else access
|
||
footer.prepend(ytEmbedAPI);
|
||
//If we're not using the embed player but the script is loaded
|
||
}else if(embedScript != null){
|
||
//Pull all scripts since the main one might have pulled others
|
||
const scripts = document.querySelectorAll('script');
|
||
|
||
//Iterate through all script tags on the page
|
||
for(let script of scripts){
|
||
//If the script came from youtube
|
||
if(script.src.match(/youtube\.com|youtu\.be/)){
|
||
//Rip it out
|
||
script.remove();
|
||
}
|
||
}
|
||
}
|
||
|
||
//If the player or mediaHandler isn't loaded
|
||
if(this.player == null || this.player.mediaHandler == null){
|
||
//We're fuggin done here
|
||
return;
|
||
}
|
||
|
||
|
||
//Get current video
|
||
const nowPlaying = this.player.mediaHandler.nowPlaying;
|
||
|
||
//If we're playing a youtube video
|
||
if(nowPlaying != null && nowPlaying.type == 'yt'){
|
||
//Restart the video
|
||
this.player.start({media: nowPlaying});
|
||
}
|
||
|
||
//Stop while we're ahead
|
||
return;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Default channel config
|
||
*/
|
||
static defaultConfig = new Map([
|
||
["ytPlayerType","raw"]
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* Youtube iframe-embed API entry point
|
||
*/
|
||
function onYouTubeIframeAPIReady(){
|
||
//Set embed api to true
|
||
client.ytEmbedAPILoaded = true;
|
||
|
||
//Get currently playing item
|
||
const nowPlaying = client.player.mediaHandler.nowPlaying;
|
||
|
||
//If we're playing a youtube video and the official embeds are enabled
|
||
if(nowPlaying.type == 'yt' && localStorage.getItem('ytPlayerType') == "embed"){
|
||
//Restart the video now that the embed api has loaded
|
||
client.player.start({media: nowPlaying});
|
||
}
|
||
}
|
||
|
||
const client = new channel();</code></pre>
|
||
</article>
|
||
</section>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
<nav>
|
||
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="addURLPopup.html">addURLPopup</a></li><li><a href="cPanel.html">cPanel</a></li><li><a href="channel.html">channel</a></li><li><a href="chatBox.html">chatBox</a></li><li><a href="chatPostprocessor.html">chatPostprocessor</a></li><li><a href="commandPreprocessor.html">commandPreprocessor</a></li><li><a href="commandProcessor.html">commandProcessor</a></li><li><a href="defaultTitlesPopup.html">defaultTitlesPopup</a></li><li><a href="emotePanel.html">emotePanel</a></li><li><a href="hlsBase.html">hlsBase</a></li><li><a href="hlsLiveStreamHandler.html">hlsLiveStreamHandler</a></li><li><a href="mediaHandler.html">mediaHandler</a></li><li><a href="newPlaylistPopup.html">newPlaylistPopup</a></li><li><a href="nullHandler.html">nullHandler</a></li><li><a href="panelObj.html">panelObj</a></li><li><a href="player.html">player</a></li><li><a href="playlistManager.html">playlistManager</a></li><li><a href="poppedPanel.html">poppedPanel</a></li><li><a href="rawFileBase.html">rawFileBase</a></li><li><a href="rawFileHandler.html">rawFileHandler</a></li><li><a href="renamePopup.html">renamePopup</a></li><li><a href="settingsPanel.html">settingsPanel</a></li><li><a href="userList.html">userList</a></li><li><a href="youtubeEmbedHandler.html">youtubeEmbedHandler</a></li></ul><h3>Global</h3><ul><li><a href="global.html#onYouTubeIframeAPIReady">onYouTubeIframeAPIReady</a></li></ul>
|
||
</nav>
|
||
|
||
<br class="clear">
|
||
|
||
<footer>
|
||
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.4</a> on Fri Sep 05 2025 05:55:09 GMT-0400 (Eastern Daylight Time)
|
||
</footer>
|
||
|
||
<script> prettyPrint(); </script>
|
||
<script src="scripts/linenumber.js"> </script>
|
||
</body>
|
||
</html>
|