2021-09-05 17:10:14 +00:00
function sortChange ( sortValue ) {
var payload = JSON . stringify ( { 'sort_order' : sortValue } ) ;
sendPost ( payload ) ;
setTimeout ( function ( ) {
location . reload ( ) ;
return false ;
} , 500 ) ;
}
2022-03-10 13:20:23 +00:00
// 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 ;
}
}
2021-09-05 17:10:14 +00:00
}
2022-03-10 13:20:23 +00:00
// 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);
// }
2022-02-25 03:39:33 +00:00
// Removes the progress bar when passed a video id
function removeProgressBar ( videoId ) {
setProgressBar ( videoId , 0 , 1 ) ;
}
2021-11-20 03:58:25 +00:00
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 ) ;
}
2022-03-10 13:20:23 +00:00
// 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);
// }
2021-10-07 16:38:17 +00:00
2021-11-25 04:52:14 +00:00
function unsubscribe ( id _unsub ) {
var payload = JSON . stringify ( { 'unsubscribe' : id _unsub } ) ;
2021-09-05 17:10:14 +00:00
sendPost ( payload ) ;
2021-12-18 09:56:32 +00:00
var message = document . createElement ( 'span' ) ;
message . innerText = "You are unsubscribed." ;
document . getElementById ( id _unsub ) . replaceWith ( message ) ;
2021-11-25 09:41:58 +00:00
}
function subscribe ( id _sub ) {
var payload = JSON . stringify ( { 'subscribe' : id _sub } ) ;
sendPost ( payload ) ;
2021-12-18 09:56:32 +00:00
var message = document . createElement ( 'span' ) ;
message . innerText = "You are subscribed." ;
document . getElementById ( id _sub ) . replaceWith ( message ) ;
2021-09-05 17:10:14 +00:00
}
2021-10-01 07:42:17 +00:00
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 ) ;
}
2021-10-03 11:17:07 +00:00
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 ) ;
}
2021-09-05 17:10:14 +00:00
// download page buttons
function rescanPending ( ) {
var payload = JSON . stringify ( { 'rescan_pending' : true } ) ;
animate ( 'rescan-icon' , 'rotate-img' ) ;
sendPost ( payload ) ;
setTimeout ( function ( ) {
2021-12-05 10:24:20 +00:00
checkMessages ( ) ;
2021-09-05 17:10:14 +00:00
} , 500 ) ;
}
function dlPending ( ) {
var payload = JSON . stringify ( { 'dl_pending' : true } ) ;
animate ( 'download-icon' , 'bounce-img' ) ;
sendPost ( payload ) ;
setTimeout ( function ( ) {
2021-12-05 10:24:20 +00:00
checkMessages ( ) ;
2021-09-05 17:10:14 +00:00
} , 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 ) ;
2021-09-17 03:52:59 +00:00
document . getElementById ( youtube _id ) . remove ( ) ;
2021-09-05 17:10:14 +00:00
setTimeout ( function ( ) {
2021-12-05 10:24:20 +00:00
checkMessages ( ) ;
2021-09-05 17:10:14 +00:00
} , 500 ) ;
}
2021-09-28 09:53:45 +00:00
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 ( ) {
2021-12-05 10:24:20 +00:00
checkMessages ( ) ;
2021-09-28 09:53:45 +00:00
} , 500 ) ;
}
2021-11-25 13:02:25 +00:00
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 ) ;
}
2021-09-24 11:03:22 +00:00
function stopQueue ( ) {
var payload = JSON . stringify ( { 'queue' : 'stop' } ) ;
sendPost ( payload ) ;
document . getElementById ( 'stop-icon' ) . remove ( ) ;
}
2021-09-25 08:35:36 +00:00
function killQueue ( ) {
var payload = JSON . stringify ( { 'queue' : 'kill' } ) ;
sendPost ( payload ) ;
document . getElementById ( 'kill-icon' ) . remove ( ) ;
}
2021-09-24 11:03:22 +00:00
2021-09-14 11:24:02 +00:00
// 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 ) ;
}
2021-11-01 09:42:07 +00:00
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 ) ;
}
2021-09-16 11:16:09 +00:00
function dbBackup ( ) {
var payload = JSON . stringify ( { 'db-backup' : true } ) ;
2022-02-05 11:26:31 +00:00
sendPost ( payload ) ;
2021-09-16 11:16:09 +00:00
// clear button
var message = document . createElement ( 'p' ) ;
message . innerText = 'backing up archive' ;
var toReplace = document . getElementById ( 'db-backup' ) ;
toReplace . innerHTML = '' ;
toReplace . appendChild ( message ) ;
}
2021-12-14 12:06:47 +00:00
function dbRestore ( button ) {
var fileName = button . getAttribute ( "data-id" ) ;
var payload = JSON . stringify ( { 'db-restore' : fileName } ) ;
2021-10-08 07:56:07 +00:00
sendPost ( payload ) ;
2021-12-14 12:06:47 +00:00
// clear backup row
2021-09-20 13:26:28 +00:00
var message = document . createElement ( 'p' ) ;
message . innerText = 'restoring from backup' ;
2021-12-14 12:06:47 +00:00
var toReplace = document . getElementById ( fileName ) ;
2021-09-20 13:26:28 +00:00
toReplace . innerHTML = '' ;
toReplace . appendChild ( message ) ;
}
2021-10-08 07:56:07 +00:00
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 ) ;
}
2022-02-11 11:19:10 +00:00
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 ) ;
}
2021-10-09 10:11:13 +00:00
// delete from file system
function deleteConfirm ( ) {
to _show = document . getElementById ( "delete-button" ) ;
document . getElementById ( "delete-item" ) . style . display = 'none' ;
to _show . style . display = "block" ;
}
2021-10-09 13:33:32 +00:00
function deleteVideo ( button ) {
2021-10-09 10:11:13 +00:00
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 ) ;
}
2021-10-09 13:33:32 +00:00
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 ) ;
}
2021-11-20 11:27:10 +00:00
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 ) ;
}
2021-10-09 10:11:13 +00:00
function cancelDelete ( ) {
document . getElementById ( "delete-button" ) . style . display = 'none' ;
document . getElementById ( "delete-item" ) . style . display = 'block' ;
}
2021-09-05 17:10:14 +00:00
// player
function createPlayer ( button ) {
2022-02-05 11:26:31 +00:00
var videoId = button . getAttribute ( 'data-id' ) ;
var videoData = getVideoData ( videoId ) ;
2022-02-25 03:39:33 +00:00
var videoProgress = getVideoProgress ( videoId ) . position ;
2022-02-24 02:36:31 +00:00
var videoName = videoData . data . title ;
2022-02-05 11:26:31 +00:00
2022-02-25 03:39:33 +00:00
var videoTag = createVideoTag ( videoData , videoProgress ) ;
2022-02-11 01:53:09 +00:00
2022-02-05 11:26:31 +00:00
var playlist = '' ;
2022-02-24 02:36:31 +00:00
var videoPlaylists = videoData . data . playlist ; // Array of playlists the video is in
2022-02-05 11:26:31 +00:00
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> ` ;
}
}
2022-02-24 02:36:31 +00:00
var videoViews = formatNumbers ( videoData . data . stats . view _count ) ;
2022-02-05 11:26:31 +00:00
2022-02-24 02:36:31 +00:00
var channelId = videoData . data . channel . channel _id ;
var channelName = videoData . data . channel . channel _name ;
2022-02-05 11:26:31 +00:00
2021-09-05 17:10:14 +00:00
removePlayer ( ) ;
2022-03-10 13:20:23 +00:00
// document.getElementById(videoId).outerHTML = ''; // Remove watch indicator from video info
2022-02-05 11:26:31 +00:00
// If cast integration is enabled create cast button
2022-02-24 02:36:31 +00:00
var castButton = '' ;
if ( videoData . config . application . enable _cast ) {
2022-02-05 11:26:31 +00:00
var castButton = ` <google-cast-launcher id="castbutton"></google-cast-launcher> ` ;
}
// Watched indicator
2022-02-24 02:36:31 +00:00
if ( videoData . data . player . watched ) {
2022-03-10 13:20:23 +00:00
var watchStatusIndicator = createWatchStatusIndicator ( videoId , "watched" ) ;
2022-02-05 11:26:31 +00:00
} else {
2022-03-10 13:20:23 +00:00
var watchStatusIndicator = createWatchStatusIndicator ( videoId , "unwatched" ) ;
2022-02-05 11:26:31 +00:00
}
2022-03-10 13:20:23 +00:00
2022-02-05 11:26:31 +00:00
var playerStats = ` <div class="thumb-icon player-stats"><img src="/static/img/icon-eye.svg" alt="views icon"><span> ${ videoViews } </span> ` ;
2022-02-24 02:36:31 +00:00
if ( videoData . data . stats . like _count ) {
var likes = formatNumbers ( videoData . data . stats . like _count ) ;
2022-02-05 11:26:31 +00:00
playerStats += ` <span>|</span><img src="/static/img/icon-thumb.svg" alt="thumbs-up"><span> ${ likes } </span> ` ;
}
2022-02-24 02:36:31 +00:00
if ( videoData . data . stats . dislike _count && videoData . config . downloads . integrate _ryd ) {
var dislikes = formatNumbers ( videoData . data . stats . dislike _count ) ;
2022-02-05 11:26:31 +00:00
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}" >
2022-02-24 02:36:31 +00:00
$ { videoTag }
2022-02-05 11:26:31 +00:00
< 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" >
2022-03-10 13:20:23 +00:00
$ { watchStatusIndicator }
2022-02-05 11:26:31 +00:00
$ { castButton }
$ { playerStats }
< div class = "player-channel-playlist" >
< h3 > < a href = "/channel/${channelId}/" > $ { channelName } < / a > < / h 3 >
$ { playlist }
< / d i v >
< a href = "/video/${videoId}/" > < h2 id = "video-title" > $ { videoName } < / h 2 > < / a >
< / d i v >
< / d i v >
` ;
2022-02-24 02:36:31 +00:00
const divPlayer = document . getElementById ( "player" ) ;
2022-02-05 11:26:31 +00:00
divPlayer . innerHTML = markup ;
}
2022-02-24 02:36:31 +00:00
// Add video tag to video page when passed a video id, function loaded on page load `video.html (115-117)`
2022-02-25 03:39:33 +00:00
function insertVideoTag ( videoData , videoProgress ) {
var videoTag = createVideoTag ( videoData , videoProgress ) ;
2022-02-24 02:36:31 +00:00
var videoMain = document . getElementsByClassName ( "video-main" ) ;
videoMain [ 0 ] . innerHTML = videoTag ;
}
2022-02-25 03:39:33 +00:00
// Generates a video tag with subtitles when passed videoData and videoProgress.
function createVideoTag ( videoData , videoProgress ) {
var videoId = videoData . data . youtube _id ;
2022-02-24 02:36:31 +00:00
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 ++ ) {
2022-03-13 15:56:20 +00:00
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 } "> ` ;
2022-02-24 02:36:31 +00:00
}
2022-02-05 11:26:31 +00:00
}
2022-02-24 02:36:31 +00:00
var videoTag = `
2022-02-25 03:39:33 +00:00
< video poster = "${videoThumbUrl}" ontimeupdate = "onVideoProgress()" onpause = "onVideoPause()" onended = "onVideoEnded()" controls autoplay width = "100%" playsinline id = "video-item" >
2022-02-24 02:36:31 +00:00
< source src = "${videoUrl}#t=${videoProgress}" type = "video/mp4" id = "video-source" videoid = "${videoId}" >
$ { subtitles }
< / v i d e o >
` ;
return videoTag ;
2022-02-05 11:26:31 +00:00
}
2022-02-24 02:36:31 +00:00
// Gets video tag
function getVideoPlayer ( ) {
2022-02-05 11:26:31 +00:00
var videoElement = document . getElementById ( "video-item" ) ;
2022-02-24 02:36:31 +00:00
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 ( ) ;
2022-02-05 11:26:31 +00:00
if ( videoElement != null ) {
2022-02-24 02:36:31 +00:00
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 ;
2022-03-10 13:20:23 +00:00
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 ;
}
2022-02-24 02:36:31 +00:00
}
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 ) ) {
2022-03-10 13:20:23 +00:00
updateVideoWatchStatus ( videoId , "unwatched" ) ;
2022-02-05 11:26:31 +00:00
}
}
}
}
2022-02-25 03:39:33 +00:00
// Runs on video end, marks video as watched
function onVideoEnded ( ) {
var videoId = getVideoPlayerVideoId ( ) ;
if ( ! getVideoPlayerWatchStatus ( ) ) { // Check if video is already marked as watched
2022-03-10 13:20:23 +00:00
updateVideoWatchStatus ( videoId , "unwatched" ) ;
2022-02-25 03:39:33 +00:00
}
}
2022-02-24 02:36:31 +00:00
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 ;
}
2022-02-05 11:26:31 +00:00
}
2022-02-24 02:36:31 +00:00
return watched ;
}
// Runs on video pause. Sends current position.
function onVideoPause ( ) {
var videoId = getVideoPlayerVideoId ( ) ;
var currentTime = getVideoPlayerCurrentTime ( ) ;
postVideoProgress ( videoId , currentTime ) ;
2022-02-05 11:26:31 +00:00
}
// 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 ;
}
2022-02-24 02:36:31 +00:00
// Gets video data when passed video ID
2022-02-05 11:26:31 +00:00
function getVideoData ( videoId ) {
var apiEndpoint = "/api/video/" + videoId + "/" ;
2022-02-24 02:36:31 +00:00
var videoData = apiRequest ( apiEndpoint , "GET" ) ;
return videoData ;
2022-02-05 11:26:31 +00:00
}
2022-02-24 02:36:31 +00:00
// Gets channel data when passed channel ID
2022-02-05 11:26:31 +00:00
function getChannelData ( channelId ) {
var apiEndpoint = "/api/channel/" + channelId + "/" ;
2022-02-24 02:36:31 +00:00
var channelData = apiRequest ( apiEndpoint , "GET" ) ;
2022-02-05 11:26:31 +00:00
return channelData . data ;
}
2022-02-24 02:36:31 +00:00
// Gets playlist data when passed playlist ID
2022-02-05 11:26:31 +00:00
function getPlaylistData ( playlistId ) {
var apiEndpoint = "/api/playlist/" + playlistId + "/" ;
2022-02-24 02:36:31 +00:00
var playlistData = apiRequest ( apiEndpoint , "GET" ) ;
2022-02-05 11:26:31 +00:00
return playlistData . data ;
}
2022-02-24 02:36:31 +00:00
// Get video progress data when passed video ID
function getVideoProgress ( videoId ) {
var apiEndpoint = "/api/video/" + videoId + "/progress/" ;
var videoProgress = apiRequest ( apiEndpoint , "GET" ) ;
return videoProgress ;
}
2022-02-05 11:26:31 +00:00
// 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 ] ) ;
}
2022-01-15 06:33:16 +00:00
}
2022-02-05 11:26:31 +00:00
return subbedPlaylists ;
}
2022-02-24 02:36:31 +00:00
// Send video position when given video id and progress in seconds
function postVideoProgress ( videoId , videoProgress ) {
var apiEndpoint = "/api/video/" + videoId + "/progress/" ;
2022-02-25 03:39:33 +00:00
var duartion = getVideoPlayerDuration ( ) ;
if ( ! isNaN ( videoProgress ) && duartion != 'undefined' ) {
2022-02-24 02:36:31 +00:00
var data = {
"position" : videoProgress
} ;
if ( videoProgress == 0 ) {
apiRequest ( apiEndpoint , "DELETE" ) ;
2022-02-25 03:39:33 +00:00
// console.log("Deleting Video Progress for Video ID: " + videoId + ", Progress: " + videoProgress);
2022-02-24 02:36:31 +00:00
} else if ( ! getVideoPlayerWatchStatus ( ) ) {
apiRequest ( apiEndpoint , "POST" , data ) ;
2022-02-25 03:39:33 +00:00
// console.log("Saving Video Progress for Video ID: " + videoId + ", Progress: " + videoProgress);
2022-02-24 02:36:31 +00:00
}
}
}
// Makes api requests when passed an endpoint and method ("GET", "POST", "DELETE")
2022-02-05 11:26:31 +00:00
function apiRequest ( apiEndpoint , method , data ) {
const xhttp = new XMLHttpRequest ( ) ;
var sessionToken = getCookie ( "sessionid" ) ;
xhttp . open ( method , apiEndpoint , false ) ;
2022-02-24 02:36:31 +00:00
xhttp . setRequestHeader ( "X-CSRFToken" , getCookie ( "csrftoken" ) ) ; // Used for video progress POST requests
2022-02-05 11:26:31 +00:00
xhttp . setRequestHeader ( "Authorization" , "Token " + sessionToken ) ;
xhttp . setRequestHeader ( "Content-Type" , "application/json" ) ;
xhttp . send ( JSON . stringify ( data ) ) ;
return JSON . parse ( xhttp . responseText ) ;
2021-09-05 17:10:14 +00:00
}
2022-02-25 03:39:33 +00:00
// Gets origin URL
2022-02-24 02:36:31 +00:00
function getURL ( ) {
2022-02-25 03:39:33 +00:00
return window . location . origin ;
2022-02-24 02:36:31 +00:00
}
2021-09-05 17:10:14 +00:00
function removePlayer ( ) {
2022-02-24 02:36:31 +00:00
var currentTime = getVideoPlayerCurrentTime ( ) ;
2022-02-25 03:39:33 +00:00
var duration = getVideoPlayerDuration ( ) ;
2022-02-24 02:36:31 +00:00
var videoId = getVideoPlayerVideoId ( ) ;
postVideoProgress ( videoId , currentTime ) ;
2022-02-25 03:39:33 +00:00
setProgressBar ( videoId , currentTime , duration ) ;
2021-09-05 17:10:14 +00:00
var playerElement = document . getElementById ( 'player' ) ;
if ( playerElement . hasChildNodes ( ) ) {
2022-02-05 11:26:31 +00:00
var youtubeId = playerElement . childNodes [ 1 ] . getAttribute ( "data-id" ) ;
2021-09-05 17:10:14 +00:00
var playedStatus = document . createDocumentFragment ( ) ;
2021-12-18 10:15:53 +00:00
var playedBox = document . getElementById ( youtubeId ) ;
if ( playedBox ) {
playedStatus . appendChild ( playedBox ) ;
2022-02-05 11:26:31 +00:00
}
2021-09-05 17:10:14 +00:00
playerElement . innerHTML = '' ;
// append played status
var videoInfo = document . getElementById ( 'video-info-' + youtubeId ) ;
videoInfo . insertBefore ( playedStatus , videoInfo . firstChild ) ;
2022-02-05 11:26:31 +00:00
}
2021-09-05 17:10:14 +00:00
}
2022-02-25 03:39:33 +00:00
// Sets the progress bar when passed a video id, video progress and video duration
function setProgressBar ( videoId , currentTime , duration ) {
2022-03-10 13:20:23 +00:00
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%" ;
}
}
2022-02-25 03:39:33 +00:00
}
2022-03-10 13:20:23 +00:00
// progressBar = document.getElementById("progress-" + videoId);
2022-02-25 03:39:33 +00:00
}
2021-12-30 15:13:47 +00:00
// multi search form
function searchMulti ( query ) {
if ( query . length > 1 ) {
2022-02-05 11:26:31 +00:00
var payload = JSON . stringify ( { 'multi_search' : query } ) ;
2021-12-30 15:13:47 +00:00
var http = new XMLHttpRequest ( ) ;
http . onreadystatechange = function ( ) {
if ( http . readyState === 4 ) {
2022-02-05 11:26:31 +00:00
allResults = JSON . parse ( http . response ) . results ;
2021-12-30 15:13:47 +00:00
populateMultiSearchResults ( allResults ) ;
2022-02-05 11:26:31 +00:00
}
2021-12-30 15:13:47 +00:00
} ;
http . open ( "POST" , "/process/" , true ) ;
http . setRequestHeader ( "X-CSRFToken" , getCookie ( "csrftoken" ) ) ;
http . setRequestHeader ( "Content-type" , "application/json" ) ;
http . send ( payload ) ;
2022-02-05 11:26:31 +00:00
}
2021-12-30 15:13:47 +00:00
}
2022-01-07 11:29:25 +00:00
function getViewDefaults ( view ) {
var defaultView = document . getElementById ( "id_" + view ) . value ;
2022-02-05 11:26:31 +00:00
return defaultView ;
2022-01-07 11:29:25 +00:00
}
2021-12-30 15:13:47 +00:00
function populateMultiSearchResults ( allResults ) {
// videos
2022-01-07 11:29:25 +00:00
var defaultVideo = getViewDefaults ( "home" ) ;
2022-02-05 11:26:31 +00:00
var allVideos = allResults . video _results ;
2021-12-30 15:13:47 +00:00
var videoBox = document . getElementById ( "video-results" ) ;
videoBox . innerHTML = "" ;
for ( let index = 0 ; index < allVideos . length ; index ++ ) {
2022-02-05 11:26:31 +00:00
const video = allVideos [ index ] . source ;
2022-01-07 11:29:25 +00:00
const videoDiv = createVideo ( video , defaultVideo ) ;
2021-12-30 15:13:47 +00:00
videoBox . appendChild ( videoDiv ) ;
2022-02-05 11:26:31 +00:00
}
2021-12-30 15:13:47 +00:00
// channels
2022-01-07 11:29:25 +00:00
var defaultChannel = getViewDefaults ( "channel" ) ;
2022-02-05 11:26:31 +00:00
var allChannels = allResults . channel _results ;
2021-12-30 15:13:47 +00:00
var channelBox = document . getElementById ( "channel-results" ) ;
channelBox . innerHTML = "" ;
for ( let index = 0 ; index < allChannels . length ; index ++ ) {
2022-02-05 11:26:31 +00:00
const channel = allChannels [ index ] . source ;
2022-01-07 11:29:25 +00:00
const channelDiv = createChannel ( channel , defaultChannel ) ;
2021-12-30 15:13:47 +00:00
channelBox . appendChild ( channelDiv ) ;
2022-02-05 11:26:31 +00:00
}
2021-12-30 15:13:47 +00:00
// playlists
2022-01-07 11:29:25 +00:00
var defaultPlaylist = getViewDefaults ( "playlist" ) ;
2022-02-05 11:26:31 +00:00
var allPlaylists = allResults . playlist _results ;
2021-12-30 15:13:47 +00:00
var playlistBox = document . getElementById ( "playlist-results" ) ;
playlistBox . innerHTML = "" ;
for ( let index = 0 ; index < allPlaylists . length ; index ++ ) {
2022-02-05 11:26:31 +00:00
const playlist = allPlaylists [ index ] . source ;
2022-01-07 11:29:25 +00:00
const playlistDiv = createPlaylist ( playlist , defaultPlaylist ) ;
2021-12-30 15:13:47 +00:00
playlistBox . appendChild ( playlistDiv ) ;
2022-02-05 11:26:31 +00:00
}
2021-12-30 15:13:47 +00:00
}
function createVideo ( video , viewStyle ) {
// create video item div from template
2022-02-05 11:26:31 +00:00
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 ) {
2022-03-10 13:20:23 +00:00
var watchStatusIndicator = createWatchStatusIndicator ( videoId , "watched" ) ;
2021-12-30 15:13:47 +00:00
} else {
2022-03-10 13:20:23 +00:00
var watchStatusIndicator = createWatchStatusIndicator ( videoId , "unwatched" ) ;
2021-12-30 15:13:47 +00:00
} ;
2022-02-05 11:26:31 +00:00
const channelId = video . channel . channel _id ;
const channelName = video . channel . channel _name ;
2021-12-30 15:13:47 +00:00
// 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" >
< / d i v >
< div class = "video-play" >
< img src = "/static/img/icon-play.svg" alt = "play-icon" >
< / d i v >
< / d i v >
< / a >
< div class = "video-desc ${viewStyle}" >
< div class = "video-desc-player" id = "video-info-${videoId}" >
2022-03-10 13:20:23 +00:00
$ { watchStatusIndicator }
2021-12-30 15:13:47 +00:00
< span > $ { videoPublished } | $ { videoDuration } < / s p a n >
< / d i v >
< div >
< a href = "/channel/${channelId}/" > < h3 > $ { channelName } < / h 3 > < / a >
< a class = "video-more" href = "/video/${videoId}/" > < h2 > $ { videoTitle } < / h 2 > < / a >
< / d i v >
< / d i v >
2022-02-05 11:26:31 +00:00
` ;
2021-12-30 15:13:47 +00:00
const videoDiv = document . createElement ( "div" ) ;
videoDiv . setAttribute ( "class" , "video-item " + viewStyle ) ;
2022-02-05 11:26:31 +00:00
videoDiv . innerHTML = markup ;
return videoDiv ;
2021-12-30 15:13:47 +00:00
}
function createChannel ( channel , viewStyle ) {
// create channel item div from template
2022-02-05 11:26:31 +00:00
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> ` ;
2021-12-30 15:13:47 +00:00
} else {
2022-02-05 11:26:31 +00:00
var button = ` <button type="button" id=" ${ channelId } " onclick="subscribe(this.id)" title="Subscribe to ${ channelName } ">Subscribe</button> ` ;
}
2021-12-30 15:13:47 +00:00
// build markup
const markup = `
2022-01-07 11:29:25 +00:00
< div class = "channel-banner ${viewStyle}" >
2021-12-30 15:13:47 +00:00
< a href = "/channel/${channelId}/" >
< img src = "/cache/channels/${channelId}_banner.jpg" alt = "${channelId}-banner" >
< / a >
< / d i v >
2022-01-07 11:29:25 +00:00
< div class = "info-box info-box-2 ${viewStyle}" >
2021-12-30 15:13:47 +00:00
< div class = "info-box-item" >
< div class = "round-img" >
< a href = "/channel/${channelId}/" >
< img src = "/cache/channels/${channelId}_thumb.jpg" alt = "channel-thumb" >
< / a >
< / d i v >
< div >
< h3 > < a href = "/channel/${channelId}/" > $ { channelName } < / a > < / h 3 >
< p > Subscribers : $ { channelSubs } < / p >
< / d i v >
< / d i v >
< div class = "info-box-item" >
< div >
< p > Last refreshed : $ { channelLastRefresh } < / p >
$ { button }
< / d i v >
< / d i v >
< / d i v >
2022-02-05 11:26:31 +00:00
` ;
2021-12-30 15:13:47 +00:00
const channelDiv = document . createElement ( "div" ) ;
channelDiv . setAttribute ( "class" , "channel-item " + viewStyle ) ;
channelDiv . innerHTML = markup ;
2022-02-05 11:26:31 +00:00
return channelDiv ;
2021-12-30 15:13:47 +00:00
}
function createPlaylist ( playlist , viewStyle ) {
// create playlist item div from template
2022-02-05 11:26:31 +00:00
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> ` ;
2021-12-30 15:13:47 +00:00
} else {
2022-02-05 11:26:31 +00:00
var button = ` <button type="button" id=" ${ playlistId } " onclick="subscribe(this.id)" title="Subscribe to ${ playlistName } ">Subscribe</button> ` ;
}
2021-12-30 15:13:47 +00:00
const markup = `
< div class = "playlist-thumbnail" >
< a href = "/playlist/${playlistId}/" >
< img src = "/cache/playlists/${playlistId}.jpg" alt = "${playlistId}-thumbnail" >
< / a >
< / d i v >
< div class = "playlist-desc ${viewStyle}" >
< a href = "/channel/${playlistChannelId}/" > < h3 > $ { playlistChannel } < / h 3 > < / a >
< a href = "/playlist/${playlistId}/" > < h2 > $ { playlistName } < / h 2 > < / a >
< p > Last refreshed : $ { playlistLastRefresh } < / p >
$ { button }
< / d i v >
2022-02-05 11:26:31 +00:00
` ;
2021-12-30 15:13:47 +00:00
const playlistDiv = document . createElement ( "div" ) ;
playlistDiv . setAttribute ( "class" , "playlist-item " + viewStyle ) ;
playlistDiv . innerHTML = markup ;
2022-02-05 11:26:31 +00:00
return playlistDiv ;
2021-12-30 15:13:47 +00:00
}
2021-09-05 17:10:14 +00:00
// 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 ) ) ;
2022-02-05 11:26:31 +00:00
}
}
2021-09-05 17:10:14 +00:00
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' ;
2022-02-05 11:26:31 +00:00
}
2021-09-05 17:10:14 +00:00
}
function showForm ( ) {
var formElement = document . getElementById ( 'hidden-form' ) ;
2022-02-05 11:26:31 +00:00
var displayStyle = formElement . style . display ;
2021-09-05 17:10:14 +00:00
if ( displayStyle === "" ) {
formElement . style . display = 'block' ;
} else {
formElement . style . display = "" ;
2022-02-05 11:26:31 +00:00
}
2022-01-02 09:25:05 +00:00
animate ( 'animate-icon' , 'pulse-img' ) ;
2021-09-05 17:10:14 +00:00
}
2021-09-15 13:47:26 +00:00
2022-03-24 08:43:15 +00:00
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" )
}
}
2021-09-15 13:47:26 +00:00
function animate ( elementId , animationClass ) {
var toAnimate = document . getElementById ( elementId ) ;
if ( toAnimate . className !== animationClass ) {
toAnimate . className = animationClass ;
2022-01-02 09:25:05 +00:00
} else {
toAnimate . classList . remove ( animationClass ) ;
2022-02-05 11:26:31 +00:00
}
2021-09-15 13:47:26 +00:00
}