mirror of
https://github.com/tubearchivist/tubearchivist-frontend.git
synced 2024-12-22 18:00:17 +00:00
chore: add external js files
This commit is contained in:
parent
d880f95c44
commit
eec288af5f
148
tubearchivist/www/public/js/cast-videos.js
Normal file
148
tubearchivist/www/public/js/cast-videos.js
Normal file
@ -0,0 +1,148 @@
|
||||
function initializeCastApi() {
|
||||
cast.framework.CastContext.getInstance().setOptions({
|
||||
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, // Use built in reciver app on cast device, see https://developers.google.com/cast/docs/styled_receiver if you want to be able to add a theme, splash screen or watermark. Has a $5 one time fee.
|
||||
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
|
||||
});
|
||||
|
||||
var player = new cast.framework.RemotePlayer();
|
||||
var playerController = new cast.framework.RemotePlayerController(player);
|
||||
|
||||
// Add event listerner to check if a connection to a cast device is initiated
|
||||
playerController.addEventListener(
|
||||
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED, function() {
|
||||
castConnectionChange(player)
|
||||
}
|
||||
);
|
||||
playerController.addEventListener(
|
||||
cast.framework.RemotePlayerEventType.CURRENT_TIME_CHANGED, function() {
|
||||
castVideoProgress(player)
|
||||
}
|
||||
);
|
||||
playerController.addEventListener(
|
||||
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED, function() {
|
||||
castVideoPaused(player)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function castConnectionChange(player) {
|
||||
// If cast connection is initialized start cast
|
||||
if (player.isConnected) {
|
||||
// console.log("Cast Connected.");
|
||||
castStart();
|
||||
} else if (!player.isConnected) {
|
||||
// console.log("Cast Disconnected.");
|
||||
}
|
||||
}
|
||||
|
||||
function castVideoProgress(player) {
|
||||
var videoId = getVideoPlayerVideoId();
|
||||
if (player.mediaInfo.contentId.includes(videoId)) {
|
||||
var currentTime = player.currentTime;
|
||||
var duration = player.duration;
|
||||
if ((currentTime % 10) <= 1.0 && currentTime != 0 && duration != 0) { // Check progress every 10 seconds or else progress is checked a few times a second
|
||||
postVideoProgress(videoId, currentTime);
|
||||
setProgressBar(videoId, currentTime, duration);
|
||||
if (!getVideoPlayerWatchStatus()) { // Check if video is already marked as watched
|
||||
if (watchedThreshold(currentTime, duration)) {
|
||||
isWatched(videoId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function castVideoPaused(player) {
|
||||
var videoId = getVideoPlayerVideoId();
|
||||
var currentTime = player.currentTime;
|
||||
var duration = player.duration;
|
||||
if (player.mediaInfo != null) {
|
||||
if (player.mediaInfo.contentId.includes(videoId)) {
|
||||
if (currentTime != 0 && duration != 0) {
|
||||
postVideoProgress(videoId, currentTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function castStart() {
|
||||
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
|
||||
// Check if there is already media playing on the cast target to prevent recasting on page reload or switching to another video page
|
||||
if (!castSession.getMediaSession()) {
|
||||
var videoId = getVideoPlayerVideoId();
|
||||
var videoData = getVideoData(videoId);
|
||||
var contentId = getURL() + videoData.data.media_url;
|
||||
var contentTitle = videoData.data.title;
|
||||
var contentImage = getURL() + videoData.data.vid_thumb_url;
|
||||
|
||||
contentType = 'video/mp4'; // Set content type, only videos right now so it is hard coded
|
||||
contentCurrentTime = getVideoPlayerCurrentTime(); // Get video's current position
|
||||
contentActiveSubtitle = [];
|
||||
// Check if a subtitle is turned on.
|
||||
for (var i = 0; i < getVideoPlayer().textTracks.length; i++) {
|
||||
if (getVideoPlayer().textTracks[i].mode == "showing") {
|
||||
contentActiveSubtitle =[i + 1];
|
||||
}
|
||||
}
|
||||
contentSubtitles = [];
|
||||
var videoSubtitles = videoData.data.subtitles; // Array of subtitles
|
||||
if (typeof(videoSubtitles) != 'undefined' && videoData.config.downloads.subtitle) {
|
||||
for (var i = 0; i < videoSubtitles.length; i++) {
|
||||
subtitle = new chrome.cast.media.Track(i, chrome.cast.media.TrackType.TEXT);
|
||||
subtitle.trackContentId = videoSubtitles[i].media_url;
|
||||
subtitle.trackContentType = 'text/vtt';
|
||||
subtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
|
||||
subtitle.name = videoSubtitles[i].name;
|
||||
subtitle.language = videoSubtitles[i].lang;
|
||||
subtitle.customData = null;
|
||||
contentSubtitles.push(subtitle);
|
||||
}
|
||||
}
|
||||
|
||||
mediaInfo = new chrome.cast.media.MediaInfo(contentId, contentType); // Create MediaInfo var that contains url and content type
|
||||
// mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED; // Set type of stream, BUFFERED, LIVE, OTHER
|
||||
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); // Create metadata var and add it to MediaInfo
|
||||
mediaInfo.metadata.title = contentTitle.replace("&", "&"); // Set the video title
|
||||
mediaInfo.metadata.images = [new chrome.cast.Image(contentImage)]; // Set the video thumbnail
|
||||
// mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
|
||||
mediaInfo.tracks = contentSubtitles;
|
||||
|
||||
var request = new chrome.cast.media.LoadRequest(mediaInfo); // Create request with the previously set MediaInfo.
|
||||
// request.queueData = new chrome.cast.media.QueueData(); // See https://developers.google.com/cast/docs/reference/web_sender/chrome.cast.media.QueueData for playlist support.
|
||||
request.currentTime = shiftCurrentTime(contentCurrentTime); // Set video start position based on the browser video position
|
||||
request.activeTrackIds = contentActiveSubtitle; // Set active subtitle based on video player
|
||||
// request.autoplay = false; // Set content to auto play, true by default
|
||||
castSession.loadMedia(request).then(
|
||||
function() {
|
||||
castSuccessful();
|
||||
},
|
||||
function() {
|
||||
castFailed(errorCode);
|
||||
}
|
||||
); // Send request to cast device
|
||||
}
|
||||
}
|
||||
|
||||
function shiftCurrentTime(contentCurrentTime) { // Shift media back 3 seconds to prevent missing some of the content
|
||||
if (contentCurrentTime > 5) {
|
||||
return(contentCurrentTime - 3);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
function castSuccessful() {
|
||||
// console.log('Cast Successful.');
|
||||
getVideoPlayer().pause(); // Pause browser video on successful cast
|
||||
}
|
||||
|
||||
function castFailed(errorCode) {
|
||||
console.log('Error code: ' + errorCode);
|
||||
}
|
||||
|
||||
window['__onGCastApiAvailable'] = function(isAvailable) {
|
||||
if (isAvailable) {
|
||||
initializeCastApi();
|
||||
}
|
||||
}
|
106
tubearchivist/www/public/js/progress.js
Normal file
106
tubearchivist/www/public/js/progress.js
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Handle multi channel notifications
|
||||
*
|
||||
*/
|
||||
|
||||
checkMessages()
|
||||
|
||||
// page map to notification status
|
||||
const messageTypes = {
|
||||
"download": ["message:download", "message:add", "message:rescan", "message:playlistscan"],
|
||||
"channel": ["message:subchannel"],
|
||||
"channel_id": ["message:playlistscan"],
|
||||
"playlist": ["message:subplaylist"],
|
||||
"setting": ["message:setting"]
|
||||
}
|
||||
|
||||
// start to look for messages
|
||||
function checkMessages() {
|
||||
var notifications = document.getElementById("notifications");
|
||||
if (notifications) {
|
||||
var dataOrigin = notifications.getAttribute("data");
|
||||
getMessages(dataOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
// get messages for page on timer
|
||||
function getMessages(dataOrigin) {
|
||||
fetch('/progress/').then(response => {
|
||||
return response.json();
|
||||
}).then(responseData => {
|
||||
var messages = buildMessage(responseData, dataOrigin);
|
||||
if (messages.length > 0) {
|
||||
// restart itself
|
||||
setTimeout(function() {
|
||||
getMessages(dataOrigin);
|
||||
}, 3000);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// make div for all messages, return relevant
|
||||
function buildMessage(responseData, dataOrigin) {
|
||||
// filter relevan messages
|
||||
var allMessages = responseData["messages"];
|
||||
var messages = allMessages.filter(function(value) {
|
||||
return messageTypes[dataOrigin].includes(value["status"])
|
||||
}, dataOrigin);
|
||||
// build divs
|
||||
var notificationDiv = document.getElementById("notifications");
|
||||
var nots = notificationDiv.childElementCount;
|
||||
notificationDiv.innerHTML = "";
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
var messageData = messages[i];
|
||||
var messageStatus = messageData["status"];
|
||||
var messageBox = document.createElement("div");
|
||||
var title = document.createElement("h3");
|
||||
title.innerHTML = messageData["title"];
|
||||
var message = document.createElement("p");
|
||||
message.innerHTML = messageData["message"];
|
||||
messageBox.appendChild(title);
|
||||
messageBox.appendChild(message);
|
||||
messageBox.classList.add(messageData["level"], "notification");
|
||||
notificationDiv.appendChild(messageBox);
|
||||
if (messageStatus === "message:download") {
|
||||
checkDownloadIcons();
|
||||
};
|
||||
};
|
||||
// reload page when no more notifications
|
||||
if (nots > 0 && messages.length === 0) {
|
||||
location.reload();
|
||||
};
|
||||
return messages
|
||||
}
|
||||
|
||||
// check if download icons are needed
|
||||
function checkDownloadIcons() {
|
||||
var iconBox = document.getElementById("downloadControl");
|
||||
if (iconBox.childElementCount === 0) {
|
||||
var downloadIcons = buildDownloadIcons();
|
||||
iconBox.appendChild(downloadIcons);
|
||||
};
|
||||
}
|
||||
|
||||
// add dl control icons
|
||||
function buildDownloadIcons() {
|
||||
var downloadIcons = document.createElement('div');
|
||||
downloadIcons.classList = 'dl-control-icons';
|
||||
// stop icon
|
||||
var stopIcon = document.createElement('img');
|
||||
stopIcon.setAttribute('id', "stop-icon");
|
||||
stopIcon.setAttribute('title', "Stop Download Queue");
|
||||
stopIcon.setAttribute('src', "/static/img/icon-stop.svg");
|
||||
stopIcon.setAttribute('alt', "stop icon");
|
||||
stopIcon.setAttribute('onclick', 'stopQueue()');
|
||||
// kill icon
|
||||
var killIcon = document.createElement('img');
|
||||
killIcon.setAttribute('id', "kill-icon");
|
||||
killIcon.setAttribute('title', "Kill Download Queue");
|
||||
killIcon.setAttribute('src', "/static/img/icon-close.svg");
|
||||
killIcon.setAttribute('alt', "kill icon");
|
||||
killIcon.setAttribute('onclick', 'killQueue()');
|
||||
// stich together
|
||||
downloadIcons.appendChild(stopIcon);
|
||||
downloadIcons.appendChild(killIcon);
|
||||
return downloadIcons
|
||||
}
|
902
tubearchivist/www/public/js/script.js
Normal file
902
tubearchivist/www/public/js/script.js
Normal file
@ -0,0 +1,902 @@
|
||||
|
||||
function sortChange(sortValue) {
|
||||
var payload = JSON.stringify({'sort_order': sortValue});
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
return false;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// Updates video watch status when passed a video id and it's current state (ex if the video was unwatched but you want to mark it as watched you will pass "unwatched")
|
||||
function updateVideoWatchStatus(input1, videoCurrentWatchStatus) {
|
||||
if (videoCurrentWatchStatus) {
|
||||
videoId = input1;
|
||||
} else if (input1.getAttribute("data-id")) {
|
||||
videoId = input1.getAttribute("data-id");
|
||||
videoCurrentWatchStatus = input1.getAttribute("data-status");
|
||||
}
|
||||
|
||||
postVideoProgress(videoId, 0); // Reset video progress on watched/unwatched;
|
||||
removeProgressBar(videoId);
|
||||
|
||||
if (videoCurrentWatchStatus == "watched") {
|
||||
var watchStatusIndicator = createWatchStatusIndicator(videoId, "unwatched");
|
||||
var payload = JSON.stringify({'un_watched': videoId});
|
||||
sendPost(payload);
|
||||
} else if (videoCurrentWatchStatus == "unwatched") {
|
||||
var watchStatusIndicator = createWatchStatusIndicator(videoId, "watched");
|
||||
var payload = JSON.stringify({'watched': videoId});
|
||||
sendPost(payload);
|
||||
}
|
||||
|
||||
var watchButtons = document.getElementsByClassName("watch-button");
|
||||
for (let i = 0; i < watchButtons.length; i++) {
|
||||
if (watchButtons[i].getAttribute("data-id") == videoId) {
|
||||
watchButtons[i].outerHTML = watchStatusIndicator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a watch status indicator when passed a video id and the videos watch status
|
||||
function createWatchStatusIndicator(videoId, videoWatchStatus) {
|
||||
if (videoWatchStatus == "watched") {
|
||||
var seen = "seen";
|
||||
var title = "Mark as unwatched";
|
||||
} else if (videoWatchStatus == "unwatched") {
|
||||
var seen = "unseen";
|
||||
var title = "Mark as watched";
|
||||
}
|
||||
var watchStatusIndicator = `<img src="/static/img/icon-${seen}.svg" alt="${seen}-icon" data-id="${videoId}" data-status="${videoWatchStatus}" onclick="updateVideoWatchStatus(this)" class="watch-button" title="${title}">`;
|
||||
return watchStatusIndicator;
|
||||
}
|
||||
|
||||
// function isWatched(youtube_id) {
|
||||
// var payload = JSON.stringify({'watched': youtube_id});
|
||||
// sendPost(payload);
|
||||
// var seenIcon = document.createElement('img');
|
||||
// seenIcon.setAttribute('src', "/static/img/icon-seen.svg");
|
||||
// seenIcon.setAttribute('alt', 'seen-icon');
|
||||
// seenIcon.setAttribute('id', youtube_id);
|
||||
// seenIcon.setAttribute('title', "Mark as unwatched");
|
||||
// seenIcon.setAttribute('onclick', "isUnwatched(this.id)");
|
||||
// seenIcon.classList = 'seen-icon';
|
||||
// document.getElementById(youtube_id).replaceWith(seenIcon);
|
||||
// }
|
||||
|
||||
// Removes the progress bar when passed a video id
|
||||
function removeProgressBar(videoId) {
|
||||
setProgressBar(videoId, 0, 1);
|
||||
}
|
||||
|
||||
function isWatchedButton(button) {
|
||||
youtube_id = button.getAttribute("data-id");
|
||||
var payload = JSON.stringify({'watched': youtube_id});
|
||||
button.remove();
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
return false;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// function isUnwatched(youtube_id) {
|
||||
// postVideoProgress(youtube_id, 0); // Reset video progress on unwatched;
|
||||
// var payload = JSON.stringify({'un_watched': youtube_id});
|
||||
// sendPost(payload);
|
||||
// var unseenIcon = document.createElement('img');
|
||||
// unseenIcon.setAttribute('src', "/static/img/icon-unseen.svg");
|
||||
// unseenIcon.setAttribute('alt', 'unseen-icon');
|
||||
// unseenIcon.setAttribute('id', youtube_id);
|
||||
// unseenIcon.setAttribute('title', "Mark as watched");
|
||||
// unseenIcon.setAttribute('onclick', "isWatched(this.id)");
|
||||
// unseenIcon.classList = 'unseen-icon';
|
||||
// document.getElementById(youtube_id).replaceWith(unseenIcon);
|
||||
// }
|
||||
|
||||
function unsubscribe(id_unsub) {
|
||||
var payload = JSON.stringify({'unsubscribe': id_unsub});
|
||||
sendPost(payload);
|
||||
var message = document.createElement('span');
|
||||
message.innerText = "You are unsubscribed.";
|
||||
document.getElementById(id_unsub).replaceWith(message);
|
||||
}
|
||||
|
||||
function subscribe(id_sub) {
|
||||
var payload = JSON.stringify({'subscribe': id_sub});
|
||||
sendPost(payload);
|
||||
var message = document.createElement('span');
|
||||
message.innerText = "You are subscribed.";
|
||||
document.getElementById(id_sub).replaceWith(message);
|
||||
}
|
||||
|
||||
function changeView(image) {
|
||||
var sourcePage = image.getAttribute("data-origin");
|
||||
var newView = image.getAttribute("data-value");
|
||||
var payload = JSON.stringify({'change_view': sourcePage + ":" + newView});
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
return false;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function toggleCheckbox(checkbox) {
|
||||
// pass checkbox id as key and checkbox.checked as value
|
||||
var toggleId = checkbox.id;
|
||||
var toggleVal = checkbox.checked;
|
||||
var payloadDict = {};
|
||||
payloadDict[toggleId] = toggleVal;
|
||||
var payload = JSON.stringify(payloadDict);
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
var currPage = window.location.pathname;
|
||||
window.location.replace(currPage);
|
||||
return false;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// download page buttons
|
||||
function rescanPending() {
|
||||
var payload = JSON.stringify({'rescan_pending': true});
|
||||
animate('rescan-icon', 'rotate-img');
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
checkMessages();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function dlPending() {
|
||||
var payload = JSON.stringify({'dl_pending': true});
|
||||
animate('download-icon', 'bounce-img');
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
checkMessages();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function toIgnore(button) {
|
||||
var youtube_id = button.getAttribute('data-id');
|
||||
var payload = JSON.stringify({'ignore': youtube_id});
|
||||
sendPost(payload);
|
||||
document.getElementById('dl-' + youtube_id).remove();
|
||||
}
|
||||
|
||||
function downloadNow(button) {
|
||||
var youtube_id = button.getAttribute('data-id');
|
||||
var payload = JSON.stringify({'dlnow': youtube_id});
|
||||
sendPost(payload);
|
||||
document.getElementById(youtube_id).remove();
|
||||
setTimeout(function(){
|
||||
checkMessages();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function forgetIgnore(button) {
|
||||
var youtube_id = button.getAttribute('data-id');
|
||||
var payload = JSON.stringify({'forgetIgnore': youtube_id});
|
||||
sendPost(payload);
|
||||
document.getElementById("dl-" + youtube_id).remove();
|
||||
}
|
||||
|
||||
function addSingle(button) {
|
||||
var youtube_id = button.getAttribute('data-id');
|
||||
var payload = JSON.stringify({'addSingle': youtube_id});
|
||||
sendPost(payload);
|
||||
document.getElementById("dl-" + youtube_id).remove();
|
||||
setTimeout(function(){
|
||||
checkMessages();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function deleteQueue(button) {
|
||||
var to_delete = button.getAttribute('data-id');
|
||||
var payload = JSON.stringify({'deleteQueue': to_delete});
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
return false;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function stopQueue() {
|
||||
var payload = JSON.stringify({'queue': 'stop'});
|
||||
sendPost(payload);
|
||||
document.getElementById('stop-icon').remove();
|
||||
}
|
||||
|
||||
function killQueue() {
|
||||
var payload = JSON.stringify({'queue': 'kill'});
|
||||
sendPost(payload);
|
||||
document.getElementById('kill-icon').remove();
|
||||
}
|
||||
|
||||
// settings page buttons
|
||||
function manualImport() {
|
||||
var payload = JSON.stringify({'manual-import': true});
|
||||
sendPost(payload);
|
||||
// clear button
|
||||
var message = document.createElement('p');
|
||||
message.innerText = 'processing import';
|
||||
var toReplace = document.getElementById('manual-import');
|
||||
toReplace.innerHTML = '';
|
||||
toReplace.appendChild(message);
|
||||
}
|
||||
|
||||
function reEmbed() {
|
||||
var payload = JSON.stringify({'re-embed': true});
|
||||
sendPost(payload);
|
||||
// clear button
|
||||
var message = document.createElement('p');
|
||||
message.innerText = 'processing thumbnails';
|
||||
var toReplace = document.getElementById('re-embed');
|
||||
toReplace.innerHTML = '';
|
||||
toReplace.appendChild(message);
|
||||
}
|
||||
|
||||
function dbBackup() {
|
||||
var payload = JSON.stringify({'db-backup': true});
|
||||
sendPost(payload);
|
||||
// clear button
|
||||
var message = document.createElement('p');
|
||||
message.innerText = 'backing up archive';
|
||||
var toReplace = document.getElementById('db-backup');
|
||||
toReplace.innerHTML = '';
|
||||
toReplace.appendChild(message);
|
||||
}
|
||||
|
||||
function dbRestore(button) {
|
||||
var fileName = button.getAttribute("data-id");
|
||||
var payload = JSON.stringify({'db-restore': fileName});
|
||||
sendPost(payload);
|
||||
// clear backup row
|
||||
var message = document.createElement('p');
|
||||
message.innerText = 'restoring from backup';
|
||||
var toReplace = document.getElementById(fileName);
|
||||
toReplace.innerHTML = '';
|
||||
toReplace.appendChild(message);
|
||||
}
|
||||
|
||||
function fsRescan() {
|
||||
var payload = JSON.stringify({'fs-rescan': true});
|
||||
sendPost(payload);
|
||||
// clear button
|
||||
var message = document.createElement('p');
|
||||
message.innerText = 'File system scan in progress';
|
||||
var toReplace = document.getElementById('fs-rescan');
|
||||
toReplace.innerHTML = '';
|
||||
toReplace.appendChild(message);
|
||||
}
|
||||
|
||||
function resetToken() {
|
||||
var payload = JSON.stringify({'reset-token': true});
|
||||
sendPost(payload);
|
||||
var message = document.createElement("p");
|
||||
message.innerText = "Token revoked";
|
||||
document.getElementById("text-reveal").replaceWith(message);
|
||||
}
|
||||
|
||||
// delete from file system
|
||||
function deleteConfirm() {
|
||||
to_show = document.getElementById("delete-button");
|
||||
document.getElementById("delete-item").style.display = 'none';
|
||||
to_show.style.display = "block";
|
||||
}
|
||||
|
||||
function deleteVideo(button) {
|
||||
var to_delete = button.getAttribute("data-id");
|
||||
var to_redirect = button.getAttribute("data-redirect");
|
||||
var payload = JSON.stringify({"delete-video": to_delete});
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
var redirect = "/channel/" + to_redirect;
|
||||
window.location.replace(redirect);
|
||||
return false;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function deleteChannel(button) {
|
||||
var to_delete = button.getAttribute("data-id");
|
||||
var payload = JSON.stringify({"delete-channel": to_delete});
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
window.location.replace("/channel/");
|
||||
return false;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function deletePlaylist(button) {
|
||||
var playlist_id = button.getAttribute("data-id");
|
||||
var playlist_action = button.getAttribute("data-action");
|
||||
var payload = JSON.stringify({
|
||||
"delete-playlist": {
|
||||
"playlist-id": playlist_id,
|
||||
"playlist-action": playlist_action
|
||||
}
|
||||
});
|
||||
sendPost(payload);
|
||||
setTimeout(function(){
|
||||
window.location.replace("/playlist/");
|
||||
return false;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function cancelDelete() {
|
||||
document.getElementById("delete-button").style.display = 'none';
|
||||
document.getElementById("delete-item").style.display = 'block';
|
||||
}
|
||||
|
||||
// player
|
||||
function createPlayer(button) {
|
||||
var videoId = button.getAttribute('data-id');
|
||||
var videoData = getVideoData(videoId);
|
||||
var videoProgress = getVideoProgress(videoId).position;
|
||||
var videoName = videoData.data.title;
|
||||
|
||||
var videoTag = createVideoTag(videoData, videoProgress);
|
||||
|
||||
var playlist = '';
|
||||
var videoPlaylists = videoData.data.playlist; // Array of playlists the video is in
|
||||
if (typeof(videoPlaylists) != 'undefined') {
|
||||
var subbedPlaylists = getSubbedPlaylists(videoPlaylists); // Array of playlist the video is in that are subscribed
|
||||
if (subbedPlaylists.length != 0) {
|
||||
var playlistData = getPlaylistData(subbedPlaylists[0]); // Playlist data for first subscribed playlist
|
||||
var playlistId = playlistData.playlist_id;
|
||||
var playlistName = playlistData.playlist_name;
|
||||
var playlist = `<h5><a href="/playlist/${playlistId}/">${playlistName}</a></h5>`;
|
||||
}
|
||||
}
|
||||
|
||||
var videoViews = formatNumbers(videoData.data.stats.view_count);
|
||||
|
||||
var channelId = videoData.data.channel.channel_id;
|
||||
var channelName = videoData.data.channel.channel_name;
|
||||
|
||||
removePlayer();
|
||||
// document.getElementById(videoId).outerHTML = ''; // Remove watch indicator from video info
|
||||
|
||||
// If cast integration is enabled create cast button
|
||||
var castButton = '';
|
||||
if (videoData.config.application.enable_cast) {
|
||||
var castButton = `<google-cast-launcher id="castbutton"></google-cast-launcher>`;
|
||||
}
|
||||
|
||||
// Watched indicator
|
||||
if (videoData.data.player.watched) {
|
||||
var watchStatusIndicator = createWatchStatusIndicator(videoId, "watched");
|
||||
} else {
|
||||
var watchStatusIndicator = createWatchStatusIndicator(videoId, "unwatched");
|
||||
}
|
||||
|
||||
|
||||
var playerStats = `<div class="thumb-icon player-stats"><img src="/static/img/icon-eye.svg" alt="views icon"><span>${videoViews}</span>`;
|
||||
if (videoData.data.stats.like_count) {
|
||||
var likes = formatNumbers(videoData.data.stats.like_count);
|
||||
playerStats += `<span>|</span><img src="/static/img/icon-thumb.svg" alt="thumbs-up"><span>${likes}</span>`;
|
||||
}
|
||||
if (videoData.data.stats.dislike_count && videoData.config.downloads.integrate_ryd) {
|
||||
var dislikes = formatNumbers(videoData.data.stats.dislike_count);
|
||||
playerStats += `<span>|</span><img class="dislike" src="/static/img/icon-thumb.svg" alt="thumbs-down"><span>${dislikes}</span>`;
|
||||
}
|
||||
playerStats += "</div>";
|
||||
|
||||
const markup = `
|
||||
<div class="video-player" data-id="${videoId}">
|
||||
${videoTag}
|
||||
<div class="player-title boxed-content">
|
||||
<img class="close-button" src="/static/img/icon-close.svg" alt="close-icon" data="${videoId}" onclick="removePlayer()" title="Close player">
|
||||
${watchStatusIndicator}
|
||||
${castButton}
|
||||
${playerStats}
|
||||
<div class="player-channel-playlist">
|
||||
<h3><a href="/channel/${channelId}/">${channelName}</a></h3>
|
||||
${playlist}
|
||||
</div>
|
||||
<a href="/video/${videoId}/"><h2 id="video-title">${videoName}</h2></a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
const divPlayer = document.getElementById("player");
|
||||
divPlayer.innerHTML = markup;
|
||||
}
|
||||
|
||||
// Add video tag to video page when passed a video id, function loaded on page load `video.html (115-117)`
|
||||
function insertVideoTag(videoData, videoProgress) {
|
||||
var videoTag = createVideoTag(videoData, videoProgress);
|
||||
var videoMain = document.getElementsByClassName("video-main");
|
||||
videoMain[0].innerHTML = videoTag;
|
||||
}
|
||||
|
||||
// Generates a video tag with subtitles when passed videoData and videoProgress.
|
||||
function createVideoTag(videoData, videoProgress) {
|
||||
var videoId = videoData.data.youtube_id;
|
||||
var videoUrl = videoData.data.media_url;
|
||||
var videoThumbUrl = videoData.data.vid_thumb_url;
|
||||
var subtitles = '';
|
||||
var videoSubtitles = videoData.data.subtitles; // Array of subtitles
|
||||
if (typeof(videoSubtitles) != 'undefined' && videoData.config.downloads.subtitle) {
|
||||
for (var i = 0; i < videoSubtitles.length; i++) {
|
||||
let label = videoSubtitles[i].name;
|
||||
if (videoSubtitles[i].source == "auto") {
|
||||
label += " - auto";
|
||||
}
|
||||
subtitles += `<track label="${label}" kind="subtitles" srclang="${videoSubtitles[i].lang}" src="${videoSubtitles[i].media_url}">`;
|
||||
}
|
||||
}
|
||||
|
||||
var videoTag = `
|
||||
<video poster="${videoThumbUrl}" ontimeupdate="onVideoProgress()" onpause="onVideoPause()" onended="onVideoEnded()" controls autoplay width="100%" playsinline id="video-item">
|
||||
<source src="${videoUrl}#t=${videoProgress}" type="video/mp4" id="video-source" videoid="${videoId}">
|
||||
${subtitles}
|
||||
</video>
|
||||
`;
|
||||
return videoTag;
|
||||
}
|
||||
|
||||
// Gets video tag
|
||||
function getVideoPlayer() {
|
||||
var videoElement = document.getElementById("video-item");
|
||||
return videoElement;
|
||||
}
|
||||
|
||||
// Gets the video source tag
|
||||
function getVideoPlayerVideoSource() {
|
||||
var videoPlayerVideoSource = document.getElementById("video-source");
|
||||
return videoPlayerVideoSource;
|
||||
}
|
||||
|
||||
// Gets the current progress of the video currently in the player
|
||||
function getVideoPlayerCurrentTime() {
|
||||
var videoElement = getVideoPlayer();
|
||||
if (videoElement != null) {
|
||||
return videoElement.currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the video id of the video currently in the player
|
||||
function getVideoPlayerVideoId() {
|
||||
var videoPlayerVideoSource = getVideoPlayerVideoSource();
|
||||
if (videoPlayerVideoSource != null) {
|
||||
return videoPlayerVideoSource.getAttribute("videoid");
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the duration of the video currently in the player
|
||||
function getVideoPlayerDuration() {
|
||||
var videoElement = getVideoPlayer();
|
||||
if (videoElement != null) {
|
||||
return videoElement.duration;
|
||||
}
|
||||
}
|
||||
|
||||
// Gets current watch status of video based on watch button
|
||||
function getVideoPlayerWatchStatus() {
|
||||
var videoId = getVideoPlayerVideoId();
|
||||
var watched = false;
|
||||
|
||||
var watchButtons = document.getElementsByClassName("watch-button");
|
||||
for (let i = 0; i < watchButtons.length; i++) {
|
||||
if (watchButtons[i].getAttribute("data-id") == videoId && watchButtons[i].getAttribute("data-status") == "watched") {
|
||||
watched = true;
|
||||
}
|
||||
}
|
||||
return watched;
|
||||
}
|
||||
|
||||
// Runs on video playback, marks video as watched if video gets to 90% or higher, sends position to api
|
||||
function onVideoProgress() {
|
||||
var videoId = getVideoPlayerVideoId();
|
||||
var currentTime = getVideoPlayerCurrentTime();
|
||||
var duration = getVideoPlayerDuration();
|
||||
if ((currentTime % 10).toFixed(1) <= 0.2) { // Check progress every 10 seconds or else progress is checked a few times a second
|
||||
postVideoProgress(videoId, currentTime);
|
||||
if (!getVideoPlayerWatchStatus()) { // Check if video is already marked as watched
|
||||
if (watchedThreshold(currentTime, duration)) {
|
||||
updateVideoWatchStatus(videoId, "unwatched");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Runs on video end, marks video as watched
|
||||
function onVideoEnded() {
|
||||
var videoId = getVideoPlayerVideoId();
|
||||
if (!getVideoPlayerWatchStatus()) { // Check if video is already marked as watched
|
||||
updateVideoWatchStatus(videoId, "unwatched");
|
||||
}
|
||||
}
|
||||
|
||||
function watchedThreshold(currentTime, duration) {
|
||||
var watched = false;
|
||||
if (duration <= 1800){ // If video is less than 30 min
|
||||
if ((currentTime / duration) >= 0.90) { // Mark as watched at 90%
|
||||
var watched = true;
|
||||
}
|
||||
} else { // If video is more than 30 min
|
||||
if (currentTime >= (duration - 120)) { // Mark as watched if there is two minutes left
|
||||
var watched = true;
|
||||
}
|
||||
}
|
||||
return watched;
|
||||
}
|
||||
|
||||
// Runs on video pause. Sends current position.
|
||||
function onVideoPause() {
|
||||
var videoId = getVideoPlayerVideoId();
|
||||
var currentTime = getVideoPlayerCurrentTime();
|
||||
postVideoProgress(videoId, currentTime);
|
||||
}
|
||||
|
||||
// Format numbers for frontend
|
||||
function formatNumbers(number) {
|
||||
var numberUnformatted = parseFloat(number);
|
||||
if (numberUnformatted > 999999999) {
|
||||
var numberFormatted = (numberUnformatted / 1000000000).toFixed(1).toString() + "B";
|
||||
} else if (numberUnformatted > 999999) {
|
||||
var numberFormatted = (numberUnformatted / 1000000).toFixed(1).toString() + "M";
|
||||
} else if (numberUnformatted > 999) {
|
||||
var numberFormatted = (numberUnformatted / 1000).toFixed(1).toString() + "K";
|
||||
} else {
|
||||
var numberFormatted = numberUnformatted;
|
||||
}
|
||||
return numberFormatted;
|
||||
}
|
||||
|
||||
// Gets video data when passed video ID
|
||||
function getVideoData(videoId) {
|
||||
var apiEndpoint = "/api/video/" + videoId + "/";
|
||||
var videoData = apiRequest(apiEndpoint, "GET");
|
||||
return videoData;
|
||||
}
|
||||
|
||||
// Gets channel data when passed channel ID
|
||||
function getChannelData(channelId) {
|
||||
var apiEndpoint = "/api/channel/" + channelId + "/";
|
||||
var channelData = apiRequest(apiEndpoint, "GET");
|
||||
return channelData.data;
|
||||
}
|
||||
|
||||
// Gets playlist data when passed playlist ID
|
||||
function getPlaylistData(playlistId) {
|
||||
var apiEndpoint = "/api/playlist/" + playlistId + "/";
|
||||
var playlistData = apiRequest(apiEndpoint, "GET");
|
||||
return playlistData.data;
|
||||
}
|
||||
|
||||
// Get video progress data when passed video ID
|
||||
function getVideoProgress(videoId) {
|
||||
var apiEndpoint = "/api/video/" + videoId + "/progress/";
|
||||
var videoProgress = apiRequest(apiEndpoint, "GET");
|
||||
return videoProgress;
|
||||
}
|
||||
|
||||
// Given an array of playlist ids it returns an array of subbed playlist ids from that list
|
||||
function getSubbedPlaylists(videoPlaylists) {
|
||||
var subbedPlaylists = [];
|
||||
for (var i = 0; i < videoPlaylists.length; i++) {
|
||||
if(getPlaylistData(videoPlaylists[i]).playlist_subscribed) {
|
||||
subbedPlaylists.push(videoPlaylists[i]);
|
||||
}
|
||||
}
|
||||
return subbedPlaylists;
|
||||
}
|
||||
|
||||
// Send video position when given video id and progress in seconds
|
||||
function postVideoProgress(videoId, videoProgress) {
|
||||
var apiEndpoint = "/api/video/" + videoId + "/progress/";
|
||||
var duartion = getVideoPlayerDuration();
|
||||
if (!isNaN(videoProgress) && duartion != 'undefined') {
|
||||
var data = {
|
||||
"position": videoProgress
|
||||
};
|
||||
if (videoProgress == 0) {
|
||||
apiRequest(apiEndpoint, "DELETE");
|
||||
// console.log("Deleting Video Progress for Video ID: " + videoId + ", Progress: " + videoProgress);
|
||||
} else if (!getVideoPlayerWatchStatus()) {
|
||||
apiRequest(apiEndpoint, "POST", data);
|
||||
// console.log("Saving Video Progress for Video ID: " + videoId + ", Progress: " + videoProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Makes api requests when passed an endpoint and method ("GET", "POST", "DELETE")
|
||||
function apiRequest(apiEndpoint, method, data) {
|
||||
const xhttp = new XMLHttpRequest();
|
||||
var sessionToken = getCookie("sessionid");
|
||||
xhttp.open(method, apiEndpoint, false);
|
||||
xhttp.setRequestHeader("X-CSRFToken", getCookie("csrftoken")); // Used for video progress POST requests
|
||||
xhttp.setRequestHeader("Authorization", "Token " + sessionToken);
|
||||
xhttp.setRequestHeader("Content-Type", "application/json");
|
||||
xhttp.send(JSON.stringify(data));
|
||||
return JSON.parse(xhttp.responseText);
|
||||
}
|
||||
|
||||
// Gets origin URL
|
||||
function getURL() {
|
||||
return window.location.origin;
|
||||
}
|
||||
|
||||
function removePlayer() {
|
||||
var currentTime = getVideoPlayerCurrentTime();
|
||||
var duration = getVideoPlayerDuration();
|
||||
var videoId = getVideoPlayerVideoId();
|
||||
postVideoProgress(videoId, currentTime);
|
||||
setProgressBar(videoId, currentTime, duration);
|
||||
var playerElement = document.getElementById('player');
|
||||
if (playerElement.hasChildNodes()) {
|
||||
var youtubeId = playerElement.childNodes[1].getAttribute("data-id");
|
||||
var playedStatus = document.createDocumentFragment();
|
||||
var playedBox = document.getElementById(youtubeId);
|
||||
if (playedBox) {
|
||||
playedStatus.appendChild(playedBox);
|
||||
}
|
||||
playerElement.innerHTML = '';
|
||||
// append played status
|
||||
var videoInfo = document.getElementById('video-info-' + youtubeId);
|
||||
videoInfo.insertBefore(playedStatus, videoInfo.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the progress bar when passed a video id, video progress and video duration
|
||||
function setProgressBar(videoId, currentTime, duration) {
|
||||
var progressBarWidth = (currentTime / duration) * 100 + "%";
|
||||
var progressBars = document.getElementsByClassName("video-progress-bar");
|
||||
for (let i = 0; i < progressBars.length; i++) {
|
||||
if (progressBars[i].id == "progress-" + videoId) {
|
||||
if (!getVideoPlayerWatchStatus()) {
|
||||
progressBars[i].style.width = progressBarWidth;
|
||||
} else {
|
||||
progressBars[i].style.width = "0%";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// progressBar = document.getElementById("progress-" + videoId);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// multi search form
|
||||
function searchMulti(query) {
|
||||
if (query.length > 1) {
|
||||
var payload = JSON.stringify({'multi_search': query});
|
||||
var http = new XMLHttpRequest();
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState === 4) {
|
||||
allResults = JSON.parse(http.response).results;
|
||||
populateMultiSearchResults(allResults);
|
||||
}
|
||||
};
|
||||
http.open("POST", "/process/", true);
|
||||
http.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
|
||||
http.setRequestHeader("Content-type", "application/json");
|
||||
http.send(payload);
|
||||
}
|
||||
}
|
||||
|
||||
function getViewDefaults(view) {
|
||||
var defaultView = document.getElementById("id_" + view).value;
|
||||
return defaultView;
|
||||
}
|
||||
|
||||
function populateMultiSearchResults(allResults) {
|
||||
// videos
|
||||
var defaultVideo = getViewDefaults("home");
|
||||
var allVideos = allResults.video_results;
|
||||
var videoBox = document.getElementById("video-results");
|
||||
videoBox.innerHTML = "";
|
||||
for (let index = 0; index < allVideos.length; index++) {
|
||||
const video = allVideos[index].source;
|
||||
const videoDiv = createVideo(video, defaultVideo);
|
||||
videoBox.appendChild(videoDiv);
|
||||
}
|
||||
// channels
|
||||
var defaultChannel = getViewDefaults("channel");
|
||||
var allChannels = allResults.channel_results;
|
||||
var channelBox = document.getElementById("channel-results");
|
||||
channelBox.innerHTML = "";
|
||||
for (let index = 0; index < allChannels.length; index++) {
|
||||
const channel = allChannels[index].source;
|
||||
const channelDiv = createChannel(channel, defaultChannel);
|
||||
channelBox.appendChild(channelDiv);
|
||||
}
|
||||
// playlists
|
||||
var defaultPlaylist = getViewDefaults("playlist");
|
||||
var allPlaylists = allResults.playlist_results;
|
||||
var playlistBox = document.getElementById("playlist-results");
|
||||
playlistBox.innerHTML = "";
|
||||
for (let index = 0; index < allPlaylists.length; index++) {
|
||||
const playlist = allPlaylists[index].source;
|
||||
const playlistDiv = createPlaylist(playlist, defaultPlaylist);
|
||||
playlistBox.appendChild(playlistDiv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function createVideo(video, viewStyle) {
|
||||
// create video item div from template
|
||||
const videoId = video.youtube_id;
|
||||
const mediaUrl = video.media_url;
|
||||
const thumbUrl = "/cache/" + video.vid_thumb_url;
|
||||
const videoTitle = video.title;
|
||||
const videoPublished = video.published;
|
||||
const videoDuration = video.player.duration_str;
|
||||
if (video.player.watched) {
|
||||
var watchStatusIndicator = createWatchStatusIndicator(videoId, "watched");
|
||||
} else {
|
||||
var watchStatusIndicator = createWatchStatusIndicator(videoId, "unwatched");
|
||||
};
|
||||
const channelId = video.channel.channel_id;
|
||||
const channelName = video.channel.channel_name;
|
||||
// build markup
|
||||
const markup = `
|
||||
<a href="#player" data-src="/media/${mediaUrl}" data-thumb="${thumbUrl}" data-title="${videoTitle}" data-channel="${channelName}" data-channel-id="${channelId}" data-id="${videoId}" onclick="createPlayer(this)">
|
||||
<div class="video-thumb-wrap ${viewStyle}">
|
||||
<div class="video-thumb">
|
||||
<img src="${thumbUrl}" alt="video-thumb">
|
||||
</div>
|
||||
<div class="video-play">
|
||||
<img src="/static/img/icon-play.svg" alt="play-icon">
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="video-desc ${viewStyle}">
|
||||
<div class="video-desc-player" id="video-info-${videoId}">
|
||||
${watchStatusIndicator}
|
||||
<span>${videoPublished} | ${videoDuration}</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/channel/${channelId}/"><h3>${channelName}</h3></a>
|
||||
<a class="video-more" href="/video/${videoId}/"><h2>${videoTitle}</h2></a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
const videoDiv = document.createElement("div");
|
||||
videoDiv.setAttribute("class", "video-item " + viewStyle);
|
||||
videoDiv.innerHTML = markup;
|
||||
return videoDiv;
|
||||
}
|
||||
|
||||
|
||||
function createChannel(channel, viewStyle) {
|
||||
// create channel item div from template
|
||||
const channelId = channel.channel_id;
|
||||
const channelName = channel.channel_name;
|
||||
const channelSubs = channel.channel_subs;
|
||||
const channelLastRefresh = channel.channel_last_refresh;
|
||||
if (channel.channel_subscribed) {
|
||||
var button = `<button class="unsubscribe" type="button" id="${channelId}" onclick="unsubscribe(this.id)" title="Unsubscribe from ${channelName}">Unsubscribe</button>`;
|
||||
} else {
|
||||
var button = `<button type="button" id="${channelId}" onclick="subscribe(this.id)" title="Subscribe to ${channelName}">Subscribe</button>`;
|
||||
}
|
||||
// build markup
|
||||
const markup = `
|
||||
<div class="channel-banner ${viewStyle}">
|
||||
<a href="/channel/${channelId}/">
|
||||
<img src="/cache/channels/${channelId}_banner.jpg" alt="${channelId}-banner">
|
||||
</a>
|
||||
</div>
|
||||
<div class="info-box info-box-2 ${viewStyle}">
|
||||
<div class="info-box-item">
|
||||
<div class="round-img">
|
||||
<a href="/channel/${channelId}/">
|
||||
<img src="/cache/channels/${channelId}_thumb.jpg" alt="channel-thumb">
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<h3><a href="/channel/${channelId}/">${channelName}</a></h3>
|
||||
<p>Subscribers: ${channelSubs}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-box-item">
|
||||
<div>
|
||||
<p>Last refreshed: ${channelLastRefresh}</p>
|
||||
${button}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
const channelDiv = document.createElement("div");
|
||||
channelDiv.setAttribute("class", "channel-item " + viewStyle);
|
||||
channelDiv.innerHTML = markup;
|
||||
return channelDiv;
|
||||
}
|
||||
|
||||
function createPlaylist(playlist, viewStyle) {
|
||||
// create playlist item div from template
|
||||
const playlistId = playlist.playlist_id;
|
||||
const playlistName = playlist.playlist_name;
|
||||
const playlistChannelId = playlist.playlist_channel_id;
|
||||
const playlistChannel = playlist.playlist_channel;
|
||||
const playlistLastRefresh = playlist.playlist_last_refresh;
|
||||
if (playlist.playlist_subscribed) {
|
||||
var button = `<button class="unsubscribe" type="button" id="${playlistId}" onclick="unsubscribe(this.id)" title="Unsubscribe from ${playlistName}">Unsubscribe</button>`;
|
||||
} else {
|
||||
var button = `<button type="button" id="${playlistId}" onclick="subscribe(this.id)" title="Subscribe to ${playlistName}">Subscribe</button>`;
|
||||
}
|
||||
const markup = `
|
||||
<div class="playlist-thumbnail">
|
||||
<a href="/playlist/${playlistId}/">
|
||||
<img src="/cache/playlists/${playlistId}.jpg" alt="${playlistId}-thumbnail">
|
||||
</a>
|
||||
</div>
|
||||
<div class="playlist-desc ${viewStyle}">
|
||||
<a href="/channel/${playlistChannelId}/"><h3>${playlistChannel}</h3></a>
|
||||
<a href="/playlist/${playlistId}/"><h2>${playlistName}</h2></a>
|
||||
<p>Last refreshed: ${playlistLastRefresh}</p>
|
||||
${button}
|
||||
</div>
|
||||
`;
|
||||
const playlistDiv = document.createElement("div");
|
||||
playlistDiv.setAttribute("class", "playlist-item " + viewStyle);
|
||||
playlistDiv.innerHTML = markup;
|
||||
return playlistDiv;
|
||||
}
|
||||
|
||||
|
||||
// generic
|
||||
function sendPost(payload) {
|
||||
var http = new XMLHttpRequest();
|
||||
http.open("POST", "/process/", true);
|
||||
http.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
|
||||
http.setRequestHeader("Content-type", "application/json");
|
||||
http.send(payload);
|
||||
}
|
||||
|
||||
|
||||
function getCookie(c_name) {
|
||||
if (document.cookie.length > 0) {
|
||||
c_start = document.cookie.indexOf(c_name + "=");
|
||||
if (c_start != -1) {
|
||||
c_start = c_start + c_name.length + 1;
|
||||
c_end = document.cookie.indexOf(";", c_start);
|
||||
if (c_end == -1) c_end = document.cookie.length;
|
||||
return unescape(document.cookie.substring(c_start,c_end));
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// animations
|
||||
function textReveal() {
|
||||
var textBox = document.getElementById('text-reveal');
|
||||
var button = document.getElementById('text-reveal-button');
|
||||
var textBoxHeight = textBox.style.height;
|
||||
if (textBoxHeight === 'unset') {
|
||||
textBox.style.height = '0px';
|
||||
button.innerText = 'Show';
|
||||
} else {
|
||||
textBox.style.height = 'unset';
|
||||
button.innerText = 'Hide';
|
||||
}
|
||||
}
|
||||
|
||||
function showForm() {
|
||||
var formElement = document.getElementById('hidden-form');
|
||||
var displayStyle = formElement.style.display;
|
||||
if (displayStyle === "") {
|
||||
formElement.style.display = 'block';
|
||||
} else {
|
||||
formElement.style.display = "";
|
||||
}
|
||||
animate('animate-icon', 'pulse-img');
|
||||
}
|
||||
|
||||
function showOverwrite() {
|
||||
var overwriteDiv = document.getElementById("overwrite-form");
|
||||
if (overwriteDiv.classList.contains("hidden-overwrite")) {
|
||||
overwriteDiv.classList.remove("hidden-overwrite");
|
||||
} else {
|
||||
overwriteDiv.classList.add("hidden-overwrite")
|
||||
}
|
||||
}
|
||||
|
||||
function animate(elementId, animationClass) {
|
||||
var toAnimate = document.getElementById(elementId);
|
||||
if (toAnimate.className !== animationClass) {
|
||||
toAnimate.className = animationClass;
|
||||
} else {
|
||||
toAnimate.classList.remove(animationClass);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user