mirror of
https://github.com/nuttylmao/nutty.gg.git
synced 2026-09-19 04:00:59 -04:00
Beta ready
This commit is contained in:
@@ -7,12 +7,14 @@
|
|||||||
--background-color: #181818;
|
--background-color: #181818;
|
||||||
--accent-color: #2196f3;
|
--accent-color: #2196f3;
|
||||||
--success-color: #3be477;
|
--success-color: #3be477;
|
||||||
|
--confirm-flash: #3be47680;
|
||||||
--button-color: #2e2e2e;
|
--button-color: #2e2e2e;
|
||||||
--dialog-background: #1d1d1d;
|
--dialog-background: #1d1d1d;
|
||||||
--callout-background: #181818;
|
--callout-background: #181818;
|
||||||
--error-background: #a82d2e33;
|
--error-background: #a82d2e33;
|
||||||
--error-color: #c65e5e;
|
--error-color: #c65e5e;
|
||||||
--mandatory-field-color: #c93f3f;
|
--mandatory-field-color: #c93f3f;
|
||||||
|
--error-text-color: #c93f3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -99,7 +101,7 @@ button:hover {
|
|||||||
|
|
||||||
button:disabled {
|
button:disabled {
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
cursor: inherit;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-button {
|
.icon-button {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<!-- YouTube warning -->
|
<!-- YouTube warning -->
|
||||||
<div id="youtube-warning" class="broadcast">
|
<div id="youtube-warning" class="broadcast">
|
||||||
<img class="platform-icon" id="platform-icon" src="icons/platforms/youtube.png"/>
|
<img class="platform-icon" id="platform-icon" src="icons/platforms/youtube.png" />
|
||||||
|
|
||||||
<div class="broadcast-info">
|
<div class="broadcast-info">
|
||||||
<label class="setting-attribute">
|
<label class="setting-attribute">
|
||||||
@@ -29,7 +29,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="broadcast-buttons">
|
<div id="broadcast-buttons">
|
||||||
<button id="broadcast-dashboard-button" class="icon-button" title="Dashboard"><img class="button-icon" src="https://api.iconify.design/gridicons:popout.svg?color=%23ffffff"></button>
|
<button id="broadcast-dashboard-button" class="icon-button" title="Dashboard"><img class="button-icon"
|
||||||
|
src="https://api.iconify.design/gridicons:popout.svg?color=%23ffffff"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -44,16 +45,21 @@
|
|||||||
<label class="title" style="text-align: center;">Stream Info</label>
|
<label class="title" style="text-align: center;">Stream Info</label>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<div style="display: flex; flex-direction: row; align-items: end; gap: 1em;">
|
||||||
<label>Title</label>
|
<label>Title</label>
|
||||||
<input type="text" id="update-all-title-input" placeholder="My First Stream #RoadToAffiliate">
|
<div id="all-title-char-limit" class="char-limit">
|
||||||
|
<span id="all-title-char-count"></span>/<span id="all-title-char-max"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="text" id="all-title-input" placeholder="Leave empty to keep current title">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Category</label>
|
<label>Category</label>
|
||||||
<input type="text" id="update-all-category-input" placeholder="Just Chatting">
|
<input type="text" id="all-category-input" placeholder="Leave empty to keep current category">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onclick="UpdateAllSubmit()">Update All</button>
|
<button id="all-submit-button" onclick="UpdateAllSubmit()">Update All</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Update Twitch Popup -->
|
<!-- Update Twitch Popup -->
|
||||||
@@ -66,21 +72,32 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<div style="display: flex; flex-direction: row; align-items: end; gap: 1em;">
|
||||||
<label>Title</label>
|
<label>Title</label>
|
||||||
<input type="text" id="update-twitch-title-input" placeholder="My First Stream #RoadToAffiliate">
|
<div id="twitch-title-char-limit" class="char-limit">
|
||||||
|
<span id="twitch-title-char-count"></span>/<span id="twitch-title-char-max"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="text" id="twitch-title-input" placeholder="Leave empty to keep current title">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Category</label>
|
<label>Category</label>
|
||||||
<input type="text" id="update-twitch-category-input" placeholder="Just Chatting">
|
<input type="text" id="twitch-category-input" placeholder="Leave empty to keep current category">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<div style="display: flex; flex-direction: row; align-items: end; gap: 1em;">
|
||||||
<label>Tags</label>
|
<label>Tags</label>
|
||||||
<input type="text" id="update-twitch-tags-input" placeholder="Retro, Speedrun, CreamTeam">
|
<div id="twitch-tags-char-limit" class="char-limit">
|
||||||
|
<span id="twitch-tags-too-long-warning">Tag too long • </span><span id="twitch-tags-char-count"></span>/<span id="twitch-tags-char-max"></span> Tags
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<label class="setting-description">Add up to 10 tags. Each tag can be 25 characters long with no spaces or special characters.</label>
|
||||||
|
<input type="text" id="twitch-tags-input" placeholder="Leave empty to keep current tags">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onclick="UpdateTwitchSubmit()">Update</button>
|
<button id="twitch-submit-button" onclick="UpdateTwitchSubmit()">Update</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Update Kick Popup -->
|
<!-- Update Kick Popup -->
|
||||||
@@ -93,16 +110,21 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<div style="display: flex; flex-direction: row; align-items: end; gap: 1em;">
|
||||||
<label>Title</label>
|
<label>Title</label>
|
||||||
<input type="text" id="update-kick-title-input" placeholder="My First Stream #RoadToAffiliate">
|
<div id="kick-title-char-limit" class="char-limit">
|
||||||
|
<span id="kick-title-char-count"></span>/<span id="kick-title-char-max"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="text" id="kick-title-input" placeholder="Leave empty to keep current title">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Category</label>
|
<label>Category</label>
|
||||||
<input type="text" id="update-kick-category-input" placeholder="Just Chatting">
|
<input type="text" id="kick-category-input" placeholder="Leave empty to keep current category">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onclick="UpdateKickSubmit()">Update</button>
|
<button id="kick-submit-button" onclick="UpdateKickSubmit()">Update</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Update YouTube Popup -->
|
<!-- Update YouTube Popup -->
|
||||||
@@ -115,35 +137,67 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<div style="display: flex; flex-direction: row; align-items: end; gap: 1em;">
|
||||||
<label>Title</label>
|
<label>Title</label>
|
||||||
<input type="text" id="update-youtube-title-input" placeholder="My First Stream #RoadToAffiliate">
|
<div id="youtube-title-char-limit" class="char-limit">
|
||||||
|
<span id="youtube-title-char-count"></span>/<span id="youtube-title-char-max"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="text" id="youtube-title-input" placeholder="Leave empty to keep current title">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<div style="display: flex; flex-direction: row; align-items: end; gap: 1em;">
|
||||||
<label>Description</label>
|
<label>Description</label>
|
||||||
<textarea type="text" id="update-youtube-description-input" placeholder="I'm describing so hard right now..." class="textarea-description"></textarea>
|
<div id="youtube-description-char-limit" class="char-limit">
|
||||||
|
<span id="youtube-description-char-count"></span>/<span id="youtube-description-char-max"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<textarea type="text" id="youtube-description-input" placeholder="Leave empty to keep current description"
|
||||||
|
class="textarea-description"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Category</label>
|
<label>Category</label>
|
||||||
<input type="text" id="update-youtube-category-input" placeholder="Gaming">
|
<select id="youtube-category-input">
|
||||||
|
<option value="Autos & Vehicles">Autos & Vehicles</option>
|
||||||
|
<option value="Comedy">Comedy</option>
|
||||||
|
<option value="Education">Education</option>
|
||||||
|
<option value="Entertainment">Entertainment</option>
|
||||||
|
<option value="Film & Animation">Film & Animation</option>
|
||||||
|
<option value="Gaming">Gaming</option>
|
||||||
|
<option value="Howto & Style">Howto & Style</option>
|
||||||
|
<option value="Music">Music</option>
|
||||||
|
<option value="News & Politics">News & Politics</option>
|
||||||
|
<option value="Nonprofits & Activism">Nonprofits & Activism</option>
|
||||||
|
<option value="People & Blogs">People & Blogs</option>
|
||||||
|
<option value="Pets & Animals">Pets & Animals</option>
|
||||||
|
<option value="Science & Technology">Science & Technology</option>
|
||||||
|
<option value="Sports">Sports</option>
|
||||||
|
<option value="Travel & Events">Travel & Events</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<div style="display: flex; flex-direction: row; align-items: end; gap: 1em;">
|
||||||
<label>Tags</label>
|
<label>Tags</label>
|
||||||
<input type="text" id="update-youtube-tags-input" placeholder="Retro, Speedrun, CreamTeam">
|
<div id="youtube-tags-char-limit" class="char-limit">
|
||||||
|
<span id="youtube-tags-char-count"></span>/<span id="youtube-tags-char-max"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="text" id="youtube-tags-input" placeholder="Leave empty to keep current tags">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Visibility</label>
|
<label>Visibility</label>
|
||||||
<select id="update-youtube-privacy-select">
|
<select id="youtube-privacy-select">
|
||||||
<option value="private">Private</option>
|
<option value="private">Private</option>
|
||||||
<option value="unlisted">Unlisted</option>
|
<option value="unlisted">Unlisted</option>
|
||||||
<option value="public">Public</option>
|
<option value="public">Public</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onclick="UpdateYouTubeSubmit()">Update</button>
|
<button id="youtube-submit-button" onclick="UpdateYouTubeSubmit()">Update</button>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
@@ -152,17 +206,20 @@
|
|||||||
<!-- Broadcast Template -->
|
<!-- Broadcast Template -->
|
||||||
<template id="broadcast-template">
|
<template id="broadcast-template">
|
||||||
<div class="broadcast">
|
<div class="broadcast">
|
||||||
<img class="platform-icon" id="platform-icon" src=""/>
|
<img class="platform-icon" id="platform-icon" src="" />
|
||||||
|
|
||||||
<div class="broadcast-info">
|
<div class="broadcast-info">
|
||||||
<label id="broadcast-title"></label>
|
<label id="broadcast-title"></label>
|
||||||
<label id="broadcast-category" class="setting-description"></label>
|
<label id="broadcast-category" class="setting-description"></label>
|
||||||
<label id="kick-warning" class="setting-attribute"><br><i>Stream info only available when live — Showing last known stream title</i></label>
|
<label id="kick-warning" class="setting-attribute"><br><i>Stream info only available when live — Showing
|
||||||
|
last known stream title</i></label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="broadcast-buttons">
|
<div id="broadcast-buttons">
|
||||||
<button id="broadcast-stream-button" class="icon-button" title="Open Stream"><img class="button-icon" src="https://api.iconify.design/streamline:button-play-solid.svg?color=%23ffffff"></button>
|
<button id="broadcast-stream-button" class="icon-button" title="Open Stream"><img class="button-icon"
|
||||||
<button id="broadcast-dashboard-button" class="icon-button" title="Dashboard"><img class="button-icon" src="https://api.iconify.design/gridicons:popout.svg?color=%23ffffff"></button>
|
src="https://api.iconify.design/streamline:button-play-solid.svg?color=%23ffffff"></button>
|
||||||
|
<button id="broadcast-dashboard-button" class="icon-button" title="Dashboard"><img class="button-icon"
|
||||||
|
src="https://api.iconify.design/gridicons:popout.svg?color=%23ffffff"></button>
|
||||||
<button id="broadcast-edit-button" class="icon-button flip-that-shit-homie" title="Edit">✎</button>
|
<button id="broadcast-edit-button" class="icon-button flip-that-shit-homie" title="Edit">✎</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -106,10 +106,17 @@ async function AddBroadcast(data) {
|
|||||||
const existingDiv = broadcastList.querySelector(`#${data.id}`);
|
const existingDiv = broadcastList.querySelector(`#${data.id}`);
|
||||||
|
|
||||||
// Create a new instance of the template
|
// Create a new instance of the template
|
||||||
const instance = existingDiv ? existingDiv : template.content.cloneNode(true);
|
let instance;
|
||||||
|
|
||||||
|
if (existingDiv)
|
||||||
|
instance = existingDiv;
|
||||||
|
else {
|
||||||
|
instance = template.content.firstElementChild.cloneNode(true);
|
||||||
|
instance.id = data.id;
|
||||||
|
broadcastList.appendChild(instance);
|
||||||
|
}
|
||||||
|
|
||||||
// Get divs
|
// Get divs
|
||||||
const broadcastEl = instance.querySelector('.broadcast');
|
|
||||||
const platformIconEl = instance.querySelector('#platform-icon');
|
const platformIconEl = instance.querySelector('#platform-icon');
|
||||||
const titleEl = instance.querySelector('#broadcast-title');
|
const titleEl = instance.querySelector('#broadcast-title');
|
||||||
const categoryEl = instance.querySelector('#broadcast-category');
|
const categoryEl = instance.querySelector('#broadcast-category');
|
||||||
@@ -118,21 +125,6 @@ async function AddBroadcast(data) {
|
|||||||
const dashboardButtonEl = instance.querySelector('#broadcast-dashboard-button');
|
const dashboardButtonEl = instance.querySelector('#broadcast-dashboard-button');
|
||||||
const editButtonEl = instance.querySelector('#broadcast-edit-button');
|
const editButtonEl = instance.querySelector('#broadcast-edit-button');
|
||||||
|
|
||||||
// Set properties
|
|
||||||
if (!existingDiv)
|
|
||||||
broadcastEl.id = data.id;
|
|
||||||
|
|
||||||
// Set the platform icon
|
|
||||||
platformIconEl.src = `icons/platforms/${data.platform}.png`;
|
|
||||||
|
|
||||||
// Set the stream title
|
|
||||||
if (data.title)
|
|
||||||
titleEl.textContent = data.title;
|
|
||||||
|
|
||||||
// Set the stream category
|
|
||||||
if (data.category)
|
|
||||||
categoryEl.textContent = data.category;
|
|
||||||
|
|
||||||
// Streamer.bot does not provide title/category for Kick, so pull from API
|
// Streamer.bot does not provide title/category for Kick, so pull from API
|
||||||
if (data.platform == 'kick')
|
if (data.platform == 'kick')
|
||||||
{
|
{
|
||||||
@@ -142,14 +134,14 @@ async function AddBroadcast(data) {
|
|||||||
// The current title is only provided if the stream if currently live
|
// The current title is only provided if the stream if currently live
|
||||||
if (response_data.livestream)
|
if (response_data.livestream)
|
||||||
{
|
{
|
||||||
titleEl.textContent = response_data.livestream.session_title;
|
data.title = response_data.livestream.session_title;
|
||||||
categoryEl.textContent = response_data.livestream.categories[0].name;
|
data.category = response_data.livestream.categories[0].name;
|
||||||
kickWarningEl.style.display = 'none';
|
kickWarningEl.style.display = 'none';
|
||||||
}
|
}
|
||||||
else if (response_data.previous_livestreams)
|
else if (response_data.previous_livestreams.length > 0)
|
||||||
{
|
{
|
||||||
titleEl.textContent = response_data.previous_livestreams[0].session_title;
|
data.title = response_data.previous_livestreams[0].session_title;
|
||||||
categoryEl.textContent = response_data.previous_livestreams[0].categories[0].name;
|
data.category = response_data.previous_livestreams[0].categories[0].name;
|
||||||
kickWarningEl.style.display = 'inline';
|
kickWarningEl.style.display = 'inline';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -158,6 +150,37 @@ async function AddBroadcast(data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flash green to show that it updated
|
||||||
|
if (titleEl.textContent != data.title || categoryEl.textContent != data.category)
|
||||||
|
{
|
||||||
|
instance.style.backgroundColor = getComputedStyle(document.documentElement).getPropertyValue('--confirm-flash');
|
||||||
|
setTimeout(() => {
|
||||||
|
instance.style.backgroundColor = '';
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the platform icon
|
||||||
|
platformIconEl.src = `icons/platforms/${data.platform}.png`;
|
||||||
|
|
||||||
|
// Special logo for YouTube shorts
|
||||||
|
if (data.platform == 'youtube') {
|
||||||
|
const targets = ["vertical", "shorts"];
|
||||||
|
|
||||||
|
const isShort = data.tags.some(item =>
|
||||||
|
targets.some(target => item.toLowerCase() === target.toLowerCase())
|
||||||
|
);
|
||||||
|
if (isShort)
|
||||||
|
platformIconEl.src = `icons/platforms/youtube-shorts.png`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the stream title
|
||||||
|
if (data.title)
|
||||||
|
titleEl.textContent = data.title;
|
||||||
|
|
||||||
|
// Set the stream category
|
||||||
|
if (data.category)
|
||||||
|
categoryEl.textContent = data.category;
|
||||||
|
|
||||||
streamButtonEl.onclick = function() {
|
streamButtonEl.onclick = function() {
|
||||||
//window.open(data.streamUrl, '_blank');
|
//window.open(data.streamUrl, '_blank');
|
||||||
OpenURL(data.streamUrl);
|
OpenURL(data.streamUrl);
|
||||||
@@ -171,29 +194,31 @@ async function AddBroadcast(data) {
|
|||||||
editButtonEl.onclick = function() {
|
editButtonEl.onclick = function() {
|
||||||
switch (data.platform) {
|
switch (data.platform) {
|
||||||
case 'twitch':
|
case 'twitch':
|
||||||
document.getElementById('update-twitch-title-input').value = titleEl.textContent;
|
document.getElementById('twitch-title-input').value = data.title;
|
||||||
document.getElementById('update-twitch-category-input').value = categoryEl.textContent;
|
document.getElementById('twitch-category-input').value = data.category;
|
||||||
|
document.getElementById('twitch-tags-input').value = data.tags.join(", ");
|
||||||
|
ValidateTwitchDialog();
|
||||||
updateTwitchDialog.style.display = "flex";
|
updateTwitchDialog.style.display = "flex";
|
||||||
break;
|
break;
|
||||||
case 'kick':
|
case 'kick':
|
||||||
document.getElementById('update-kick-title-input').value = titleEl.textContent;
|
document.getElementById('kick-title-input').value = titleEl.textContent;
|
||||||
document.getElementById('update-kick-category-input').value = categoryEl.textContent;
|
document.getElementById('kick-category-input').value = categoryEl.textContent;
|
||||||
|
ValidateKickDialog();
|
||||||
updateKickDialog.style.display = "flex";
|
updateKickDialog.style.display = "flex";
|
||||||
break;
|
break;
|
||||||
case 'youtube':
|
case 'youtube':
|
||||||
currentBroadcastId = broadcastEl.id;
|
currentBroadcastId = data.id;
|
||||||
document.getElementById('update-youtube-title-input').value = data.title;
|
document.getElementById('youtube-title-input').value = data.title;
|
||||||
document.getElementById('update-youtube-description-input').value = data.description;
|
document.getElementById('youtube-description-input').value = data.description;
|
||||||
document.getElementById('update-youtube-category-input').value = data.category;
|
document.getElementById('youtube-category-input').value = data.category;
|
||||||
document.getElementById('update-youtube-privacy-select').value = data.privacy;
|
document.getElementById('youtube-tags-input').value = data.tags.join(", ");
|
||||||
|
document.getElementById('youtube-privacy-select').value = data.privacy;
|
||||||
|
ValidateYouTubeDialog();
|
||||||
updateYouTubeDialog.style.display = "flex";
|
updateYouTubeDialog.style.display = "flex";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
blurLayer.style.display = "block";
|
blurLayer.style.display = "block";
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!existingDiv)
|
|
||||||
broadcastList.appendChild(instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -216,8 +241,6 @@ async function OpenURL(url) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////
|
///////////////////////
|
||||||
// PAGE INTERACTIONS //
|
// PAGE INTERACTIONS //
|
||||||
///////////////////////
|
///////////////////////
|
||||||
@@ -254,8 +277,8 @@ async function UpdateAllSubmit() {
|
|||||||
},
|
},
|
||||||
args = {
|
args = {
|
||||||
platform: 'all',
|
platform: 'all',
|
||||||
title: document.getElementById('update-all-title-input').value,
|
title: document.getElementById('all-title-input').value,
|
||||||
category: document.getElementById('update-all-category-input').value
|
category: document.getElementById('all-category-input').value
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -269,9 +292,9 @@ async function UpdateTwitchSubmit() {
|
|||||||
},
|
},
|
||||||
args = {
|
args = {
|
||||||
platform: 'twitch',
|
platform: 'twitch',
|
||||||
title: document.getElementById('update-twitch-title-input').value,
|
title: document.getElementById('twitch-title-input').value,
|
||||||
category: document.getElementById('update-twitch-category-input').value,
|
category: document.getElementById('twitch-category-input').value,
|
||||||
tags: document.getElementById('update-twitch-tags-input').value
|
tags: document.getElementById('twitch-tags-input').value
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -285,8 +308,8 @@ async function UpdateKickSubmit() {
|
|||||||
},
|
},
|
||||||
args = {
|
args = {
|
||||||
platform: 'kick',
|
platform: 'kick',
|
||||||
title: document.getElementById('update-kick-title-input').value,
|
title: document.getElementById('kick-title-input').value,
|
||||||
category: document.getElementById('update-kick-category-input').value
|
category: document.getElementById('kick-category-input').value
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -300,11 +323,11 @@ async function UpdateYouTubeSubmit() {
|
|||||||
},
|
},
|
||||||
args = {
|
args = {
|
||||||
platform: 'youtube',
|
platform: 'youtube',
|
||||||
title: document.getElementById('update-youtube-title-input').value,
|
title: document.getElementById('youtube-title-input').value,
|
||||||
description: document.getElementById('update-youtube-description-input').value,
|
description: document.getElementById('youtube-description-input').value,
|
||||||
category: document.getElementById('update-youtube-category-input').value,
|
category: document.getElementById('youtube-category-input').value,
|
||||||
tags: document.getElementById('update-youtube-tags-input').value,
|
tags: document.getElementById('youtube-tags-input').value,
|
||||||
privacy: document.getElementById('update-youtube-privacy-select').value,
|
privacy: document.getElementById('youtube-privacy-select').value,
|
||||||
broadcastId: currentBroadcastId
|
broadcastId: currentBroadcastId
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -314,6 +337,204 @@ async function UpdateYouTubeSubmit() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// DATA VALIDATION //
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
const GLOBAL_TITLE_MAX = 100;
|
||||||
|
const TWITCH_TITLE_MAX = 140;
|
||||||
|
const TWITCH_TAGS_MAX = 10;
|
||||||
|
const KICK_TITLE_MAX = 100;
|
||||||
|
const YOUTUBE_TITLE_MAX = 100;
|
||||||
|
const YOUTUBE_DESCRIPTION_MAX = 5000;
|
||||||
|
const YOUTUBE_TAGS_MAX = 500;
|
||||||
|
|
||||||
|
const allTitleInput = document.getElementById("all-title-input");
|
||||||
|
const twitchTitleInput = document.getElementById("twitch-title-input");
|
||||||
|
const twitchTagsInput = document.getElementById("twitch-tags-input");
|
||||||
|
const kickTitleInput = document.getElementById("kick-title-input");
|
||||||
|
const youtubeTitleInput = document.getElementById("youtube-title-input");
|
||||||
|
const youtubeDescriptionInput = document.getElementById("youtube-description-input");
|
||||||
|
const youtubeTagsInput = document.getElementById("youtube-tags-input");
|
||||||
|
|
||||||
|
// Function to update char count and handle validation
|
||||||
|
function ValidateUpdateAllDialog() {
|
||||||
|
// Get references to elements
|
||||||
|
const allTitleCharLimit = document.getElementById('all-title-char-limit');
|
||||||
|
const allCharCount = document.getElementById('all-title-char-count');
|
||||||
|
const allTitleCharMax = document.getElementById('all-title-char-max');
|
||||||
|
const allUpdateButton = document.getElementById('all-submit-button');
|
||||||
|
|
||||||
|
// Validate title field
|
||||||
|
const currentLength = allTitleInput.value.length;
|
||||||
|
allCharCount.textContent = currentLength;
|
||||||
|
allTitleCharMax.textContent = GLOBAL_TITLE_MAX;
|
||||||
|
|
||||||
|
if (currentLength > GLOBAL_TITLE_MAX)
|
||||||
|
allTitleCharLimit.style.color = getComputedStyle(document.documentElement).getPropertyValue('--error-text-color');
|
||||||
|
else
|
||||||
|
allTitleCharLimit.style.color = ""; // reset to default
|
||||||
|
|
||||||
|
// Set button interactability (yes, that is a word — look it up)
|
||||||
|
if (currentLength > GLOBAL_TITLE_MAX)
|
||||||
|
allUpdateButton.disabled = true;
|
||||||
|
else
|
||||||
|
allUpdateButton.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update char count and handle validation
|
||||||
|
function ValidateTwitchDialog() {
|
||||||
|
// Get references to elements
|
||||||
|
const twitchTitleCharLimit = document.getElementById('twitch-title-char-limit');
|
||||||
|
const twitchCharCount = document.getElementById('twitch-title-char-count');
|
||||||
|
const twitchTitleCharMax = document.getElementById('twitch-title-char-max');
|
||||||
|
const twitchTagsCharLimit = document.getElementById('twitch-tags-char-limit');
|
||||||
|
const twitchTagsCharCount = document.getElementById('twitch-tags-char-count');
|
||||||
|
const twitchTagsCharMax = document.getElementById('twitch-tags-char-max');
|
||||||
|
const twitchTagsTooLongWarning = document.getElementById('twitch-tags-too-long-warning');
|
||||||
|
const twitchUpdateButton = document.getElementById('twitch-submit-button');
|
||||||
|
|
||||||
|
// Validate title field
|
||||||
|
const currentLength = twitchTitleInput.value.length;
|
||||||
|
twitchCharCount.textContent = currentLength;
|
||||||
|
twitchTitleCharMax.textContent = TWITCH_TITLE_MAX;
|
||||||
|
|
||||||
|
if (currentLength > TWITCH_TITLE_MAX)
|
||||||
|
twitchTitleCharLimit.style.color = getComputedStyle(document.documentElement).getPropertyValue('--error-text-color');
|
||||||
|
else
|
||||||
|
twitchTitleCharLimit.style.color = ""; // reset to default
|
||||||
|
|
||||||
|
// Validate tags field
|
||||||
|
// Split by comma, trim each tag, sum lengths
|
||||||
|
const tagsArray = twitchTagsInput.value
|
||||||
|
.split(',')
|
||||||
|
.map(tag => tag.trim())
|
||||||
|
.filter(tag => tag.length > 0);
|
||||||
|
|
||||||
|
const tagsLength = tagsArray.length;
|
||||||
|
twitchTagsCharCount.textContent = tagsLength;
|
||||||
|
twitchTagsCharMax.textContent = TWITCH_TAGS_MAX;
|
||||||
|
|
||||||
|
if (tagsLength > TWITCH_TAGS_MAX)
|
||||||
|
twitchTagsCharLimit.style.color = getComputedStyle(document.documentElement).getPropertyValue('--error-text-color');
|
||||||
|
else
|
||||||
|
twitchTagsCharLimit.style.color = ""; // reset to default
|
||||||
|
|
||||||
|
// Also check that each tag is under 25 characters
|
||||||
|
const hasLongTag = tagsArray.some(tag => tag.length > 25);
|
||||||
|
if (hasLongTag) {
|
||||||
|
twitchTagsTooLongWarning.style.display = 'inline';
|
||||||
|
twitchTagsCharLimit.style.color = getComputedStyle(document.documentElement).getPropertyValue('--error-text-color');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
twitchTagsTooLongWarning.style.display = 'none';
|
||||||
|
twitchTagsCharLimit.style.color = ""; // reset to default
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set button interactability (yes, that is a word — look it up)
|
||||||
|
if (currentLength > TWITCH_TITLE_MAX || tagsLength > TWITCH_TAGS_MAX || hasLongTag)
|
||||||
|
twitchUpdateButton.disabled = true;
|
||||||
|
else
|
||||||
|
twitchUpdateButton.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update char count and handle validation
|
||||||
|
function ValidateKickDialog() {
|
||||||
|
// Get references to elements
|
||||||
|
const kickTitleCharLimit = document.getElementById('kick-title-char-limit');
|
||||||
|
const kickCharCount = document.getElementById('kick-title-char-count');
|
||||||
|
const kickTitleCharMax = document.getElementById('kick-title-char-max');
|
||||||
|
const kickUpdateButton = document.getElementById('kick-submit-button');
|
||||||
|
|
||||||
|
// Validate title field
|
||||||
|
const currentLength = kickTitleInput.value.length;
|
||||||
|
kickCharCount.textContent = currentLength;
|
||||||
|
kickTitleCharMax.textContent = KICK_TITLE_MAX;
|
||||||
|
|
||||||
|
if (currentLength > KICK_TITLE_MAX)
|
||||||
|
kickTitleCharLimit.style.color = getComputedStyle(document.documentElement).getPropertyValue('--error-text-color');
|
||||||
|
else
|
||||||
|
kickTitleCharLimit.style.color = ""; // reset to default
|
||||||
|
|
||||||
|
// Set button interactability (yes, that is a word — look it up)
|
||||||
|
if (currentLength > KICK_TITLE_MAX)
|
||||||
|
kickUpdateButton.disabled = true;
|
||||||
|
else
|
||||||
|
kickUpdateButton.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ValidateYouTubeDialog() {
|
||||||
|
// Get references to elements
|
||||||
|
const youtubeTitleCharLimit = document.getElementById('youtube-title-char-limit');
|
||||||
|
const youtubeTitleCharCount = document.getElementById('youtube-title-char-count');
|
||||||
|
const youtubeTitleCharMax = document.getElementById('youtube-title-char-max');
|
||||||
|
const youtubeDescriptionCharLimit = document.getElementById('youtube-description-char-limit');
|
||||||
|
const youtubeDescriptionCharCount = document.getElementById('youtube-description-char-count');
|
||||||
|
const youtubeDescriptionCharMax = document.getElementById('youtube-description-char-max');
|
||||||
|
const youtubeTagsCharLimit = document.getElementById('youtube-tags-char-limit');
|
||||||
|
const youtubeTagsCharCount = document.getElementById('youtube-tags-char-count');
|
||||||
|
const youtubeTagsCharMax = document.getElementById('youtube-tags-char-max');
|
||||||
|
const youtubeUpdateButton = document.getElementById('youtube-submit-button');
|
||||||
|
|
||||||
|
// Validate title field
|
||||||
|
const titleLength = youtubeTitleInput.value.length;
|
||||||
|
youtubeTitleCharCount.textContent = titleLength;
|
||||||
|
youtubeTitleCharMax.textContent = YOUTUBE_TITLE_MAX;
|
||||||
|
|
||||||
|
if (titleLength > YOUTUBE_TITLE_MAX)
|
||||||
|
youtubeTitleCharLimit.style.color = getComputedStyle(document.documentElement).getPropertyValue('--error-text-color');
|
||||||
|
else
|
||||||
|
youtubeTitleCharLimit.style.color = ""; // reset to default
|
||||||
|
|
||||||
|
// Validate description field
|
||||||
|
const descriptionLength = youtubeDescriptionInput.value.length;
|
||||||
|
youtubeDescriptionCharCount.textContent = descriptionLength;
|
||||||
|
youtubeDescriptionCharMax.textContent = YOUTUBE_DESCRIPTION_MAX;
|
||||||
|
|
||||||
|
if (descriptionLength > YOUTUBE_DESCRIPTION_MAX)
|
||||||
|
youtubeDescriptionCharLimit.style.color = getComputedStyle(document.documentElement).getPropertyValue('--error-text-color');
|
||||||
|
else
|
||||||
|
youtubeDescriptionCharLimit.style.color = ""; // reset to default
|
||||||
|
|
||||||
|
// Validate tags field
|
||||||
|
// Split by comma, trim each tag, sum lengths
|
||||||
|
const tagsArray = youtubeTagsInput.value
|
||||||
|
.split(',')
|
||||||
|
.map(tag => tag.trim())
|
||||||
|
.filter(tag => tag.length > 0);
|
||||||
|
|
||||||
|
const tagsLength = tagsArray.reduce((sum, tag) => sum + tag.length, 0) + (tagsArray.length > 0 ? tagsArray.length - 1 : 0);
|
||||||
|
youtubeTagsCharCount.textContent = tagsLength;
|
||||||
|
youtubeTagsCharMax.textContent = YOUTUBE_TAGS_MAX;
|
||||||
|
|
||||||
|
if (tagsLength > YOUTUBE_TAGS_MAX)
|
||||||
|
youtubeTagsCharLimit.style.color = getComputedStyle(document.documentElement).getPropertyValue('--error-text-color');
|
||||||
|
else
|
||||||
|
youtubeTagsCharLimit.style.color = ""; // reset to default
|
||||||
|
|
||||||
|
// Set button interactability (yes, that is a word — look it up)
|
||||||
|
if (titleLength > YOUTUBE_TITLE_MAX || descriptionLength > YOUTUBE_DESCRIPTION_MAX || tagsLength > YOUTUBE_TAGS_MAX)
|
||||||
|
youtubeUpdateButton.disabled = true;
|
||||||
|
else
|
||||||
|
youtubeUpdateButton.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach event listener
|
||||||
|
allTitleInput.addEventListener("input", ValidateUpdateAllDialog);
|
||||||
|
twitchTitleInput.addEventListener("input", ValidateTwitchDialog);
|
||||||
|
twitchTagsInput.addEventListener("input", ValidateTwitchDialog);
|
||||||
|
kickTitleInput.addEventListener("input", ValidateKickDialog);
|
||||||
|
youtubeTitleInput.addEventListener("input", ValidateYouTubeDialog);
|
||||||
|
youtubeDescriptionInput.addEventListener("input", ValidateYouTubeDialog);
|
||||||
|
youtubeTagsInput.addEventListener("input", ValidateYouTubeDialog);
|
||||||
|
|
||||||
|
// Initial check (in case the input has prefilled text)
|
||||||
|
ValidateUpdateAllDialog();
|
||||||
|
ValidateTwitchDialog();
|
||||||
|
ValidateKickDialog();
|
||||||
|
ValidateYouTubeDialog();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ button {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
|
|
||||||
|
transition: 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.broadcast-info {
|
.broadcast-info {
|
||||||
@@ -74,3 +76,10 @@ button {
|
|||||||
#youtube-warning {
|
#youtube-warning {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.char-limit {
|
||||||
|
margin-left: auto;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 0.8em;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user