diff --git a/www/doc/client/addURLPopup.html b/www/doc/client/addURLPopup.html new file mode 100644 index 0000000..455b455 --- /dev/null +++ b/www/doc/client/addURLPopup.html @@ -0,0 +1,884 @@ + + + + + JSDoc: Class: addURLPopup + + + + + + + + + + +
+ +

Class: addURLPopup

+ + + + + + +
+ +
+ +

addURLPopup(event, playlist, location, client, doc)

+ +
Class representing pop-up dialogue which adds media to a given playlist
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new addURLPopup(event, playlist, location, client, doc)

+ + + + + + +
+ Instantiates a new Add URL Pop-up +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
playlist + + +String + + + + Playlist name
location + + +String + + + + Location of playlist, either Channel or User
client + + +channel + + + + Parent Client Management Object
doc + + +Document + + + + Current owner documnet of the panel, so we know where to drop our pop-up
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

client

+ + + + +
+ Parent Client Management Object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

location

+ + + + +
+ Location of playlist, either Channel or User +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

playlist

+ + + + +
+ Playlist Name +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ canopyUXUtils.popup() object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

addToPlaylist(event)

+ + + + + + +
+ Handles sending request to add to a playlist to the server +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

asyncConstructor()

+ + + + + + +
+ Continuation of object construction, called after child popup object construction +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

setupInput()

+ + + + + + +
+ Defines input-related Event Handlers +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/www/doc/client/cPanel.html b/www/doc/client/cPanel.html index 582e49c..e7c2e2d 100644 --- a/www/doc/client/cPanel.html +++ b/www/doc/client/cPanel.html @@ -2596,13 +2596,13 @@
diff --git a/www/doc/client/channel.html b/www/doc/client/channel.html index d5f9a33..0cbc821 100644 --- a/www/doc/client/channel.html +++ b/www/doc/client/channel.html @@ -1248,13 +1248,13 @@
diff --git a/www/doc/client/channel.js.html b/www/doc/client/channel.js.html index eb8ae9d..a14ea6c 100644 --- a/www/doc/client/channel.js.html +++ b/www/doc/client/channel.js.html @@ -283,13 +283,13 @@ const client = new channel();
diff --git a/www/doc/client/chat.js.html b/www/doc/client/chat.js.html index cf1f5f0..e426f71 100644 --- a/www/doc/client/chat.js.html +++ b/www/doc/client/chat.js.html @@ -284,8 +284,8 @@ class chatBox{ } /** - * Concatinate Text into Chat Prompt - * @param {String} text - Text to Concatinate + * Concatenate Text into Chat Prompt + * @param {String} text - Text to Concatenate */ catChat(text){ this.chatPrompt.value += text; @@ -656,13 +656,13 @@ L /**
diff --git a/www/doc/client/chatBox.html b/www/doc/client/chatBox.html index 255128e..6acfefd 100644 --- a/www/doc/client/chatBox.html +++ b/www/doc/client/chatBox.html @@ -1641,7 +1641,7 @@ Seems weird to stick this in here, but the split is dictated by chat width :P
- Concatinate Text into Chat Prompt + Concatenate Text into Chat Prompt
@@ -1693,7 +1693,7 @@ Seems weird to stick this in here, but the split is dictated by chat width :P - Text to Concatinate + Text to Concatenate @@ -4644,13 +4644,13 @@ Also prevents horizontal scroll-bars from chat/window resizing
diff --git a/www/doc/client/chatPostprocessor.html b/www/doc/client/chatPostprocessor.html index 4673ea7..5e8c99d 100644 --- a/www/doc/client/chatPostprocessor.html +++ b/www/doc/client/chatPostprocessor.html @@ -1788,13 +1788,13 @@ Internal command used by several text filters to prevent code re-writes
diff --git a/www/doc/client/chatPostprocessor.js.html b/www/doc/client/chatPostprocessor.js.html index ae4b63c..327294e 100644 --- a/www/doc/client/chatPostprocessor.js.html +++ b/www/doc/client/chatPostprocessor.js.html @@ -665,13 +665,13 @@ class chatPostprocessor{
diff --git a/www/doc/client/commandPreprocessor.html b/www/doc/client/commandPreprocessor.html index 99d9d3f..3192883 100644 --- a/www/doc/client/commandPreprocessor.html +++ b/www/doc/client/commandPreprocessor.html @@ -1906,13 +1906,13 @@
diff --git a/www/doc/client/commandPreprocessor.js.html b/www/doc/client/commandPreprocessor.js.html index 9e6a44c..4c0faee 100644 --- a/www/doc/client/commandPreprocessor.js.html +++ b/www/doc/client/commandPreprocessor.js.html @@ -365,13 +365,13 @@ class commandProcessor{
diff --git a/www/doc/client/commandProcessor.html b/www/doc/client/commandProcessor.html index e8bf2a6..212de38 100644 --- a/www/doc/client/commandProcessor.html +++ b/www/doc/client/commandProcessor.html @@ -415,13 +415,13 @@
diff --git a/www/doc/client/cpanel.js.html b/www/doc/client/cpanel.js.html index 8056e0a..1e7f6cb 100644 --- a/www/doc/client/cpanel.js.html +++ b/www/doc/client/cpanel.js.html @@ -509,13 +509,13 @@ class poppedPanel{
diff --git a/www/doc/client/defaultTitlesPopup.html b/www/doc/client/defaultTitlesPopup.html new file mode 100644 index 0000000..8738888 --- /dev/null +++ b/www/doc/client/defaultTitlesPopup.html @@ -0,0 +1,969 @@ + + + + + JSDoc: Class: defaultTitlesPopup + + + + + + + + + + +
+ +

Class: defaultTitlesPopup

+ + + + + + +
+ +
+ +

defaultTitlesPopup(event, playlist, titles, location, client, doc)

+ +
Class Representing popup dialogue for changing playlists defualt titles
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new defaultTitlesPopup(event, playlist, titles, location, client, doc)

+ + + + + + +
+ Instantiates a new Default Titles Popup +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
playlist + + +String + + + + Playlist name
titles + + +String + + + + List of titles, denoted by newlines
location + + +String + + + + Location of playlist, either Channel or User
client + + +channel + + + + Parent Client Management Object
doc + + +Document + + + + Current owner documnet of the panel, so we know where to drop our pop-up
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

client

+ + + + +
+ Parent Client Management Object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

location

+ + + + +
+ Location of playlist, either Channel or User +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

playlist

+ + + + +
+ Playlist Name +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ canopyUXUtils.popup() object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

titles

+ + + + +
+ Array of titles to set +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

asyncConstructor()

+ + + + + + +
+ Continuation of object construction, called after child popup object construction +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

changeDefaultTitles(event)

+ + + + + + +
+ Handles sending request to change default titles of playlist to the server +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

setupInput()

+ + + + + + +
+ Defines input-related Event Handlers +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/www/doc/client/emotePanel.html b/www/doc/client/emotePanel.html new file mode 100644 index 0000000..2f46149 --- /dev/null +++ b/www/doc/client/emotePanel.html @@ -0,0 +1,2258 @@ + + + + + JSDoc: Class: emotePanel + + + + + + + + + + +
+ +

Class: emotePanel

+ + + + + + +
+ +
+ +

emotePanel(client, panelDocument)

+ +
Class representing Emote Panel UX
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new emotePanel(client, panelDocument)

+ + + + + + +
+ Instantiates a new Panel Object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
client + + +channel + + + + Parent client Management Object
panelDocument + + +Document + + + + Panel Document
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + +

Extends

+ + + + + + + + + + + + + + + + + + + + +

Members

+ + + +

client

+ + + + +
+ Parent Client Management object +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

name

+ + + + +
+ Panel Name +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

ownerDoc

+ + + + +
+ Current root document panel doc lives within +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

pageURL

+ + + + +
+ Panel Default Page URL +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

panelDocument

+ + + + +
+ Panel Document +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

addPersonalEmote(event)

+ + + + + + +
+ Requests server to add emote to list of personal emotes +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down by event listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

closer()

+ + + + + + +
+ Called upon panel close/exit +
+ + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

deletePersonalEmote(name)

+ + + + + + +
+ Requests server to remove emote from list of personal emotes +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
name + + +String + + + + Name of emote to delete
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

docSwitch()

+ + + + + + +
+ Handles Document/Panel Changes +
+ + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async) getPage() → {String}

+ + + + + + +
+ Fetches panel page from the server +
+ + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Raw panel doc HTML +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

renderEmoteLists()

+ + + + + + +
+ Renders out emote list to panel document +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

renderEmotes(emoteList, container, personal)

+ + + + + + +
+ Renders out emotes to emote lists +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
emoteList + + +Array + + + + + + list of emotes to render
container + + +Node + + + + + + Container to render emotes out to
personal + + +Boolean + + + + + + false + + Denotes whether or not we're rendering personal emotes
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

setupInput()

+ + + + + + +
+ Defines input-related event handlers +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toggleChanEmotes(event)

+ + + + + + +
+ Toggles Channel emote display +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down by event listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toggleEmotes(icon, list)

+ + + + + + +
+ Toggles a specified emote list on or off +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
icon + + +Node + + + + Toggle Icon for given list
list + + +Node + + + + Emote list container to toggle
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

togglePersonalEmotes(event)

+ + + + + + +
+ Toggles Personal emote display +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down by event listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toggleSiteEmotes(event)

+ + + + + + +
+ Toggles Site emote display +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down by event listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

useEmote(emote)

+ + + + + + +
+ Concatenates specified emote into chat prompt input +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
emote + + +String + + + + Emote to concat into chat
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/www/doc/client/global.html b/www/doc/client/global.html index 281baf5..bbcbcd8 100644 --- a/www/doc/client/global.html +++ b/www/doc/client/global.html @@ -202,13 +202,13 @@
diff --git a/www/doc/client/hlsBase.html b/www/doc/client/hlsBase.html index 570794e..0993a4c 100644 --- a/www/doc/client/hlsBase.html +++ b/www/doc/client/hlsBase.html @@ -2913,13 +2913,13 @@
diff --git a/www/doc/client/hlsLiveStreamHandler.html b/www/doc/client/hlsLiveStreamHandler.html index be4378b..66a4430 100644 --- a/www/doc/client/hlsLiveStreamHandler.html +++ b/www/doc/client/hlsLiveStreamHandler.html @@ -2890,13 +2890,13 @@
diff --git a/www/doc/client/index.html b/www/doc/client/index.html index eefcca4..97ae9f8 100644 --- a/www/doc/client/index.html +++ b/www/doc/client/index.html @@ -81,13 +81,13 @@ This new codebase intends to solve the following issues with the current CyTube
diff --git a/www/doc/client/mediaHandler.html b/www/doc/client/mediaHandler.html index 64a1729..eeb014d 100644 --- a/www/doc/client/mediaHandler.html +++ b/www/doc/client/mediaHandler.html @@ -2695,13 +2695,13 @@
diff --git a/www/doc/client/mediaHandler.js.html b/www/doc/client/mediaHandler.js.html index d1d7982..3432101 100644 --- a/www/doc/client/mediaHandler.js.html +++ b/www/doc/client/mediaHandler.js.html @@ -829,13 +829,13 @@ class hlsLiveStreamHandler extends hlsBase{
diff --git a/www/doc/client/newPlaylistPopup.html b/www/doc/client/newPlaylistPopup.html new file mode 100644 index 0000000..e3951ca --- /dev/null +++ b/www/doc/client/newPlaylistPopup.html @@ -0,0 +1,714 @@ + + + + + JSDoc: Class: newPlaylistPopup + + + + + + + + + + +
+ +

Class: newPlaylistPopup

+ + + + + + +
+ +
+ +

newPlaylistPopup(event, client, doc)

+ +
Class representing pop-up dialogue for creating a new playlist
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new newPlaylistPopup(event, client, doc)

+ + + + + + +
+ Instantiates a New Playlist Popup +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
client + + +channel + + + + Parent Client Management Object
doc + + +Document + + + + Current owner documnet of the panel, so we know where to drop our pop-up
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

client

+ + + + +
+ Parent Client Management Object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ canopyUXUtils.popup() object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

asyncConstructor()

+ + + + + + +
+ Continuation of object construction, called after child popup object construction +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

createPlaylist(event)

+ + + + + + +
+ Sends request to create a playlist off to the server +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

setupInput()

+ + + + + + +
+ Defines input-related Event Handlers +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/www/doc/client/nullHandler.html b/www/doc/client/nullHandler.html index 6f54084..9c32ab7 100644 --- a/www/doc/client/nullHandler.html +++ b/www/doc/client/nullHandler.html @@ -2867,13 +2867,13 @@
diff --git a/www/doc/client/panelObj.html b/www/doc/client/panelObj.html index 114225a..67aa060 100644 --- a/www/doc/client/panelObj.html +++ b/www/doc/client/panelObj.html @@ -903,13 +903,13 @@
diff --git a/www/doc/client/panels_emotePanel.js.html b/www/doc/client/panels_emotePanel.js.html new file mode 100644 index 0000000..b1e68bf --- /dev/null +++ b/www/doc/client/panels_emotePanel.js.html @@ -0,0 +1,362 @@ + + + + + JSDoc: Source: panels/emotePanel.js + + + + + + + + + + +
+ +

Source: panels/emotePanel.js

+ + + + + + +
+
+
/*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 representing Emote Panel UX
+ * @extends panelObj
+ */
+class emotePanel extends panelObj{
+    /**
+     * Instantiates a new Panel Object
+     * @param {channel} client - Parent client Management Object
+     * @param {Document} panelDocument - Panel Document
+     */
+    constructor(client, panelDocument){
+        super(client, "Emote Palette", "/panel/emote", panelDocument);
+
+        this.client.socket.on("personalEmotes", this.renderEmoteLists.bind(this));
+    }
+
+    closer(){
+        this.client.socket.off("personalEmotes", this.renderEmoteLists.bind(this));
+    }
+
+    docSwitch(){
+        this.siteEmoteTitle = this.panelDocument.querySelector('#site-emotes-title');
+        this.chanEmoteTitle = this.panelDocument.querySelector('#chan-emotes-title');
+        this.personalEmoteTitle = this.panelDocument.querySelector('#personal-emotes-title');
+
+        this.siteEmoteToggle = this.panelDocument.querySelector('#site-emotes-toggle');
+        this.chanEmoteToggle = this.panelDocument.querySelector('#chan-emotes-toggle');
+        this.personalEmoteToggle = this.panelDocument.querySelector('#personal-emotes-toggle');
+
+        this.siteEmoteList = this.panelDocument.querySelector('#emote-panel-site-list');
+        this.chanEmoteList = this.panelDocument.querySelector('#emote-panel-chan-list');
+        this.personalEmoteSection = this.panelDocument.querySelector('#emote-panel-personal-section');
+        this.personalEmoteList = this.panelDocument.querySelector('#emote-panel-personal-list');
+
+        this.searchPrompt = this.panelDocument.querySelector('#emote-panel-search-prompt');
+
+        this.personalEmoteLinkPrompt = this.panelDocument.querySelector('#new-emote-link-input');
+        this.personalEmoteNamePrompt = this.panelDocument.querySelector('#new-emote-name-input');
+        this.personalEmoteAddButton = this.panelDocument.querySelector('#new-emote-button');
+
+        this.setupInput();
+
+        this.renderEmoteLists();
+    }
+
+    /**
+     * Defines input-related event handlers
+     */
+    setupInput(){
+        //Make sure to remove any event listeners in-case we moving an already instantiated panel
+        this.siteEmoteToggle.removeEventListener("click", this.toggleSiteEmotes.bind(this));
+        this.siteEmoteToggle.addEventListener("click", this.toggleSiteEmotes.bind(this));
+
+        this.chanEmoteToggle.removeEventListener("click", this.toggleChanEmotes.bind(this));
+        this.chanEmoteToggle.addEventListener("click", this.toggleChanEmotes.bind(this));
+
+        this.personalEmoteToggle.removeEventListener("click", this.togglePersonalEmotes.bind(this));
+        this.personalEmoteToggle.addEventListener("click", this.togglePersonalEmotes.bind(this));
+
+        this.siteEmoteTitle.removeEventListener("click", this.toggleSiteEmotes.bind(this));
+        this.siteEmoteTitle.addEventListener("click", this.toggleSiteEmotes.bind(this));
+
+        this.chanEmoteTitle.removeEventListener("click", this.toggleChanEmotes.bind(this));
+        this.chanEmoteTitle.addEventListener("click", this.toggleChanEmotes.bind(this));
+
+        this.personalEmoteTitle.removeEventListener("click", this.togglePersonalEmotes.bind(this));
+        this.personalEmoteTitle.addEventListener("click", this.togglePersonalEmotes.bind(this));
+
+        this.searchPrompt.removeEventListener('keyup', this.renderEmoteLists.bind(this));
+        this.searchPrompt.addEventListener('keyup', this.renderEmoteLists.bind(this));
+
+        this.personalEmoteAddButton.removeEventListener("click", this.addPersonalEmote.bind(this));
+        this.personalEmoteAddButton.addEventListener("click", this.addPersonalEmote.bind(this));
+    }
+
+    /**
+     * Toggles Site emote display
+     * @param {Event} event - Event passed down by event listener
+     */
+    toggleSiteEmotes(event){
+        this.toggleEmotes(this.siteEmoteToggle, this.siteEmoteList);
+    }
+
+    /**
+     * Toggles Channel emote display
+     * @param {Event} event - Event passed down by event listener
+     */
+    toggleChanEmotes(event){
+        this.toggleEmotes(this.chanEmoteToggle, this.chanEmoteList);
+    }
+
+    /**
+     * Toggles Personal emote display
+     * @param {Event} event - Event passed down by event listener
+     */
+    togglePersonalEmotes(event){
+        this.toggleEmotes(this.personalEmoteToggle, this.personalEmoteSection);
+    }
+
+    /**
+     * Toggles a specified emote list on or off
+     * @param {Node} icon - Toggle Icon for given list
+     * @param {Node} list - Emote list container to toggle
+     */
+    toggleEmotes(icon, list){
+        if(list.checkVisibility()){
+            icon.classList.replace('bi-caret-down-fill','bi-caret-left-fill');
+            list.style.display = 'none';
+        }else{
+            icon.classList.replace('bi-caret-left-fill', 'bi-caret-down-fill');
+            list.style.display = 'grid';
+        }
+    }
+
+    /**
+     * Concatenates specified emote into chat prompt input
+     * @param {String} emote - Emote to concat into chat
+     */
+    useEmote(emote){
+        //If we're using this from the active panel
+        if(this.client.cPanel.activePanel == this){
+            //Close it
+            this.client.cPanel.hideActivePanel();
+        }
+
+        //Add the emote to the chatbox prompt
+        this.client.chatBox.catChat(`[${emote}]`);
+    }
+
+    /**
+     * Requests server to add emote to list of personal emotes
+     * @param {Event} event - Event passed down by event listener
+     */
+    addPersonalEmote(event){
+        //Collect input
+        const name = this.personalEmoteNamePrompt.value;
+        const link = this.personalEmoteLinkPrompt.value;
+
+        //Empty out prompts
+        this.personalEmoteNamePrompt.value = '';
+        this.personalEmoteLinkPrompt.value = '';
+
+        //Send emote to server
+        this.client.socket.emit("addPersonalEmote", {name, link});
+    }
+
+    /**
+     * Requests server to remove emote from list of personal emotes
+     * @param {String} name - Name of emote to delete
+     */
+    deletePersonalEmote(name){
+        //send out delete
+        this.client.socket.emit('deletePersonalEmote', {name});
+    }
+
+    /**
+     * Renders out emote list to panel document
+     */
+    renderEmoteLists(){
+        //if we've initialized the search prompt (wont happen yet first run)
+        if(this.searchPrompt != null){
+            //Get the search value
+            var search = this.searchPrompt.value;
+        }
+
+        //pull emote lists from the command preprocessor
+        var siteEmotes = this.client.chatBox.commandPreprocessor.emotes.site;
+        var chanEmotes = this.client.chatBox.commandPreprocessor.emotes.chan;
+        var personalEmotes = this.client.chatBox.commandPreprocessor.emotes.personal;
+
+        //If we have a search bar and a search in the search bar 
+        if(search != null && search != ''){
+            //filter emote lists using the filterQuery function
+            siteEmotes = siteEmotes.filter(filterQuery);
+            chanEmotes = chanEmotes.filter(filterQuery);
+            personalEmotes = personalEmotes.filter(filterQuery);
+
+            function filterQuery(emote){
+                //return true for anyany case-insensitive matches
+                return (emote.name.toLowerCase().match(search.toLowerCase())) != null;
+            }
+        }
+
+        //render out the emote lists
+        this.renderEmotes(siteEmotes, this.siteEmoteList);
+        this.renderEmotes(chanEmotes, this.chanEmoteList);
+        this.renderEmotes(personalEmotes, this.personalEmoteList, true);
+    }
+
+    /**
+     * Renders out emotes to emote lists
+     * @param {Array} emoteList - list of emotes to render
+     * @param {Node} container - Container to render emotes out to
+     * @param {Boolean} personal - Denotes whether or not we're rendering personal emotes
+     */
+    renderEmotes(emoteList, container, personal = false){
+        //Clear out the container
+        container.innerHTML = '';
+
+        //If we have two or less emotes
+        if(emoteList.length <= 2){
+            //Set the container display to flex
+            container.style.display = 'flex';
+        //otherwise
+        }else{
+            //Set the container display to grid
+            container.style.display = 'grid';
+        }
+
+        //For each emote
+        emoteList.forEach((emote) => {
+            //Create div to hold emote span
+            const emoteDiv = document.createElement('div');
+            emoteDiv.classList.add('emote-panel-list-emote');
+
+            const emoteSpan = document.createElement('span');
+            emoteSpan.classList.add('emote-panel-list-emote');
+
+            //If we have a low emote count
+            if(emoteList.length <= 2){
+                //render them huuuuuge
+                emoteDiv.classList.add('emote-panel-list-big-emote');
+                emoteSpan.classList.add('emote-panel-list-big-emote');
+            }
+
+            //If the emote is an image
+            if(emote.type == 'image'){
+                //Create image node
+                var emoteMedia = document.createElement('img');
+            //if emote is a video
+            }else if(emote.type == 'video'){
+                //create video node
+                var emoteMedia = document.createElement('video');
+                //Set video properties
+                emoteMedia.autoplay = true;
+                emoteMedia.muted = true;
+                emoteMedia.controls = false;
+                emoteMedia.loop = true;
+            }
+
+            //set media link as source
+            emoteMedia.src = emote.link;
+            //Set media class
+            emoteMedia.classList.add('emote-list-media');
+
+            //if we have a low emote count
+            if(emoteList.length <= 2){
+                //render them huuuuuge
+                emoteMedia.classList.add('emote-list-big-media');
+            }
+
+
+            //Create paragraph tag
+            const emoteTitle = document.createElement('p');
+            //Set title class
+            emoteTitle.classList.add('emote-list-title');
+            //Set emote title
+            emoteTitle.textContent = utils.unescapeEntities(`[${emote.name}]`);
+
+            //if we're rendering personal emotes
+            if(personal){
+                //create span to hold trash icon
+                const trashSpan = document.createElement('span');
+                trashSpan.classList.add('emote-list-trash-icon');
+
+                //Create trash icon
+                const trashIcon = document.createElement('i');
+                trashIcon.classList.add('emote-list-trash-icon', 'bi-trash-fill');
+                trashIcon.id = `emote-list-trash-icon-${emote.name}`;
+
+                //add deletePersonalEmote event listener
+                trashIcon.addEventListener('click', ()=>{this.deletePersonalEmote(emote.name)});
+                
+                //Add trash icon to trash span
+                trashSpan.appendChild(trashIcon);
+
+                //append trash span to emote div
+                emoteDiv.appendChild(trashSpan);
+            }
+            
+            //Add the emote media to the emote span
+            emoteSpan.appendChild(emoteMedia);
+            //Add title paragraph node
+            emoteSpan.appendChild(emoteTitle);
+
+            //Add useEmote event listener
+            emoteSpan.addEventListener('click', ()=>{this.useEmote(emote.name)});
+
+            //Add emote span to the emote div
+            emoteDiv.appendChild(emoteSpan);
+
+            //Append the mote span to the emote list
+            container.appendChild(emoteDiv);
+        })
+    }
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/www/doc/client/panels_queuePanel_playlistManager.js.html b/www/doc/client/panels_queuePanel_playlistManager.js.html new file mode 100644 index 0000000..528bd61 --- /dev/null +++ b/www/doc/client/panels_queuePanel_playlistManager.js.html @@ -0,0 +1,989 @@ + + + + + JSDoc: Source: panels/queuePanel/playlistManager.js + + + + + + + + + + +
+ +

Source: panels/queuePanel/playlistManager.js

+ + + + + + +
+
+
/*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 representing Playlist Manager UX within the Queue Panel
+ */
+class playlistManager{
+
+    /**
+     * 
+     * @param {channel} client - Parent Client Management Object
+     * @param {Document} panelDocument - Panel Document
+     * @param {queuePanel} queuePanel - Parent Queue Panel Object
+     */
+    constructor(client, panelDocument, queuePanel){
+        /**
+         * Parent Client Management Object
+         */
+        this.client = client;
+        
+        /**
+         * Panel Document
+         */
+        this.panelDocument = panelDocument;
+        
+        /**
+         * Parent Queue Panel Object
+         */
+        this.queuePanel = queuePanel;
+        
+        /**
+         * Map of which playlists are open and which are not, for better refresh handling
+         */
+        this.openMap = {
+            Channel: new Map(),
+            User: new Map()
+        };
+
+        //Define Listeners
+        this.defineListeners();
+    }
+
+    /**
+     * Handles Network-Related Event Listeners
+     */
+    defineListeners(){
+        this.client.socket.on("chanPlaylists", this.renderChannelPlaylists.bind(this));
+        this.client.socket.on("userPlaylists", this.renderUserPlaylists.bind(this));
+    }
+
+    docSwitch(){
+        //Grab menus
+        this.channelPlaylistDiv = this.panelDocument.querySelector("#queue-channel-playlist-div");
+        this.userPlaylistDiv = this.panelDocument.querySelector("#queue-user-playlist-div");
+
+        //Grab controls
+        this.createPlaylistSpan = this.panelDocument.querySelector('#queue-add-playlist-span');
+        this.channelPlaylistLabel = this.panelDocument.querySelector('#queue-channel-playlist-span');
+        this.channelPlaylistCaret = this.panelDocument.querySelector('#queue-channel-playlist-toggle');
+        this.userPlaylistLabel = this.panelDocument.querySelector('#queue-user-playlist-span');
+        this.userPlaylistCaret = this.panelDocument.querySelector('#queue-user-playlist-toggle');
+
+        //Force playlist re-render to fix controls
+        this.client.socket.emit('getChannelPlaylists');
+        this.client.socket.emit('getUserPlaylists');
+
+        //Setup Input
+        this.setupInput();
+    }
+
+    /**
+     * Handles Input-Related Event Listeners
+     */
+    setupInput(){
+        this.createPlaylistSpan.addEventListener('click', (event)=>{new newPlaylistPopup(event, this.client, this.queuePanel.ownerDoc)})
+        this.channelPlaylistLabel.addEventListener('click', this.toggleChannelPlaylists.bind(this));
+        this.userPlaylistLabel.addEventListener('click', this.toggleUserPlaylists.bind(this));
+    }
+
+    /* queue control button functions */
+
+    /**
+     * Toggle Channel Playlists
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    toggleChannelPlaylists(event){
+        //If the div is hidden
+        if(this.channelPlaylistDiv.style.display == 'none'){
+            //Light up the button
+            this.channelPlaylistLabel.classList.add('positive');
+            //Flip the caret
+            this.channelPlaylistCaret.classList.replace('bi-caret-right-fill', 'bi-caret-down-fill');
+            //Show the div
+            this.channelPlaylistDiv.style.display = '';
+        }else{
+            //Unlight the button
+            this.channelPlaylistLabel.classList.remove('positive');
+            //Flip the caret
+            this.channelPlaylistCaret.classList.replace('bi-caret-down-fill', 'bi-caret-right-fill');
+            //Hide the div
+            this.channelPlaylistDiv.style.display = 'none';
+        }
+    }
+
+    /**
+     * Toggle User Playlists
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    toggleUserPlaylists(event){
+        //If the div is hidden
+        if(this.userPlaylistDiv.style.display == 'none'){
+            //Light up the button
+            this.userPlaylistLabel.classList.add('positive');
+            //Flip the caret
+            this.userPlaylistCaret.classList.replace('bi-caret-right-fill', 'bi-caret-down-fill');
+            //Show the div
+            this.userPlaylistDiv.style.display = '';
+        }else{
+            //Unlight the button
+            this.userPlaylistLabel.classList.remove('positive');
+            //Flip the caret
+            this.userPlaylistCaret.classList.replace('bi-caret-down-fill', 'bi-caret-right-fill');
+            //Hide the div
+            this.userPlaylistDiv.style.display = 'none';
+        }
+    }
+
+    /**
+     * Checks which playlists where open before a refresh and re-opens them
+     * @param {String} location - Whether or not we're dealing with user or channel playlists
+     */
+    checkOpenPlaylists(location){
+        //If open map is a string, indicating we just renamed a playlist with it's media open
+        if(typeof this.openMap[location] == 'string'){
+            //Create new map to hold status with the new name of the renamed playlist already added
+            this.openMap[location] = new Map([[this.openMap[location], true]]);
+        }else{
+            //Create new map to hold status
+            this.openMap[location] = new Map();
+        }
+
+        let mediaContainerDivs = [];
+
+        if(location == 'Channel'){
+            mediaContainerDivs = this.channelPlaylistDiv.querySelectorAll('.queue-playlist-media-container-div')
+        }else{
+            mediaContainerDivs = this.userPlaylistDiv.querySelectorAll('.queue-playlist-media-container-div')
+        }
+
+        //For each container Div rendered
+        for(let containerDiv of mediaContainerDivs){
+            //Set whether or not it's visible in the map
+            this.openMap[location].set(containerDiv.dataset['playlist'], (containerDiv.style.display != 'none'));
+        }
+    }
+
+    //Main playlist rendering functions
+    
+    /**
+     * Renders Channel Playlist list
+     * @param {Object} data - Data from server
+     */
+    renderChannelPlaylists(data){
+        //Check for open playlists
+        this.checkOpenPlaylists('Channel');
+
+        //Clear channel playlist div
+        this.channelPlaylistDiv.innerHTML = '';
+
+        //Append rendered playlists
+        this.channelPlaylistDiv.append(...this.renderPlaylists(data, 'Channel'));
+    }
+
+    /**
+     * Renders User Playlist list
+     * @param {Object} data - Data from server
+     */
+    renderUserPlaylists(data){
+        //Check for open playlists
+        this.checkOpenPlaylists('User');
+
+        //Clear channel playlist div
+        this.userPlaylistDiv.innerHTML = '';
+
+        //Append rendered playlists
+        this.userPlaylistDiv.append(...this.renderPlaylists(data, 'User'));
+    }
+
+    /**
+     * Render set of playlists out to Playlist Management Menu
+     * @param {Object} data - Data from server
+     * @param {String} location - Location to load from, either Channel or User
+     * @returns {Node} Rendered out playlist list
+     */
+    renderPlaylists(data, location){
+        const playlists = [];
+
+        //For every playlist sent down from the server
+        for(let playlistIndex in data){
+            //Get playlist from data
+            const playlist = data[playlistIndex];
+
+            //Create a new playlist div
+            const playlistDiv = document.createElement('div');
+            //Set it's class
+            playlistDiv.classList.add('queue-playlist-div');
+
+            //Create span to hold playlist entry line contents
+            const playlistSpan = document.createElement('span');
+            //Set classes
+            playlistSpan.classList.add('queue-playlist-span');
+
+            //If this isn't our first rodeo
+            if(playlistIndex != 0){
+                //make note
+                playlistSpan.classList.add('not-first');
+            }
+
+            //assemble playlist entry line
+            playlistSpan.append(
+                this.renderLabels(playlist, location),
+                this.renderControls(playlist, location)
+            );
+
+            //assemble playlist div
+            playlistDiv.append(
+                playlistSpan,
+                this.renderMedia(playlist, location),
+            );
+
+            //add playlist div to playlists array
+            playlists.push(playlistDiv);
+        }
+
+        return playlists;
+    }
+
+    //aux rendering functions
+    /**
+     * Renders Playlist labels
+     * @param {Object} playlist - Playlist from server to render label for
+     * @param {String} location - Location of playlist (Channel or User)
+     * @returns {Node} Rendered out playlist label
+     */
+    renderLabels(playlist, location){
+        //Create playlist label span
+        const playlistLabels = document.createElement('span');
+        //Set it's class
+        playlistLabels.classList.add('queue-playlist-labels-span');
+
+        //create playlist title span
+        const playlistTitleSpan = document.createElement('span');
+        //Set class
+        playlistTitleSpan.classList.add('queue-playlist-title-span', 'interactive');
+
+        //Create playlist title caret
+        const playlistTitleCaret = document.createElement('i');
+
+        //If this is supposed to be open
+        if(this.openMap[location].get(playlist.name)){
+            //Set class accordingly
+            playlistTitleSpan.classList.add('positive');
+            playlistTitleCaret.classList.add('bi-caret-down-fill');
+        //otherwise
+        }else{
+            //Set class accordingly
+            playlistTitleCaret.classList.add('bi-caret-right-fill');
+        }
+
+        //Create playlist title label
+        const playlistTitle = document.createElement('p');
+        //Set it's class
+        playlistTitle.classList.add('queue-playlist-title');
+        //Unescape Sanatized Enteties and safely inject as plaintext
+        playlistTitle.innerText = utils.unescapeEntities(playlist.name);
+
+        //Construct playlist title span
+        playlistTitleSpan.appendChild(playlistTitleCaret);
+        playlistTitleSpan.appendChild(playlistTitle);
+
+        //Create playlist count label
+        const playlistCount = document.createElement('p');
+        //Set it's class
+        playlistCount.classList.add('queue-playlist-count');
+        //List video count
+        playlistCount.innerText = `Count: ${playlist.media.length}`;
+
+        //Append items to playlist labels span
+        playlistLabels.appendChild(playlistTitleSpan);
+        playlistLabels.appendChild(playlistCount);
+
+        //Define input listeners
+        playlistTitleSpan.addEventListener('click', this.toggleMedia.bind(this));
+
+        return playlistLabels;
+    }
+
+    /**
+     * Renders out Playlist Controls
+     * @param {Object} playlist - Playlist from server to render label for
+     * @param {String} location - Location of playlist (Channel or User)
+     * @returns {Node} Rendered out playlist controls
+     */
+    renderControls(playlist, location){
+        //Create playlist control span
+        const playlistControls = document.createElement('span');
+        //Set it's class
+        playlistControls.classList.add('queue-playlist-control-span');
+        //Set dataset
+        playlistControls.dataset['playlist'] = playlist.name;
+        playlistControls.dataset['location'] = location;
+
+        //Create queue all button
+        const playlistQueueRandomButton = document.createElement('button');
+        //Set it's classes
+        playlistQueueRandomButton.classList.add('queue-playlist-queue-random-button', 'queue-playlist-control');
+        //Inject text content
+        playlistQueueRandomButton.textContent = 'Random';
+        //Set title
+        playlistQueueRandomButton.title = 'Queue Random Item from Playlist';
+
+        //Create queue all button
+        const playlistQueueAllButton = document.createElement('button');
+        //Set it's classes
+        playlistQueueAllButton.classList.add('queue-playlist-queue-all-button', 'queue-playlist-control', 'not-first');
+        //Inject text content
+        playlistQueueAllButton.textContent = 'All';
+        //Set title
+        playlistQueueAllButton.title = 'Queue Entire Playlist';
+
+        //Create add from URL button
+        const playlistAddURLButton = document.createElement('button');
+        //Set it's classes
+        playlistAddURLButton.classList.add('queue-playlist-add-url-button', 'queue-playlist-control', 'positive-button', 'not-first');
+        //Set Tile
+        playlistAddURLButton.title = 'Add To Playlist From URL'
+
+        //Create playlist icons (we're using two so we're putting them inside the button :P)
+        const playlistAddIcon = document.createElement('i');
+        const playlistLinkIcon = document.createElement('i');
+        //set classes
+        playlistAddIcon.classList.add('bi-plus-lg');
+        playlistLinkIcon.classList.add('bi-link-45deg');
+
+        //Append icons to URL button
+        playlistAddURLButton.appendChild(playlistAddIcon);
+        playlistAddURLButton.appendChild(playlistLinkIcon);
+
+        //Create default titles button
+        const playlistDefaultTitlesButton = document.createElement('button');
+        //Set classes
+        playlistDefaultTitlesButton.classList.add('queue-playlist-add-url-button', 'queue-playlist-control', 'bi-tags-fill', 'positive-button', 'not-first');               
+        //Set title
+        playlistDefaultTitlesButton.title = 'Change Default Titles'
+        //Set dataset
+        playlistDefaultTitlesButton.dataset['titles'] = JSON.stringify(playlist.defaultTitles);
+
+        //Create rename button
+        const playlistRenameButton = document.createElement('button');
+        //Set it's classes
+        playlistRenameButton.classList.add('queue-playlist-add-url-button', 'queue-playlist-control', 'bi-input-cursor-text', 'positive-button', 'not-first');
+        //Set title
+        playlistRenameButton.title = 'Rename Playlist'
+        
+        //Create delete button
+        const playlistDeleteButton = document.createElement('button');
+        //Set it's classes
+        playlistDeleteButton.classList.add('queue-playlist-delete-button', 'queue-playlist-control', 'danger-button', 'bi-trash-fill', 'not-first');
+        //Set title
+        playlistDeleteButton.title = 'Delete Playlist'
+
+        //Append items to playlist control span
+        playlistControls.append(
+            playlistQueueRandomButton,
+            playlistQueueAllButton,
+            playlistAddURLButton,
+            playlistDefaultTitlesButton,
+            playlistRenameButton,
+            playlistDeleteButton
+        );
+
+        //Define input event listeners
+        playlistAddURLButton.addEventListener('click', this.addURL.bind(this));
+        playlistDefaultTitlesButton.addEventListener('click', this.editDefaultTitles.bind(this));
+        playlistRenameButton.addEventListener('click', this.renamePlaylist.bind(this));
+        playlistQueueRandomButton.addEventListener('click', this.queueRandom.bind(this));
+        playlistQueueAllButton.addEventListener('click', this.queueAll.bind(this));
+        playlistDeleteButton.addEventListener('click', this.deletePlaylist.bind(this));
+
+        return playlistControls;
+    }
+
+    /**
+     * Renders media object out for an entire playlist
+     * @param {Object} playlist - Playlist from server to render label for
+     * @param {String} location - Location of playlist (Channel or User)
+     * @returns {Node} Rendered out playlist 
+     */
+    renderMedia(playlist, location){
+        //Create media container div
+        const mediaContainer = document.createElement('div');
+        //Set classes
+        mediaContainer.classList.add('queue-playlist-media-container-div');
+
+        //If the playlist wasn't set to open in the open map
+        if(!this.openMap[location].get(playlist.name)){
+            //Auto-hide media container
+            mediaContainer.style.display = 'none';
+        }
+
+        //Set dataset
+        mediaContainer.dataset['playlist'] = playlist.name;
+
+        for(let mediaIndex in playlist.media){
+            //Grab media object from playlist
+            const media = playlist.media[mediaIndex];
+
+            //Sanatize title text
+            const title = utils.unescapeEntities(media.title);
+
+            //Create media div
+            const mediaDiv = document.createElement('div');
+            //Set class
+            mediaDiv.classList.add('queue-playlist-media-div');
+            //Inject title
+            mediaDiv.title = title;
+
+            //If this isn't our first rodeo
+            if(mediaIndex != 0){
+                mediaDiv.classList.add('not-first');
+            }
+
+
+            //Create media title
+            const mediaTitle = document.createElement('p');
+            //Set class
+            mediaTitle.classList.add('queue-playlist-media-title');
+            //Inject text content
+            mediaTitle.innerText = title;
+
+            //Append items to media div
+            mediaDiv.append(
+                mediaTitle,
+                this.renderMediaControls(media, playlist, location)
+            );
+            
+            
+            //Append media div to media container
+            mediaContainer.appendChild(mediaDiv);
+        }
+
+        //return media container
+        return mediaContainer;
+    }
+
+    /**
+     * Renders controls out for a single media entry within a playlist
+     * @param {Object} media - Media object from playlist to render controls for
+     * @param {Object} playlist - Playlist from server to render label for
+     * @param {String} location - Location of playlist (Channel or User)
+     * @returns {Node} Rendered out playlist 
+     */
+    renderMediaControls(media, playlist, location){
+        //Create media control span
+        const mediaControlSpan = document.createElement('span');
+        //Set it's class
+        mediaControlSpan.classList.add('queue-playlist-media-control-span');
+        //Set dataset
+        mediaControlSpan.dataset['playlist'] = playlist.name;
+        mediaControlSpan.dataset['uuid'] = media.uuid;
+        mediaControlSpan.dataset['location'] = location;
+
+        //Create Queue Media icon
+        const queueMediaIcon = document.createElement('i');
+        //set class
+        queueMediaIcon.classList.add('queue-playlist-control', 'queue-playlist-media-queue-icon', 'bi-play-circle');
+        //Set title
+        queueMediaIcon.title = (`Queue '${media.title}'`);
+
+        //Create delete media icon
+        const deleteMediaIcon = document.createElement('i');
+        //set class
+        deleteMediaIcon.classList.add('queue-playlist-control', 'queue-playlist-media-delete-icon', 'danger-text', 'bi-trash-fill');
+        //Set title
+        deleteMediaIcon.title = `Delete '${media.title}' from playlist '${playlist.name}'`;
+
+        //Append items to media control span
+        mediaControlSpan.appendChild(queueMediaIcon);
+        mediaControlSpan.appendChild(deleteMediaIcon);
+
+        //Handle input event listeners
+        queueMediaIcon.addEventListener('click', this.queueMedia.bind(this));
+        deleteMediaIcon.addEventListener('click', this.deleteMedia.bind(this));
+
+        //Return media control span
+        return mediaControlSpan;
+    }
+
+    /**
+     * Toggle Media List
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    toggleMedia(event){
+        //Grab playlist title caret
+        const playlistTitleCaret = event.target.querySelector('i');
+        //I hope my mother doesn't see this next line, god I hate dot crawling...
+        const mediaContainer = event.target.parentNode.parentNode.nextElementSibling;
+
+        //If the div is hidden
+        if(mediaContainer.style.display == 'none'){
+            //Light up the button
+            event.target.classList.add('positive');
+            //Flip the caret
+            playlistTitleCaret.classList.replace('bi-caret-right-fill', 'bi-caret-down-fill');
+            //Show the div
+            mediaContainer.style.display = '';
+        }else{
+            //Unlight the button
+            event.target.classList.remove('positive');
+            //Flip the caret
+            playlistTitleCaret.classList.replace('bi-caret-down-fill', 'bi-caret-right-fill');
+            //Hide the div
+            mediaContainer.style.display = 'none';
+        }
+    }
+
+    /**
+     * Add URL to playlist
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    addURL(event){
+        new addURLPopup(
+            event, 
+            event.target.parentNode.dataset['playlist'],
+            event.target.parentNode.dataset['location'],
+            this.client,
+            this.queuePanel.ownerDoc
+        );
+    }
+
+    //playlist control functions
+
+    /**
+     * Sends request to server to edit default titles
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    editDefaultTitles(event){
+        new defaultTitlesPopup(
+            event,
+            event.target.parentNode.dataset['playlist'],
+            JSON.parse(event.target.dataset['titles']),
+            event.target.parentNode.dataset['location'],
+            this.client,
+            this.queuePanel.ownerDoc
+        );
+    }
+
+    /**
+     * Sends request to server to rename playlists
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    renamePlaylist(event){
+        new renamePopup(
+            event,
+            event.target.parentNode.dataset['playlist'],
+            this.client,
+            this.queuePanel.ownerDoc,
+            handleOpenedMedia.bind(this)
+        );
+
+        function handleOpenedMedia(newName){
+            //do an ugly dot crawl to get the media container div
+            const mediaContainer = event.target.parentNode.parentNode.nextElementSibling;
+
+            //If the media container is visible
+            if(mediaContainer.style.display != 'none'){
+                //Set openMap to new name indicating the new playlist has it's media opened
+                this.openMap[event.target.parentNode.dataset['location']] = newName;
+            }
+        }
+    }
+
+    /**
+     * Sends request to server to queue all playlist items
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    queueAll(event){
+        this.client.socket.emit(`queue${event.target.parentNode.dataset['location']}Playlist`, {playlist: event.target.parentNode.dataset['playlist']});
+    }
+
+    /**
+     * Sends request to server to queue a playlist item
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    queueMedia(event){
+        this.client.socket.emit(`queueFrom${event.target.parentNode.dataset['location']}Playlist`,{playlist: event.target.parentNode.dataset['playlist'], uuid: event.target.parentNode.dataset['uuid']});
+    }
+
+    /**
+     * Sends request to server to queue a random playlist item
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    queueRandom(event){
+        this.client.socket.emit(`queueRandomFrom${event.target.parentNode.dataset['location']}Playlist`,{playlist: event.target.parentNode.dataset['playlist']});
+    }
+
+    /**
+     * Sends request to server to delete a playlist
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    deletePlaylist(event){
+        this.client.socket.emit(`delete${event.target.parentNode.dataset['location']}Playlist`, {playlist: event.target.parentNode.dataset['playlist']});
+    }
+
+    /**
+     * Sends request to server to delete a playlist item
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    deleteMedia(event ){
+        this.client.socket.emit(`delete${event.target.parentNode.dataset['location']}PlaylistMedia`, {playlist: event.target.parentNode.dataset['playlist'], uuid: event.target.parentNode.dataset['uuid']});
+    }
+
+}
+
+/**
+ * Class representing pop-up dialogue for creating a new playlist
+ */
+class newPlaylistPopup{
+    /**
+     * Instantiates a New Playlist Popup
+     * @param {Event} event - Event passed down from Event Listener
+     * @param {channel} client - Parent Client Management Object
+     * @param {Document} doc - Current owner documnet of the panel, so we know where to drop our pop-up
+     */
+    constructor(event, client, doc){
+        /**
+         * Parent Client Management Object
+         */
+        this.client = client;
+
+        //Create media popup and call async constructor when done
+        //unfortunately we cant call constructors asyncronously, and we cant call back to this from super, so we can't extend this as it stands :(
+        /**
+         * canopyUXUtils.popup() object
+         */
+        this.popup = new canopyUXUtils.popup('/newPlaylist', true, this.asyncConstructor.bind(this), doc, false);
+    }
+
+    /**
+     * Continuation of object construction, called after child popup object construction
+     */
+    asyncConstructor(){
+        this.name = this.popup.contentDiv.querySelector('#queue-create-playlist-popup-name');
+        this.defaultTitles = this.popup.contentDiv.querySelector('#queue-create-playlist-popup-default-titles');
+        this.location = this.popup.contentDiv.querySelector('#queue-create-playlist-popup-location');
+        this.saveButton = this.popup.contentDiv.querySelector('#queue-create-playlist-popup-save');
+
+        this.setupInput();
+    }
+
+    /**
+     * Defines input-related Event Handlers
+     */
+    setupInput(){
+        //Setup input
+        this.saveButton.addEventListener('click', this.createPlaylist.bind(this));
+        this.popup.popupDiv.addEventListener('keydown', this.createPlaylist.bind(this));
+    }
+
+    /**
+     * Sends request to create a playlist off to the server
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    createPlaylist(event){
+        //If we clicked or hit enter
+        if(event.key == null || (event.key == "Enter" && this.defaultTitles !== this.popup.doc.activeElement)){
+
+            //Tell the server to create a new playlist
+            this.client.socket.emit(`create${this.location.value}Playlist`, {
+                playlist: this.name.value,
+                defaultTitles: this.defaultTitles.value.split('\n')
+            });
+
+            //Close the popup
+            this.popup.closePopup();
+        }
+    }
+}
+
+/**
+ * Class representing pop-up dialogue which adds media to a given playlist
+ */
+class addURLPopup{
+    /**
+     * Instantiates a new Add URL Pop-up
+     * @param {Event} event - Event passed down from Event Listener
+     * @param {String} playlist - Playlist name
+     * @param {String} location - Location of playlist, either Channel or User
+     * @param {channel} client - Parent Client Management Object
+     * @param {Document} doc - Current owner documnet of the panel, so we know where to drop our pop-up
+     */
+    constructor(event, playlist, location, client, doc){
+        /**
+         * Parent Client Management Object
+         */
+        this.client = client;
+
+        /**
+         * Playlist Name
+         */
+        this.playlist = playlist
+
+        /**
+         * Location of playlist, either Channel or User
+         */
+        this.location = location;
+
+        //Create media popup and call async constructor when done
+        //unfortunately we cant call constructors asyncronously, and we cant call back to this from super, so we can't extend this as it stands :(
+        /**
+         * canopyUXUtils.popup() object
+         */
+        this.popup = new canopyUXUtils.popup('/addToPlaylist', true, this.asyncConstructor.bind(this), doc);
+    }
+
+    /**
+     * Continuation of object construction, called after child popup object construction
+     */
+    asyncConstructor(){
+        this.urlPrompt = this.popup.contentDiv.querySelector('#playlist-add-media-popup-prompt');
+        this.addButton = this.popup.contentDiv.querySelector('#playlist-add-media-popup-button');
+
+        this.setupInput();
+    }
+
+    /**
+     * Defines input-related Event Handlers
+     */
+    setupInput(){
+        //Setup input
+        this.addButton.addEventListener('click', this.addToPlaylist.bind(this));
+        this.popup.popupDiv.addEventListener('keydown', this.addToPlaylist.bind(this));
+    }
+
+    /**
+     * Handles sending request to add to a playlist to the server
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    addToPlaylist(event){
+        //If we clicked or hit enter
+        if(event.key == null || event.key == "Enter"){
+
+            //Tell the server to add url to the playlist
+            this.client.socket.emit(`addTo${this.location}Playlist`, {
+            //this.client.socket.emit(`addToChannelPlaylist`, {
+                playlist: this.playlist,
+                url: this.urlPrompt.value
+            });
+
+            //Close the popup
+            this.popup.closePopup();
+        }
+    }
+}
+
+/**
+ * Class Representing popup dialogue for changing playlists defualt titles
+ */
+class defaultTitlesPopup{
+    /**
+     * Instantiates a new Default Titles Popup
+     * @param {Event} event - Event passed down from Event Listener
+     * @param {String} playlist - Playlist name
+     * @param {String} titles - List of titles, denoted by newlines
+     * @param {String} location - Location of playlist, either Channel or User
+     * @param {channel} client - Parent Client Management Object
+     * @param {Document} doc - Current owner documnet of the panel, so we know where to drop our pop-up
+     */
+    constructor(event, playlist, titles, location, client, doc){
+        /**
+         * Parent Client Management Object
+         */
+        this.client = client;
+
+        /**
+         * Playlist Name
+         */
+        this.playlist = playlist
+
+        /**
+         * Location of playlist, either Channel or User
+         */
+        this.location = location;
+
+        /**
+         * Array of titles to set
+         */
+        this.titles = titles.join('\n');
+
+        //Create media popup and call async constructor when done
+        //unfortunately we cant call constructors asyncronously, and we cant call back to this from super, so we can't extend this as it stands :(
+        /**
+         * canopyUXUtils.popup() object
+         */
+        this.popup = new canopyUXUtils.popup('/playlistDefaultTitles', true, this.asyncConstructor.bind(this), doc, false);
+    }
+
+    /**
+     * Continuation of object construction, called after child popup object construction
+     */
+    asyncConstructor(){
+        this.titlePrompt = this.popup.contentDiv.querySelector('#playlist-default-titles-popup-prompt');
+        this.titleButton = this.popup.contentDiv.querySelector('#playlist-default-media-popup-button');
+
+        this.titlePrompt.textContent = utils.unescapeEntities(this.titles);
+        this.setupInput();
+    }
+
+    /**
+     * Defines input-related Event Handlers
+     */
+    setupInput(){
+        //Setup input
+        this.titleButton.addEventListener('click', this.changeDefaultTitles.bind(this));
+        this.popup.popupDiv.addEventListener('keydown', this.changeDefaultTitles.bind(this));
+    }
+
+    /**
+     * Handles sending request to change default titles of playlist to the server
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    changeDefaultTitles(event){
+        //If we clicked or hit enter while the prompt wasn't active
+        if(event.key == null || (event.key == "Enter" && this.titlePrompt !== this.popup.doc.activeElement)){
+
+            //Tell the server to change the titles
+            this.client.socket.emit(`changeDefaultTitles${this.location}Playlist`, {
+                playlist: this.playlist,
+                defaultTitles: this.titlePrompt.value.split('\n')
+            });
+
+            //Close the popup
+            this.popup.closePopup();
+        }
+    }
+}
+
+/**
+ * Class representing pop-up dialogue to rename a playlist
+ */
+class renamePopup{
+    /**
+     * Instantiates a new Rename Pop-up
+     * @param {Event} event - Event passed down from Event Listener
+     * @param {String} playlist - Playlist name
+     * @param {channel} client - Parent Client Management Object
+     * @param {Document} doc - Current owner documnet of the panel, so we know where to drop our pop-up
+     * @param {Function} cb - Callback function, passed new name upon rename
+     */
+    constructor(event, playlist, client, doc, cb){
+        /**
+         * Parent Client Management Object
+         */
+        this.client = client;
+
+        /**
+         * Playlist Name
+         */
+        this.playlist = playlist
+
+        /**
+         * Callback Function, passed new name upon rename
+         */
+        this.cb = cb;
+
+        //Create media popup and call async constructor when done
+        //unfortunately we cant call constructors asyncronously, and we cant call back to this from super, so we can't extend this as it stands :(
+        /**
+         * canopyUXUtils.popup() object
+         */
+        this.popup = new canopyUXUtils.popup('/renamePlaylist', true, this.asyncConstructor.bind(this), doc);
+    }
+
+    /**
+     * Continuation of object construction, called after child popup object construction
+     */
+    asyncConstructor(){
+        this.renamePrompt = this.popup.contentDiv.querySelector('#playlist-rename-popup-prompt');
+        this.renameButton = this.popup.contentDiv.querySelector('#playlist-rename-popup-button');
+
+        this.setupInput();
+    }
+
+    /**
+     * Defines input-related Event Handlers
+     */
+    setupInput(){
+        //Setup input
+        this.renameButton.addEventListener('click', this.renamePlaylist.bind(this));
+        this.popup.popupDiv.addEventListener('keydown', this.renamePlaylist.bind(this));
+    }
+
+    /**
+     * Handles sending request to rename playlist to the server
+     * @param {Event} event - Event passed down from Event Listener
+     */
+    renamePlaylist(event){
+        //If we clicked or hit enter while the prompt wasn't active
+        if(event.key == null || event.key == "Enter"){
+
+            //Tell the server to change the titles
+            this.client.socket.emit('renameChannelPlaylist', {
+                playlist: this.playlist,
+                name: this.renamePrompt.value
+            });
+
+            //if CB is a function
+            if(typeof this.cb == 'function'){
+                //Hand it back the new name
+                this.cb(this.renamePrompt.value);
+            }
+
+            //Close the popup
+            this.popup.closePopup();
+        }
+    }
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/www/doc/client/panels_settingsPanel.js.html b/www/doc/client/panels_settingsPanel.js.html new file mode 100644 index 0000000..35f071a --- /dev/null +++ b/www/doc/client/panels_settingsPanel.js.html @@ -0,0 +1,112 @@ + + + + + JSDoc: Source: panels/settingsPanel.js + + + + + + + + + + +
+ +

Source: panels/settingsPanel.js

+ + + + + + +
+
+
/*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 representing the settings panel
+ * @extends panelObj
+ */
+class settingsPanel extends panelObj{
+    /**
+     * Instantiates a new Panel Object
+     * @param {channel} client - Parent client Management Object
+     * @param {Document} panelDocument - Panel Document
+     */
+    constructor(client, panelDocument){
+        super(client, "Client Settings", "/panel/settings", panelDocument);
+    }
+
+    closer(){
+    }
+
+    docSwitch(){
+        this.youtubeSource = this.panelDocument.querySelector("#settings-panel-youtube-source select");
+
+        this.renderSettings();
+        this.setupInput();
+    }
+
+    /**
+     * Defines input-related event handlers
+     */
+    setupInput(){
+        this.youtubeSource.addEventListener('change', this.updateYoutubeSource.bind(this));
+    }
+
+    /**
+     * Renders actual user settings state into panel display
+     */
+    renderSettings(){
+        this.youtubeSource.value = localStorage.getItem("ytPlayerType");
+    }
+
+    /**
+     * Event handler for Youtube Source selector
+     */
+    updateYoutubeSource(){
+        localStorage.setItem("ytPlayerType", this.youtubeSource.value);
+        client.processConfig("ytPlayerType", this.youtubeSource.value);
+    }
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/www/doc/client/player.html b/www/doc/client/player.html index e96c2d9..56875c9 100644 --- a/www/doc/client/player.html +++ b/www/doc/client/player.html @@ -3368,13 +3368,13 @@ Might seem weird to keep this here instead of the HLS handler, but remember we m
diff --git a/www/doc/client/player.js.html b/www/doc/client/player.js.html index 25a1ace..3081b68 100644 --- a/www/doc/client/player.js.html +++ b/www/doc/client/player.js.html @@ -468,13 +468,13 @@ class player{
diff --git a/www/doc/client/playlistManager.html b/www/doc/client/playlistManager.html new file mode 100644 index 0000000..5d22395 --- /dev/null +++ b/www/doc/client/playlistManager.html @@ -0,0 +1,3548 @@ + + + + + JSDoc: Class: playlistManager + + + + + + + + + + +
+ +

Class: playlistManager

+ + + + + + +
+ +
+ +

playlistManager(client, panelDocument, queuePanel)

+ +
Class representing Playlist Manager UX within the Queue Panel
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new playlistManager(client, panelDocument, queuePanel)

+ + + + + + + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
client + + +channel + + + + Parent Client Management Object
panelDocument + + +Document + + + + Panel Document
queuePanel + + +queuePanel + + + + Parent Queue Panel Object
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

client

+ + + + +
+ Parent Client Management Object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

openMap

+ + + + +
+ Map of which playlists are open and which are not, for better refresh handling +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

panelDocument

+ + + + +
+ Panel Document +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

queuePanel

+ + + + +
+ Parent Queue Panel Object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

addURL(event)

+ + + + + + +
+ Add URL to playlist +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

checkOpenPlaylists(location)

+ + + + + + +
+ Checks which playlists where open before a refresh and re-opens them +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
location + + +String + + + + Whether or not we're dealing with user or channel playlists
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

defineListeners()

+ + + + + + +
+ Handles Network-Related Event Listeners +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

deleteMedia(event)

+ + + + + + +
+ Sends request to server to delete a playlist item +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

deletePlaylist(event)

+ + + + + + +
+ Sends request to server to delete a playlist +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

editDefaultTitles(event)

+ + + + + + +
+ Sends request to server to edit default titles +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

queueAll(event)

+ + + + + + +
+ Sends request to server to queue all playlist items +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

queueMedia(event)

+ + + + + + +
+ Sends request to server to queue a playlist item +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

queueRandom(event)

+ + + + + + +
+ Sends request to server to queue a random playlist item +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

renamePlaylist(event)

+ + + + + + +
+ Sends request to server to rename playlists +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

renderChannelPlaylists(data)

+ + + + + + +
+ Renders Channel Playlist list +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Object + + + + Data from server
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

renderControls(playlist, location) → {Node}

+ + + + + + +
+ Renders out Playlist Controls +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
playlist + + +Object + + + + Playlist from server to render label for
location + + +String + + + + Location of playlist (Channel or User)
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Rendered out playlist controls +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

renderLabels(playlist, location) → {Node}

+ + + + + + +
+ Renders Playlist labels +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
playlist + + +Object + + + + Playlist from server to render label for
location + + +String + + + + Location of playlist (Channel or User)
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Rendered out playlist label +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

renderMedia(playlist, location) → {Node}

+ + + + + + +
+ Renders media object out for an entire playlist +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
playlist + + +Object + + + + Playlist from server to render label for
location + + +String + + + + Location of playlist (Channel or User)
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Rendered out playlist +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

renderMediaControls(media, playlist, location) → {Node}

+ + + + + + +
+ Renders controls out for a single media entry within a playlist +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
media + + +Object + + + + Media object from playlist to render controls for
playlist + + +Object + + + + Playlist from server to render label for
location + + +String + + + + Location of playlist (Channel or User)
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Rendered out playlist +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

renderPlaylists(data, location) → {Node}

+ + + + + + +
+ Render set of playlists out to Playlist Management Menu +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Object + + + + Data from server
location + + +String + + + + Location to load from, either Channel or User
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Rendered out playlist list +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

renderUserPlaylists(data)

+ + + + + + +
+ Renders User Playlist list +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Object + + + + Data from server
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

setupInput()

+ + + + + + +
+ Handles Input-Related Event Listeners +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toggleChannelPlaylists(event)

+ + + + + + +
+ Toggle Channel Playlists +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toggleMedia(event)

+ + + + + + +
+ Toggle Media List +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

toggleUserPlaylists(event)

+ + + + + + +
+ Toggle User Playlists +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/www/doc/client/poppedPanel.html b/www/doc/client/poppedPanel.html index b9f77ad..43150e7 100644 --- a/www/doc/client/poppedPanel.html +++ b/www/doc/client/poppedPanel.html @@ -1436,13 +1436,13 @@
diff --git a/www/doc/client/rawFileBase.html b/www/doc/client/rawFileBase.html index ab77579..fd7d0cc 100644 --- a/www/doc/client/rawFileBase.html +++ b/www/doc/client/rawFileBase.html @@ -2908,13 +2908,13 @@
diff --git a/www/doc/client/rawFileHandler.html b/www/doc/client/rawFileHandler.html index 64939ea..aea5215 100644 --- a/www/doc/client/rawFileHandler.html +++ b/www/doc/client/rawFileHandler.html @@ -2890,13 +2890,13 @@
diff --git a/www/doc/client/renamePopup.html b/www/doc/client/renamePopup.html new file mode 100644 index 0000000..8fc2c05 --- /dev/null +++ b/www/doc/client/renamePopup.html @@ -0,0 +1,884 @@ + + + + + JSDoc: Class: renamePopup + + + + + + + + + + +
+ +

Class: renamePopup

+ + + + + + +
+ +
+ +

renamePopup(event, playlist, client, doc, cb)

+ +
Class representing pop-up dialogue to rename a playlist
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new renamePopup(event, playlist, client, doc, cb)

+ + + + + + +
+ Instantiates a new Rename Pop-up +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
playlist + + +String + + + + Playlist name
client + + +channel + + + + Parent Client Management Object
doc + + +Document + + + + Current owner documnet of the panel, so we know where to drop our pop-up
cb + + +function + + + + Callback function, passed new name upon rename
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +

Members

+ + + +

cb

+ + + + +
+ Callback Function, passed new name upon rename +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

client

+ + + + +
+ Parent Client Management Object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

playlist

+ + + + +
+ Playlist Name +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+ canopyUXUtils.popup() object +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

asyncConstructor()

+ + + + + + +
+ Continuation of object construction, called after child popup object construction +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

renamePlaylist(event)

+ + + + + + +
+ Handles sending request to rename playlist to the server +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + + +Event + + + + Event passed down from Event Listener
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

setupInput()

+ + + + + + +
+ Defines input-related Event Handlers +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/www/doc/client/settingsPanel.html b/www/doc/client/settingsPanel.html new file mode 100644 index 0000000..936db78 --- /dev/null +++ b/www/doc/client/settingsPanel.html @@ -0,0 +1,1165 @@ + + + + + JSDoc: Class: settingsPanel + + + + + + + + + + +
+ +

Class: settingsPanel

+ + + + + + +
+ +
+ +

settingsPanel(client, panelDocument)

+ +
Class representing the settings panel
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new settingsPanel(client, panelDocument)

+ + + + + + +
+ Instantiates a new Panel Object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
client + + +channel + + + + Parent client Management Object
panelDocument + + +Document + + + + Panel Document
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + +

Extends

+ + + + + + + + + + + + + + + + + + + + +

Members

+ + + +

client

+ + + + +
+ Parent Client Management object +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

name

+ + + + +
+ Panel Name +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

ownerDoc

+ + + + +
+ Current root document panel doc lives within +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

pageURL

+ + + + +
+ Panel Default Page URL +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

panelDocument

+ + + + +
+ Panel Document +
+ + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

closer()

+ + + + + + +
+ Called upon panel close/exit +
+ + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

docSwitch()

+ + + + + + +
+ Handles Document/Panel Changes +
+ + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async) getPage() → {String}

+ + + + + + +
+ Fetches panel page from the server +
+ + + + + + + + + + + + + +
+ + + + + + + + +
Overrides:
+
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Raw panel doc HTML +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

renderSettings()

+ + + + + + +
+ Renders actual user settings state into panel display +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

setupInput()

+ + + + + + +
+ Defines input-related event handlers +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

updateYoutubeSource()

+ + + + + + +
+ Event handler for Youtube Source selector +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/www/doc/client/userList.html b/www/doc/client/userList.html index 8c2accc..7a1fc45 100644 --- a/www/doc/client/userList.html +++ b/www/doc/client/userList.html @@ -1185,13 +1185,13 @@
diff --git a/www/doc/client/userlist.js.html b/www/doc/client/userlist.js.html index d93908b..c06a58e 100644 --- a/www/doc/client/userlist.js.html +++ b/www/doc/client/userlist.js.html @@ -246,13 +246,13 @@ class userList{
diff --git a/www/doc/client/youtubeEmbedHandler.html b/www/doc/client/youtubeEmbedHandler.html index cd60f4b..adf47a1 100644 --- a/www/doc/client/youtubeEmbedHandler.html +++ b/www/doc/client/youtubeEmbedHandler.html @@ -2885,13 +2885,13 @@
diff --git a/www/doc/server/activeChannel.html b/www/doc/server/activeChannel.html index 2504c7e..44f4b99 100644 --- a/www/doc/server/activeChannel.html +++ b/www/doc/server/activeChannel.html @@ -786,7 +786,7 @@
diff --git a/www/doc/server/app_channel_activeChannel.js.html b/www/doc/server/app_channel_activeChannel.js.html index 348ddf8..1912be3 100644 --- a/www/doc/server/app_channel_activeChannel.js.html +++ b/www/doc/server/app_channel_activeChannel.js.html @@ -196,7 +196,7 @@ module.exports = activeChannel;
diff --git a/www/doc/server/app_channel_channelManager.js.html b/www/doc/server/app_channel_channelManager.js.html index ced5aee..fd01594 100644 --- a/www/doc/server/app_channel_channelManager.js.html +++ b/www/doc/server/app_channel_channelManager.js.html @@ -347,7 +347,7 @@ module.exports = channelManager;
diff --git a/www/doc/server/app_channel_chat.js.html b/www/doc/server/app_channel_chat.js.html index e1e4fa2..b04b700 100644 --- a/www/doc/server/app_channel_chat.js.html +++ b/www/doc/server/app_channel_chat.js.html @@ -81,7 +81,7 @@ module.exports = chat;
diff --git a/www/doc/server/app_channel_chatBuffer.js.html b/www/doc/server/app_channel_chatBuffer.js.html index 3c09baf..c2af720 100644 --- a/www/doc/server/app_channel_chatBuffer.js.html +++ b/www/doc/server/app_channel_chatBuffer.js.html @@ -178,7 +178,7 @@ module.exports = chatBuffer;
diff --git a/www/doc/server/app_channel_chatHandler.js.html b/www/doc/server/app_channel_chatHandler.js.html index 44b3036..15f8f6f 100644 --- a/www/doc/server/app_channel_chatHandler.js.html +++ b/www/doc/server/app_channel_chatHandler.js.html @@ -376,7 +376,7 @@ module.exports = chatHandler;
diff --git a/www/doc/server/app_channel_commandPreprocessor.js.html b/www/doc/server/app_channel_commandPreprocessor.js.html index 6514a1e..cb94006 100644 --- a/www/doc/server/app_channel_commandPreprocessor.js.html +++ b/www/doc/server/app_channel_commandPreprocessor.js.html @@ -473,7 +473,7 @@ module.exports = commandPreprocessor;
diff --git a/www/doc/server/app_channel_connectedUser.js.html b/www/doc/server/app_channel_connectedUser.js.html index a520193..babed09 100644 --- a/www/doc/server/app_channel_connectedUser.js.html +++ b/www/doc/server/app_channel_connectedUser.js.html @@ -334,7 +334,7 @@ module.exports = connectedUser;
diff --git a/www/doc/server/app_channel_media_media.js.html b/www/doc/server/app_channel_media_media.js.html index f4553bb..9692c00 100644 --- a/www/doc/server/app_channel_media_media.js.html +++ b/www/doc/server/app_channel_media_media.js.html @@ -83,7 +83,7 @@ module.exports = media;
diff --git a/www/doc/server/app_channel_media_playlistHandler.js.html b/www/doc/server/app_channel_media_playlistHandler.js.html index 0fbd48f..1c4ba7f 100644 --- a/www/doc/server/app_channel_media_playlistHandler.js.html +++ b/www/doc/server/app_channel_media_playlistHandler.js.html @@ -1180,7 +1180,7 @@ module.exports = playlistHandler;
diff --git a/www/doc/server/app_channel_media_queue.js.html b/www/doc/server/app_channel_media_queue.js.html index 61488cf..58de3c8 100644 --- a/www/doc/server/app_channel_media_queue.js.html +++ b/www/doc/server/app_channel_media_queue.js.html @@ -1795,7 +1795,7 @@ module.exports = queue;
diff --git a/www/doc/server/app_channel_media_queuedMedia.js.html b/www/doc/server/app_channel_media_queuedMedia.js.html index 186edec..a6136ab 100644 --- a/www/doc/server/app_channel_media_queuedMedia.js.html +++ b/www/doc/server/app_channel_media_queuedMedia.js.html @@ -165,7 +165,7 @@ module.exports = queuedMedia;
diff --git a/www/doc/server/app_channel_tokebot.js.html b/www/doc/server/app_channel_tokebot.js.html index 730b904..4cc6d1a 100644 --- a/www/doc/server/app_channel_tokebot.js.html +++ b/www/doc/server/app_channel_tokebot.js.html @@ -273,7 +273,7 @@ module.exports = tokebot;
diff --git a/www/doc/server/channelManager.html b/www/doc/server/channelManager.html index f4a7404..dcab073 100644 --- a/www/doc/server/channelManager.html +++ b/www/doc/server/channelManager.html @@ -1991,7 +1991,7 @@
diff --git a/www/doc/server/chat.html b/www/doc/server/chat.html index 421f210..7aa1414 100644 --- a/www/doc/server/chat.html +++ b/www/doc/server/chat.html @@ -329,7 +329,7 @@
diff --git a/www/doc/server/chatBuffer.html b/www/doc/server/chatBuffer.html index 1c88a99..f315f4c 100644 --- a/www/doc/server/chatBuffer.html +++ b/www/doc/server/chatBuffer.html @@ -829,7 +829,7 @@ Left here since it seems like good form anywho, since this would be a private, o
diff --git a/www/doc/server/chatHandler.html b/www/doc/server/chatHandler.html index 8a2b548..39cd367 100644 --- a/www/doc/server/chatHandler.html +++ b/www/doc/server/chatHandler.html @@ -3686,7 +3686,7 @@
diff --git a/www/doc/server/commandPreprocessor.html b/www/doc/server/commandPreprocessor.html index 191b74c..1de4ef6 100644 --- a/www/doc/server/commandPreprocessor.html +++ b/www/doc/server/commandPreprocessor.html @@ -1246,7 +1246,7 @@ These arrays are used to handle further command/chat processing
diff --git a/www/doc/server/commandProcessor.html b/www/doc/server/commandProcessor.html index c54ee7b..6cd8c4d 100644 --- a/www/doc/server/commandProcessor.html +++ b/www/doc/server/commandProcessor.html @@ -1831,7 +1831,7 @@
diff --git a/www/doc/server/connectedUser.html b/www/doc/server/connectedUser.html index 0bc268c..5a72860 100644 --- a/www/doc/server/connectedUser.html +++ b/www/doc/server/connectedUser.html @@ -1879,7 +1879,7 @@ Having to crawl through these sockets is that. Because the other ways seem more
diff --git a/www/doc/server/global.html b/www/doc/server/global.html index 8c21ffa..e1da05a 100644 --- a/www/doc/server/global.html +++ b/www/doc/server/global.html @@ -7377,7 +7377,7 @@ Warns server admin against unsafe config options.
diff --git a/www/doc/server/index.html b/www/doc/server/index.html index a5fac30..1d55802 100644 --- a/www/doc/server/index.html +++ b/www/doc/server/index.html @@ -87,7 +87,7 @@ This new codebase intends to solve the following issues with the current CyTube
diff --git a/www/doc/server/media.html b/www/doc/server/media.html index 33b9fa0..bc27a62 100644 --- a/www/doc/server/media.html +++ b/www/doc/server/media.html @@ -352,7 +352,7 @@
diff --git a/www/doc/server/playlistHandler.html b/www/doc/server/playlistHandler.html index 98c99a5..4ce5d2c 100644 --- a/www/doc/server/playlistHandler.html +++ b/www/doc/server/playlistHandler.html @@ -5108,7 +5108,7 @@
diff --git a/www/doc/server/queue.html b/www/doc/server/queue.html index 7813882..5b8e3e3 100644 --- a/www/doc/server/queue.html +++ b/www/doc/server/queue.html @@ -5805,7 +5805,7 @@ Called auto-magically by the Synchronization Timer
diff --git a/www/doc/server/queuedMedia.html b/www/doc/server/queuedMedia.html index 90c33bb..b5a3c9d 100644 --- a/www/doc/server/queuedMedia.html +++ b/www/doc/server/queuedMedia.html @@ -936,7 +936,7 @@
diff --git a/www/doc/server/schemas_channel_channelBanSchema.js.html b/www/doc/server/schemas_channel_channelBanSchema.js.html index dd2b77b..910cca3 100644 --- a/www/doc/server/schemas_channel_channelBanSchema.js.html +++ b/www/doc/server/schemas_channel_channelBanSchema.js.html @@ -101,7 +101,7 @@ module.exports = channelBanSchema;
diff --git a/www/doc/server/schemas_channel_channelPermissionSchema.js.html b/www/doc/server/schemas_channel_channelPermissionSchema.js.html index 750b88c..f71cc13 100644 --- a/www/doc/server/schemas_channel_channelPermissionSchema.js.html +++ b/www/doc/server/schemas_channel_channelPermissionSchema.js.html @@ -169,7 +169,7 @@ module.exports = channelPermissionSchema;
diff --git a/www/doc/server/schemas_channel_channelSchema.js.html b/www/doc/server/schemas_channel_channelSchema.js.html index f392729..94f1e79 100644 --- a/www/doc/server/schemas_channel_channelSchema.js.html +++ b/www/doc/server/schemas_channel_channelSchema.js.html @@ -934,7 +934,7 @@ module.exports = mongoose.model("channel", channelSchema);
diff --git a/www/doc/server/schemas_channel_chatSchema.js.html b/www/doc/server/schemas_channel_chatSchema.js.html index c1ed22f..2e8a43b 100644 --- a/www/doc/server/schemas_channel_chatSchema.js.html +++ b/www/doc/server/schemas_channel_chatSchema.js.html @@ -96,7 +96,7 @@ module.exports = chatSchema;
diff --git a/www/doc/server/schemas_channel_media_mediaSchema.js.html b/www/doc/server/schemas_channel_media_mediaSchema.js.html index 81a1f2c..60f4393 100644 --- a/www/doc/server/schemas_channel_media_mediaSchema.js.html +++ b/www/doc/server/schemas_channel_media_mediaSchema.js.html @@ -96,7 +96,7 @@ module.exports = mediaSchema;
diff --git a/www/doc/server/schemas_channel_media_playlistMediaSchema.js.html b/www/doc/server/schemas_channel_media_playlistMediaSchema.js.html index e0e0de1..924cf72 100644 --- a/www/doc/server/schemas_channel_media_playlistMediaSchema.js.html +++ b/www/doc/server/schemas_channel_media_playlistMediaSchema.js.html @@ -124,7 +124,7 @@ module.exports = mediaSchema.discriminator('saved', playlistMediaProperties); diff --git a/www/doc/server/schemas_channel_media_playlistSchema.js.html b/www/doc/server/schemas_channel_media_playlistSchema.js.html index e369231..6c1cf31 100644 --- a/www/doc/server/schemas_channel_media_playlistSchema.js.html +++ b/www/doc/server/schemas_channel_media_playlistSchema.js.html @@ -174,7 +174,7 @@ module.exports = playlistSchema;
diff --git a/www/doc/server/schemas_channel_media_queuedMediaSchema.js.html b/www/doc/server/schemas_channel_media_queuedMediaSchema.js.html index a7152ba..5031d91 100644 --- a/www/doc/server/schemas_channel_media_queuedMediaSchema.js.html +++ b/www/doc/server/schemas_channel_media_queuedMediaSchema.js.html @@ -113,7 +113,7 @@ module.exports = mediaSchema.discriminator('queued', queuedProperties); diff --git a/www/doc/server/schemas_emoteSchema.js.html b/www/doc/server/schemas_emoteSchema.js.html index c943ef9..7bbd86f 100644 --- a/www/doc/server/schemas_emoteSchema.js.html +++ b/www/doc/server/schemas_emoteSchema.js.html @@ -164,7 +164,7 @@ module.exports = mongoose.model("emote", emoteSchema);
diff --git a/www/doc/server/schemas_flairSchema.js.html b/www/doc/server/schemas_flairSchema.js.html index 89a923b..ef88412 100644 --- a/www/doc/server/schemas_flairSchema.js.html +++ b/www/doc/server/schemas_flairSchema.js.html @@ -118,7 +118,7 @@ module.exports = mongoose.model("flair", flairSchema);
diff --git a/www/doc/server/schemas_permissionSchema.js.html b/www/doc/server/schemas_permissionSchema.js.html index 15ef881..c47ba41 100644 --- a/www/doc/server/schemas_permissionSchema.js.html +++ b/www/doc/server/schemas_permissionSchema.js.html @@ -356,7 +356,7 @@ module.exports = mongoose.model("permissions", permissionSchema);
diff --git a/www/doc/server/schemas_statSchema.js.html b/www/doc/server/schemas_statSchema.js.html index d3bac04..108453b 100644 --- a/www/doc/server/schemas_statSchema.js.html +++ b/www/doc/server/schemas_statSchema.js.html @@ -240,7 +240,7 @@ module.exports = mongoose.model("statistics", statSchema);
diff --git a/www/doc/server/schemas_tokebot_tokeCommandSchema.js.html b/www/doc/server/schemas_tokebot_tokeCommandSchema.js.html index 53b32c0..faf2ad3 100644 --- a/www/doc/server/schemas_tokebot_tokeCommandSchema.js.html +++ b/www/doc/server/schemas_tokebot_tokeCommandSchema.js.html @@ -160,7 +160,7 @@ module.exports = mongoose.model("tokeCommand", tokeCommandSchema);
diff --git a/www/doc/server/schemas_user_emailChangeSchema.js.html b/www/doc/server/schemas_user_emailChangeSchema.js.html index 5d491e4..ad1815f 100644 --- a/www/doc/server/schemas_user_emailChangeSchema.js.html +++ b/www/doc/server/schemas_user_emailChangeSchema.js.html @@ -222,7 +222,7 @@ module.exports = mongoose.model("emailChange", emailChangeSchema);
diff --git a/www/doc/server/schemas_user_passwordResetSchema.js.html b/www/doc/server/schemas_user_passwordResetSchema.js.html index 38156eb..f1a2127 100644 --- a/www/doc/server/schemas_user_passwordResetSchema.js.html +++ b/www/doc/server/schemas_user_passwordResetSchema.js.html @@ -198,7 +198,7 @@ module.exports = mongoose.model("passwordReset", passwordResetSchema);
diff --git a/www/doc/server/schemas_user_userBanSchema.js.html b/www/doc/server/schemas_user_userBanSchema.js.html index 4c2954d..42ed732 100644 --- a/www/doc/server/schemas_user_userBanSchema.js.html +++ b/www/doc/server/schemas_user_userBanSchema.js.html @@ -521,7 +521,7 @@ module.exports = mongoose.model("userBan", userBanSchema);
diff --git a/www/doc/server/schemas_user_userSchema.js.html b/www/doc/server/schemas_user_userSchema.js.html index 385a7f4..ca6b7fa 100644 --- a/www/doc/server/schemas_user_userSchema.js.html +++ b/www/doc/server/schemas_user_userSchema.js.html @@ -888,7 +888,7 @@ module.exports.userModel = mongoose.model("user", userSchema);
diff --git a/www/doc/server/tokebot.html b/www/doc/server/tokebot.html index 39cedd1..586e3da 100644 --- a/www/doc/server/tokebot.html +++ b/www/doc/server/tokebot.html @@ -841,7 +841,7 @@ I would now, but I don't want to break shit in a comment-only commit.
diff --git a/www/doc/server/utils_altchaUtils.js.html b/www/doc/server/utils_altchaUtils.js.html index 9b888ce..70699f8 100644 --- a/www/doc/server/utils_altchaUtils.js.html +++ b/www/doc/server/utils_altchaUtils.js.html @@ -118,7 +118,7 @@ module.exports.verify = async function(payload, uniqueSecret = ''){
diff --git a/www/doc/server/utils_configCheck.js.html b/www/doc/server/utils_configCheck.js.html index 408a772..0dbbedd 100644 --- a/www/doc/server/utils_configCheck.js.html +++ b/www/doc/server/utils_configCheck.js.html @@ -108,7 +108,7 @@ module.exports.securityCheck = function(){
diff --git a/www/doc/server/utils_hashUtils.js.html b/www/doc/server/utils_hashUtils.js.html index af4d8ba..161f4f3 100644 --- a/www/doc/server/utils_hashUtils.js.html +++ b/www/doc/server/utils_hashUtils.js.html @@ -103,7 +103,7 @@ module.exports.hashIP = function(ip){
diff --git a/www/doc/server/utils_linkUtils.js.html b/www/doc/server/utils_linkUtils.js.html index 4bee12a..8d88295 100644 --- a/www/doc/server/utils_linkUtils.js.html +++ b/www/doc/server/utils_linkUtils.js.html @@ -146,7 +146,7 @@ module.exports.markLink = async function(link){
diff --git a/www/doc/server/utils_loggerUtils.js.html b/www/doc/server/utils_loggerUtils.js.html index 20cafd3..888daca 100644 --- a/www/doc/server/utils_loggerUtils.js.html +++ b/www/doc/server/utils_loggerUtils.js.html @@ -207,7 +207,7 @@ module.exports.errorMiddleware = function(err, req, res, next){
diff --git a/www/doc/server/utils_mailUtils.js.html b/www/doc/server/utils_mailUtils.js.html index f9ff380..cb3ebc9 100644 --- a/www/doc/server/utils_mailUtils.js.html +++ b/www/doc/server/utils_mailUtils.js.html @@ -140,7 +140,7 @@ module.exports.sendAddressVerification = async function(requestDB, userDB, newEm
diff --git a/www/doc/server/utils_media_internetArchiveUtils.js.html b/www/doc/server/utils_media_internetArchiveUtils.js.html index 60d0abe..14b617c 100644 --- a/www/doc/server/utils_media_internetArchiveUtils.js.html +++ b/www/doc/server/utils_media_internetArchiveUtils.js.html @@ -154,7 +154,7 @@ module.exports.fetchMetadata = async function(fullID, title){
diff --git a/www/doc/server/utils_media_yanker.js.html b/www/doc/server/utils_media_yanker.js.html index 9381dc7..fb77445 100644 --- a/www/doc/server/utils_media_yanker.js.html +++ b/www/doc/server/utils_media_yanker.js.html @@ -193,7 +193,7 @@ module.exports.getMediaType = async function(url){
diff --git a/www/doc/server/utils_media_ytdlpUtils.js.html b/www/doc/server/utils_media_ytdlpUtils.js.html index 400a92b..ff197ba 100644 --- a/www/doc/server/utils_media_ytdlpUtils.js.html +++ b/www/doc/server/utils_media_ytdlpUtils.js.html @@ -186,7 +186,7 @@ async function ytdlpFetch(link, format = 'b'){
diff --git a/www/doc/server/utils_regexUtils.js.html b/www/doc/server/utils_regexUtils.js.html index b1e7099..440bdb6 100644 --- a/www/doc/server/utils_regexUtils.js.html +++ b/www/doc/server/utils_regexUtils.js.html @@ -69,7 +69,7 @@ module.exports.escapeRegex = function(string){
diff --git a/www/doc/server/utils_scheduler.js.html b/www/doc/server/utils_scheduler.js.html index e067e4f..3f68e13 100644 --- a/www/doc/server/utils_scheduler.js.html +++ b/www/doc/server/utils_scheduler.js.html @@ -105,7 +105,7 @@ module.exports.kickoff = function(){
diff --git a/www/doc/server/utils_sessionUtils.js.html b/www/doc/server/utils_sessionUtils.js.html index c4b04a3..534bf7e 100644 --- a/www/doc/server/utils_sessionUtils.js.html +++ b/www/doc/server/utils_sessionUtils.js.html @@ -236,7 +236,7 @@ module.exports.maxAttempts = maxAttempts;
diff --git a/www/js/channel/chat.js b/www/js/channel/chat.js index 0f2eae4..a9f475d 100644 --- a/www/js/channel/chat.js +++ b/www/js/channel/chat.js @@ -256,8 +256,8 @@ class chatBox{ } /** - * Concatinate Text into Chat Prompt - * @param {String} text - Text to Concatinate + * Concatenate Text into Chat Prompt + * @param {String} text - Text to Concatenate */ catChat(text){ this.chatPrompt.value += text; diff --git a/www/js/channel/panels/emotePanel.js b/www/js/channel/panels/emotePanel.js index 801d50b..464fd40 100644 --- a/www/js/channel/panels/emotePanel.js +++ b/www/js/channel/panels/emotePanel.js @@ -13,7 +13,17 @@ 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 .*/ + +/** + * Class representing Emote Panel UX + * @extends panelObj + */ class emotePanel extends panelObj{ + /** + * Instantiates a new Panel Object + * @param {channel} client - Parent client Management Object + * @param {Document} panelDocument - Panel Document + */ constructor(client, panelDocument){ super(client, "Emote Palette", "/panel/emote", panelDocument); @@ -49,6 +59,9 @@ class emotePanel extends panelObj{ this.renderEmoteLists(); } + /** + * Defines input-related event handlers + */ setupInput(){ //Make sure to remove any event listeners in-case we moving an already instantiated panel this.siteEmoteToggle.removeEventListener("click", this.toggleSiteEmotes.bind(this)); @@ -76,18 +89,35 @@ class emotePanel extends panelObj{ this.personalEmoteAddButton.addEventListener("click", this.addPersonalEmote.bind(this)); } + /** + * Toggles Site emote display + * @param {Event} event - Event passed down by event listener + */ toggleSiteEmotes(event){ this.toggleEmotes(this.siteEmoteToggle, this.siteEmoteList); } + /** + * Toggles Channel emote display + * @param {Event} event - Event passed down by event listener + */ toggleChanEmotes(event){ this.toggleEmotes(this.chanEmoteToggle, this.chanEmoteList); } + /** + * Toggles Personal emote display + * @param {Event} event - Event passed down by event listener + */ togglePersonalEmotes(event){ this.toggleEmotes(this.personalEmoteToggle, this.personalEmoteSection); } + /** + * Toggles a specified emote list on or off + * @param {Node} icon - Toggle Icon for given list + * @param {Node} list - Emote list container to toggle + */ toggleEmotes(icon, list){ if(list.checkVisibility()){ icon.classList.replace('bi-caret-down-fill','bi-caret-left-fill'); @@ -98,6 +128,10 @@ class emotePanel extends panelObj{ } } + /** + * Concatenates specified emote into chat prompt input + * @param {String} emote - Emote to concat into chat + */ useEmote(emote){ //If we're using this from the active panel if(this.client.cPanel.activePanel == this){ @@ -109,6 +143,10 @@ class emotePanel extends panelObj{ this.client.chatBox.catChat(`[${emote}]`); } + /** + * Requests server to add emote to list of personal emotes + * @param {Event} event - Event passed down by event listener + */ addPersonalEmote(event){ //Collect input const name = this.personalEmoteNamePrompt.value; @@ -122,11 +160,18 @@ class emotePanel extends panelObj{ this.client.socket.emit("addPersonalEmote", {name, link}); } + /** + * Requests server to remove emote from list of personal emotes + * @param {String} name - Name of emote to delete + */ deletePersonalEmote(name){ //send out delete this.client.socket.emit('deletePersonalEmote', {name}); } + /** + * Renders out emote list to panel document + */ renderEmoteLists(){ //if we've initialized the search prompt (wont happen yet first run) if(this.searchPrompt != null){ @@ -158,6 +203,12 @@ class emotePanel extends panelObj{ this.renderEmotes(personalEmotes, this.personalEmoteList, true); } + /** + * Renders out emotes to emote lists + * @param {Array} emoteList - list of emotes to render + * @param {Node} container - Container to render emotes out to + * @param {Boolean} personal - Denotes whether or not we're rendering personal emotes + */ renderEmotes(emoteList, container, personal = false){ //Clear out the container container.innerHTML = ''; diff --git a/www/js/channel/panels/queuePanel/playlistManager.js b/www/js/channel/panels/queuePanel/playlistManager.js index 953cd09..7fc61f1 100644 --- a/www/js/channel/panels/queuePanel/playlistManager.js +++ b/www/js/channel/panels/queuePanel/playlistManager.js @@ -13,15 +13,36 @@ 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 .*/ +/** + * Class representing Playlist Manager UX within the Queue Panel + */ class playlistManager{ + + /** + * + * @param {channel} client - Parent Client Management Object + * @param {Document} panelDocument - Panel Document + * @param {queuePanel} queuePanel - Parent Queue Panel Object + */ constructor(client, panelDocument, queuePanel){ - //Set client + /** + * Parent Client Management Object + */ this.client = client; - //Set panel document + + /** + * Panel Document + */ this.panelDocument = panelDocument; - //Set parent queue panel + + /** + * Parent Queue Panel Object + */ this.queuePanel = queuePanel; - //Create openMap + + /** + * Map of which playlists are open and which are not, for better refresh handling + */ this.openMap = { Channel: new Map(), User: new Map() @@ -31,6 +52,9 @@ class playlistManager{ this.defineListeners(); } + /** + * Handles Network-Related Event Listeners + */ defineListeners(){ this.client.socket.on("chanPlaylists", this.renderChannelPlaylists.bind(this)); this.client.socket.on("userPlaylists", this.renderUserPlaylists.bind(this)); @@ -56,6 +80,9 @@ class playlistManager{ this.setupInput(); } + /** + * Handles Input-Related Event Listeners + */ setupInput(){ this.createPlaylistSpan.addEventListener('click', (event)=>{new newPlaylistPopup(event, this.client, this.queuePanel.ownerDoc)}) this.channelPlaylistLabel.addEventListener('click', this.toggleChannelPlaylists.bind(this)); @@ -63,6 +90,11 @@ class playlistManager{ } /* queue control button functions */ + + /** + * Toggle Channel Playlists + * @param {Event} event - Event passed down from Event Listener + */ toggleChannelPlaylists(event){ //If the div is hidden if(this.channelPlaylistDiv.style.display == 'none'){ @@ -82,7 +114,10 @@ class playlistManager{ } } - /* queue control button functions */ + /** + * Toggle User Playlists + * @param {Event} event - Event passed down from Event Listener + */ toggleUserPlaylists(event){ //If the div is hidden if(this.userPlaylistDiv.style.display == 'none'){ @@ -102,6 +137,10 @@ class playlistManager{ } } + /** + * Checks which playlists where open before a refresh and re-opens them + * @param {String} location - Whether or not we're dealing with user or channel playlists + */ checkOpenPlaylists(location){ //If open map is a string, indicating we just renamed a playlist with it's media open if(typeof this.openMap[location] == 'string'){ @@ -128,6 +167,11 @@ class playlistManager{ } //Main playlist rendering functions + + /** + * Renders Channel Playlist list + * @param {Object} data - Data from server + */ renderChannelPlaylists(data){ //Check for open playlists this.checkOpenPlaylists('Channel'); @@ -139,6 +183,10 @@ class playlistManager{ this.channelPlaylistDiv.append(...this.renderPlaylists(data, 'Channel')); } + /** + * Renders User Playlist list + * @param {Object} data - Data from server + */ renderUserPlaylists(data){ //Check for open playlists this.checkOpenPlaylists('User'); @@ -150,6 +198,12 @@ class playlistManager{ this.userPlaylistDiv.append(...this.renderPlaylists(data, 'User')); } + /** + * Render set of playlists out to Playlist Management Menu + * @param {Object} data - Data from server + * @param {String} location - Location to load from, either Channel or User + * @returns {Node} Rendered out playlist list + */ renderPlaylists(data, location){ const playlists = []; @@ -194,6 +248,12 @@ class playlistManager{ } //aux rendering functions + /** + * Renders Playlist labels + * @param {Object} playlist - Playlist from server to render label for + * @param {String} location - Location of playlist (Channel or User) + * @returns {Node} Rendered out playlist label + */ renderLabels(playlist, location){ //Create playlist label span const playlistLabels = document.createElement('span'); @@ -247,6 +307,12 @@ class playlistManager{ return playlistLabels; } + /** + * Renders out Playlist Controls + * @param {Object} playlist - Playlist from server to render label for + * @param {String} location - Location of playlist (Channel or User) + * @returns {Node} Rendered out playlist controls + */ renderControls(playlist, location){ //Create playlist control span const playlistControls = document.createElement('span'); @@ -336,6 +402,12 @@ class playlistManager{ return playlistControls; } + /** + * Renders media object out for an entire playlist + * @param {Object} playlist - Playlist from server to render label for + * @param {String} location - Location of playlist (Channel or User) + * @returns {Node} Rendered out playlist + */ renderMedia(playlist, location){ //Create media container div const mediaContainer = document.createElement('div'); @@ -393,6 +465,13 @@ class playlistManager{ return mediaContainer; } + /** + * Renders controls out for a single media entry within a playlist + * @param {Object} media - Media object from playlist to render controls for + * @param {Object} playlist - Playlist from server to render label for + * @param {String} location - Location of playlist (Channel or User) + * @returns {Node} Rendered out playlist + */ renderMediaControls(media, playlist, location){ //Create media control span const mediaControlSpan = document.createElement('span'); @@ -429,6 +508,10 @@ class playlistManager{ return mediaControlSpan; } + /** + * Toggle Media List + * @param {Event} event - Event passed down from Event Listener + */ toggleMedia(event){ //Grab playlist title caret const playlistTitleCaret = event.target.querySelector('i'); @@ -453,6 +536,10 @@ class playlistManager{ } } + /** + * Add URL to playlist + * @param {Event} event - Event passed down from Event Listener + */ addURL(event){ new addURLPopup( event, @@ -464,6 +551,11 @@ class playlistManager{ } //playlist control functions + + /** + * Sends request to server to edit default titles + * @param {Event} event - Event passed down from Event Listener + */ editDefaultTitles(event){ new defaultTitlesPopup( event, @@ -475,6 +567,10 @@ class playlistManager{ ); } + /** + * Sends request to server to rename playlists + * @param {Event} event - Event passed down from Event Listener + */ renamePlaylist(event){ new renamePopup( event, @@ -496,38 +592,75 @@ class playlistManager{ } } + /** + * Sends request to server to queue all playlist items + * @param {Event} event - Event passed down from Event Listener + */ queueAll(event){ this.client.socket.emit(`queue${event.target.parentNode.dataset['location']}Playlist`, {playlist: event.target.parentNode.dataset['playlist']}); } + /** + * Sends request to server to queue a playlist item + * @param {Event} event - Event passed down from Event Listener + */ queueMedia(event){ this.client.socket.emit(`queueFrom${event.target.parentNode.dataset['location']}Playlist`,{playlist: event.target.parentNode.dataset['playlist'], uuid: event.target.parentNode.dataset['uuid']}); } + /** + * Sends request to server to queue a random playlist item + * @param {Event} event - Event passed down from Event Listener + */ queueRandom(event){ this.client.socket.emit(`queueRandomFrom${event.target.parentNode.dataset['location']}Playlist`,{playlist: event.target.parentNode.dataset['playlist']}); } + /** + * Sends request to server to delete a playlist + * @param {Event} event - Event passed down from Event Listener + */ deletePlaylist(event){ this.client.socket.emit(`delete${event.target.parentNode.dataset['location']}Playlist`, {playlist: event.target.parentNode.dataset['playlist']}); } + /** + * Sends request to server to delete a playlist item + * @param {Event} event - Event passed down from Event Listener + */ deleteMedia(event ){ this.client.socket.emit(`delete${event.target.parentNode.dataset['location']}PlaylistMedia`, {playlist: event.target.parentNode.dataset['playlist'], uuid: event.target.parentNode.dataset['uuid']}); } } +/** + * Class representing pop-up dialogue for creating a new playlist + */ class newPlaylistPopup{ + /** + * Instantiates a New Playlist Popup + * @param {Event} event - Event passed down from Event Listener + * @param {channel} client - Parent Client Management Object + * @param {Document} doc - Current owner documnet of the panel, so we know where to drop our pop-up + */ constructor(event, client, doc){ - //Set Client + /** + * Parent Client Management Object + */ this.client = client; //Create media popup and call async constructor when done //unfortunately we cant call constructors asyncronously, and we cant call back to this from super, so we can't extend this as it stands :( + /** + * canopyUXUtils.popup() object + */ this.popup = new canopyUXUtils.popup('/newPlaylist', true, this.asyncConstructor.bind(this), doc, false); } + /** + * Continuation of object construction, called after child popup object construction + */ asyncConstructor(){ this.name = this.popup.contentDiv.querySelector('#queue-create-playlist-popup-name'); this.defaultTitles = this.popup.contentDiv.querySelector('#queue-create-playlist-popup-default-titles'); @@ -537,12 +670,19 @@ class newPlaylistPopup{ this.setupInput(); } + /** + * Defines input-related Event Handlers + */ setupInput(){ //Setup input this.saveButton.addEventListener('click', this.createPlaylist.bind(this)); this.popup.popupDiv.addEventListener('keydown', this.createPlaylist.bind(this)); } + /** + * Sends request to create a playlist off to the server + * @param {Event} event - Event passed down from Event Listener + */ createPlaylist(event){ //If we clicked or hit enter if(event.key == null || (event.key == "Enter" && this.defaultTitles !== this.popup.doc.activeElement)){ @@ -559,22 +699,45 @@ class newPlaylistPopup{ } } +/** + * Class representing pop-up dialogue which adds media to a given playlist + */ class addURLPopup{ + /** + * Instantiates a new Add URL Pop-up + * @param {Event} event - Event passed down from Event Listener + * @param {String} playlist - Playlist name + * @param {String} location - Location of playlist, either Channel or User + * @param {channel} client - Parent Client Management Object + * @param {Document} doc - Current owner documnet of the panel, so we know where to drop our pop-up + */ constructor(event, playlist, location, client, doc){ - //Set Client + /** + * Parent Client Management Object + */ this.client = client; - //Set playlist + /** + * Playlist Name + */ this.playlist = playlist - //Set location + /** + * Location of playlist, either Channel or User + */ this.location = location; //Create media popup and call async constructor when done //unfortunately we cant call constructors asyncronously, and we cant call back to this from super, so we can't extend this as it stands :( + /** + * canopyUXUtils.popup() object + */ this.popup = new canopyUXUtils.popup('/addToPlaylist', true, this.asyncConstructor.bind(this), doc); } + /** + * Continuation of object construction, called after child popup object construction + */ asyncConstructor(){ this.urlPrompt = this.popup.contentDiv.querySelector('#playlist-add-media-popup-prompt'); this.addButton = this.popup.contentDiv.querySelector('#playlist-add-media-popup-button'); @@ -582,12 +745,19 @@ class addURLPopup{ this.setupInput(); } + /** + * Defines input-related Event Handlers + */ setupInput(){ //Setup input this.addButton.addEventListener('click', this.addToPlaylist.bind(this)); this.popup.popupDiv.addEventListener('keydown', this.addToPlaylist.bind(this)); } + /** + * Handles sending request to add to a playlist to the server + * @param {Event} event - Event passed down from Event Listener + */ addToPlaylist(event){ //If we clicked or hit enter if(event.key == null || event.key == "Enter"){ @@ -605,25 +775,51 @@ class addURLPopup{ } } +/** + * Class Representing popup dialogue for changing playlists defualt titles + */ class defaultTitlesPopup{ + /** + * Instantiates a new Default Titles Popup + * @param {Event} event - Event passed down from Event Listener + * @param {String} playlist - Playlist name + * @param {String} titles - List of titles, denoted by newlines + * @param {String} location - Location of playlist, either Channel or User + * @param {channel} client - Parent Client Management Object + * @param {Document} doc - Current owner documnet of the panel, so we know where to drop our pop-up + */ constructor(event, playlist, titles, location, client, doc){ - //Set Client + /** + * Parent Client Management Object + */ this.client = client; - //Set playlist + /** + * Playlist Name + */ this.playlist = playlist - //Set location + /** + * Location of playlist, either Channel or User + */ this.location = location; - //Set title string + /** + * Array of titles to set + */ this.titles = titles.join('\n'); //Create media popup and call async constructor when done //unfortunately we cant call constructors asyncronously, and we cant call back to this from super, so we can't extend this as it stands :( + /** + * canopyUXUtils.popup() object + */ this.popup = new canopyUXUtils.popup('/playlistDefaultTitles', true, this.asyncConstructor.bind(this), doc, false); } + /** + * Continuation of object construction, called after child popup object construction + */ asyncConstructor(){ this.titlePrompt = this.popup.contentDiv.querySelector('#playlist-default-titles-popup-prompt'); this.titleButton = this.popup.contentDiv.querySelector('#playlist-default-media-popup-button'); @@ -632,12 +828,19 @@ class defaultTitlesPopup{ this.setupInput(); } + /** + * Defines input-related Event Handlers + */ setupInput(){ //Setup input this.titleButton.addEventListener('click', this.changeDefaultTitles.bind(this)); this.popup.popupDiv.addEventListener('keydown', this.changeDefaultTitles.bind(this)); } + /** + * Handles sending request to change default titles of playlist to the server + * @param {Event} event - Event passed down from Event Listener + */ changeDefaultTitles(event){ //If we clicked or hit enter while the prompt wasn't active if(event.key == null || (event.key == "Enter" && this.titlePrompt !== this.popup.doc.activeElement)){ @@ -654,22 +857,45 @@ class defaultTitlesPopup{ } } +/** + * Class representing pop-up dialogue to rename a playlist + */ class renamePopup{ + /** + * Instantiates a new Rename Pop-up + * @param {Event} event - Event passed down from Event Listener + * @param {String} playlist - Playlist name + * @param {channel} client - Parent Client Management Object + * @param {Document} doc - Current owner documnet of the panel, so we know where to drop our pop-up + * @param {Function} cb - Callback function, passed new name upon rename + */ constructor(event, playlist, client, doc, cb){ - //Set Client + /** + * Parent Client Management Object + */ this.client = client; - //Set playlist + /** + * Playlist Name + */ this.playlist = playlist - //Set callback + /** + * Callback Function, passed new name upon rename + */ this.cb = cb; //Create media popup and call async constructor when done //unfortunately we cant call constructors asyncronously, and we cant call back to this from super, so we can't extend this as it stands :( + /** + * canopyUXUtils.popup() object + */ this.popup = new canopyUXUtils.popup('/renamePlaylist', true, this.asyncConstructor.bind(this), doc); } + /** + * Continuation of object construction, called after child popup object construction + */ asyncConstructor(){ this.renamePrompt = this.popup.contentDiv.querySelector('#playlist-rename-popup-prompt'); this.renameButton = this.popup.contentDiv.querySelector('#playlist-rename-popup-button'); @@ -677,13 +903,20 @@ class renamePopup{ this.setupInput(); } + /** + * Defines input-related Event Handlers + */ setupInput(){ //Setup input - this.renameButton.addEventListener('click', this.changeDefaultTitles.bind(this)); - this.popup.popupDiv.addEventListener('keydown', this.changeDefaultTitles.bind(this)); + this.renameButton.addEventListener('click', this.renamePlaylist.bind(this)); + this.popup.popupDiv.addEventListener('keydown', this.renamePlaylist.bind(this)); } - changeDefaultTitles(event){ + /** + * Handles sending request to rename playlist to the server + * @param {Event} event - Event passed down from Event Listener + */ + renamePlaylist(event){ //If we clicked or hit enter while the prompt wasn't active if(event.key == null || event.key == "Enter"){ diff --git a/www/js/channel/panels/settingsPanel.js b/www/js/channel/panels/settingsPanel.js index c2e0aca..73849a7 100644 --- a/www/js/channel/panels/settingsPanel.js +++ b/www/js/channel/panels/settingsPanel.js @@ -13,7 +13,17 @@ 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 .*/ + +/** + * Class representing the settings panel + * @extends panelObj + */ class settingsPanel extends panelObj{ + /** + * Instantiates a new Panel Object + * @param {channel} client - Parent client Management Object + * @param {Document} panelDocument - Panel Document + */ constructor(client, panelDocument){ super(client, "Client Settings", "/panel/settings", panelDocument); } @@ -28,14 +38,23 @@ class settingsPanel extends panelObj{ this.setupInput(); } + /** + * Defines input-related event handlers + */ setupInput(){ this.youtubeSource.addEventListener('change', this.updateYoutubeSource.bind(this)); } + /** + * Renders actual user settings state into panel display + */ renderSettings(){ this.youtubeSource.value = localStorage.getItem("ytPlayerType"); } + /** + * Event handler for Youtube Source selector + */ updateYoutubeSource(){ localStorage.setItem("ytPlayerType", this.youtubeSource.value); client.processConfig("ytPlayerType", this.youtubeSource.value);