mirror of https://github.com/FreeTubeApp/FreeTube
Add Lock to profile switching and code cleanup
This commit is contained in:
parent
eb10fee246
commit
456d1dfddc
|
@ -30,85 +30,86 @@
|
|||
*/
|
||||
function goToChannel(channelId) {
|
||||
|
||||
channelView.channelId = channelId;
|
||||
channelView.channelSearchValue = '';
|
||||
channelVideosView.page = 2;
|
||||
channelView.channelId = channelId;
|
||||
channelView.channelSearchValue = '';
|
||||
channelVideosView.page = 2;
|
||||
|
||||
headerView.title = 'Latest Uploads';
|
||||
hideViews();
|
||||
loadingView.seen = true;
|
||||
headerView.title = 'Latest Uploads';
|
||||
hideViews();
|
||||
loadingView.seen = true;
|
||||
|
||||
channelView.aboutTabSeen = false;
|
||||
channelView.aboutTabSeen = false;
|
||||
|
||||
// Setting subButtonText here as Mustache templates are logic-less.
|
||||
isSubscribed(channelId).then((subscribed) => {
|
||||
channelView.subButtonText = (subscribed ? "UNSUBSCRIBE" : "SUBSCRIBE");
|
||||
});
|
||||
|
||||
invidiousAPI('channels', channelId, {}, (data) => {
|
||||
ft.log(data);
|
||||
|
||||
channelView.id = channelId;
|
||||
channelView.name = data.author;
|
||||
|
||||
// Can't access url of undefined, check defined
|
||||
data.authorBanners.length
|
||||
? channelView.banner = data.authorBanners[0].url
|
||||
: channelView.banner = undefined;
|
||||
|
||||
data.authorThumbnails.length >= 4
|
||||
? channelView.icon = data.authorThumbnails[3].url
|
||||
: channelView.icon = undefined
|
||||
|
||||
channelView.subCount = data.subCount.toLocaleString(); //toLocaleString adds commas as thousands separators
|
||||
channelView.description = autolinker.link(data.description); //autolinker makes URLs clickable
|
||||
|
||||
channelVideosView.videoList = [];
|
||||
|
||||
channelView.featuredChannels = data.relatedChannels;
|
||||
|
||||
const views = [
|
||||
aboutView,
|
||||
headerView,
|
||||
historyView,
|
||||
popularView,
|
||||
savedView,
|
||||
searchView,
|
||||
settingsView,
|
||||
subscriptionView
|
||||
]
|
||||
|
||||
if (seenAll(views, false)) {
|
||||
channelVideosView.seen = true;
|
||||
channelView.seen = true;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
loadingView.seen = false;
|
||||
data.latestVideos.forEach((video) => {
|
||||
displayVideo(video, 'channel');
|
||||
// Setting subButtonText here as Mustache templates are logic-less.
|
||||
isSubscribed(channelId).then((subscribed) => {
|
||||
channelView.subButtonText = (subscribed ? "UNSUBSCRIBE" : "SUBSCRIBE");
|
||||
});
|
||||
|
||||
if (typeof(channelView.banner) === 'undefined') {
|
||||
window.setTimeout(() => {$('.channelViewBanner').get(0).height = 200;}, 50);
|
||||
}
|
||||
}, (errorData) => {
|
||||
showToast(errorData.responseJSON.error);
|
||||
loadingView.seen = false;
|
||||
});
|
||||
invidiousAPI('channels', channelId, {}, (data) => {
|
||||
ft.log(data);
|
||||
|
||||
invidiousAPI('channels/playlists', channelId, {}, (data) => {
|
||||
ft.log(data);
|
||||
channelView.id = channelId;
|
||||
channelView.name = data.author;
|
||||
|
||||
channelPlaylistsView.videoList = [];
|
||||
channelPlaylistsView.continuationString = data.continuation;
|
||||
// Can't access url of undefined, check defined
|
||||
data.authorBanners.length ?
|
||||
channelView.banner = data.authorBanners[0].url :
|
||||
channelView.banner = undefined;
|
||||
|
||||
data.playlists.forEach((playlist) => {
|
||||
displayPlaylist(playlist, 'channelPlaylist');
|
||||
data.authorThumbnails.length >= 4 ?
|
||||
channelView.icon = data.authorThumbnails[3].url :
|
||||
channelView.icon = undefined
|
||||
|
||||
channelView.subCount = data.subCount.toLocaleString(); //toLocaleString adds commas as thousands separators
|
||||
channelView.description = autolinker.link(data.description); //autolinker makes URLs clickable
|
||||
|
||||
channelVideosView.videoList = [];
|
||||
|
||||
channelView.featuredChannels = data.relatedChannels;
|
||||
|
||||
const views = [
|
||||
aboutView,
|
||||
headerView,
|
||||
historyView,
|
||||
popularView,
|
||||
savedView,
|
||||
searchView,
|
||||
settingsView,
|
||||
subscriptionView
|
||||
]
|
||||
|
||||
if (seenAll(views, false)) {
|
||||
channelVideosView.seen = true;
|
||||
channelView.seen = true;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
loadingView.seen = false;
|
||||
data.latestVideos.forEach((video) => {
|
||||
displayVideo(video, 'channel');
|
||||
});
|
||||
|
||||
if (typeof (channelView.banner) === 'undefined') {
|
||||
window.setTimeout(() => {
|
||||
$('.channelViewBanner').get(0).height = 200;
|
||||
}, 50);
|
||||
}
|
||||
}, (errorData) => {
|
||||
showToast(errorData.responseJSON.error);
|
||||
loadingView.seen = false;
|
||||
});
|
||||
|
||||
invidiousAPI('channels/playlists', channelId, {}, (data) => {
|
||||
ft.log(data);
|
||||
|
||||
channelPlaylistsView.videoList = [];
|
||||
channelPlaylistsView.continuationString = data.continuation;
|
||||
|
||||
data.playlists.forEach((playlist) => {
|
||||
displayPlaylist(playlist, 'channelPlaylist');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,37 +118,43 @@ function goToChannel(channelId) {
|
|||
* @return {Void}
|
||||
*/
|
||||
function channelNextPage() {
|
||||
showToast('Fetching results, please wait…');
|
||||
showToast('Fetching results, please wait…');
|
||||
|
||||
let sortValue = document.getElementById('channelVideosSortValue').value;
|
||||
let sortValue = document.getElementById('channelVideosSortValue').value;
|
||||
|
||||
invidiousAPI('channels/videos', channelView.channelId, {'sort_by': sortValue, 'page': channelVideosView.page }, (data) => {
|
||||
ft.log(data);
|
||||
data.forEach((video) => {
|
||||
displayVideo(video, 'channel');
|
||||
invidiousAPI('channels/videos', channelView.channelId, {
|
||||
'sort_by': sortValue,
|
||||
'page': channelVideosView.page
|
||||
}, (data) => {
|
||||
ft.log(data);
|
||||
data.forEach((video) => {
|
||||
displayVideo(video, 'channel');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
channelVideosView.page = channelVideosView.page + 1;
|
||||
channelVideosView.page = channelVideosView.page + 1;
|
||||
}
|
||||
|
||||
function channelPlaylistNextPage() {
|
||||
if (channelPlaylistsView.continuationString === null) {
|
||||
showToast('There are no more playlists for this channel.');
|
||||
return;
|
||||
}
|
||||
if (channelPlaylistsView.continuationString === null) {
|
||||
showToast('There are no more playlists for this channel.');
|
||||
return;
|
||||
}
|
||||
|
||||
showToast('Fetching results, please wait…');
|
||||
showToast('Fetching results, please wait…');
|
||||
|
||||
let sortValue = document.getElementById('channelVideosSortValue').value;
|
||||
let sortValue = document.getElementById('channelVideosSortValue').value;
|
||||
|
||||
invidiousAPI('channels/playlists', channelView.channelId, {'sort_by': sortValue, 'continuation': channelPlaylistsView.continuationString }, (data) => {
|
||||
ft.log(data);
|
||||
channelPlaylistsView.continuationString = data.continuation;
|
||||
data.playlists.forEach((playlist) => {
|
||||
displayPlaylist(playlist, 'channelPlaylist');
|
||||
invidiousAPI('channels/playlists', channelView.channelId, {
|
||||
'sort_by': sortValue,
|
||||
'continuation': channelPlaylistsView.continuationString
|
||||
}, (data) => {
|
||||
ft.log(data);
|
||||
channelPlaylistsView.continuationString = data.continuation;
|
||||
data.playlists.forEach((playlist) => {
|
||||
displayPlaylist(playlist, 'channelPlaylist');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function channelSearchKeypress(e) {
|
||||
|
@ -157,34 +164,34 @@ function channelSearchKeypress(e) {
|
|||
}
|
||||
|
||||
function searchChannel() {
|
||||
if (channelView.channelSearchValue === '') {
|
||||
return;
|
||||
}
|
||||
if (channelView.channelSearchValue === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
showToast('Fetching results, please wait…');
|
||||
showToast('Fetching results, please wait…');
|
||||
|
||||
invidiousAPI('channels/search', channelView.channelId, {
|
||||
q: channelView.channelSearchValue,
|
||||
page: channelSearchView.page,
|
||||
}, function (data) {
|
||||
ft.log(data);
|
||||
invidiousAPI('channels/search', channelView.channelId, {
|
||||
q: channelView.channelSearchValue,
|
||||
page: channelSearchView.page,
|
||||
}, function (data) {
|
||||
ft.log(data);
|
||||
|
||||
data.forEach((video) => {
|
||||
switch (video.type) {
|
||||
case 'video':
|
||||
displayVideo(video, 'channelSearch');
|
||||
break;
|
||||
case 'playlist':
|
||||
if (video.videoCount > 0) {
|
||||
displayPlaylist(video, 'channelSearch');
|
||||
data.forEach((video) => {
|
||||
switch (video.type) {
|
||||
case 'video':
|
||||
displayVideo(video, 'channelSearch');
|
||||
break;
|
||||
case 'playlist':
|
||||
if (video.videoCount > 0) {
|
||||
displayPlaylist(video, 'channelSearch');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
channelSearchView.page = channelSearchView.page + 1;
|
||||
});
|
||||
channelSearchView.page = channelSearchView.page + 1;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,5 +204,7 @@ function searchChannel() {
|
|||
* @example seenAll{[view1, view2]} => bool
|
||||
*/
|
||||
function seenAll(views, expected = true) {
|
||||
return views.every(({ seen }) => seen === expected)
|
||||
return views.every(({
|
||||
seen
|
||||
}) => seen === expected)
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ let ft = {};
|
|||
* @returns {Void}
|
||||
*/
|
||||
ft.log = function (...data) {
|
||||
if (typeof(settingsView) !== 'undefined' && !settingsView.debugMode) {
|
||||
return;
|
||||
if (typeof (settingsView) !== 'undefined' && !settingsView.debugMode) {
|
||||
return;
|
||||
}
|
||||
let currentTime = new Date();
|
||||
let time = currentTime.getDate() + "/" +
|
||||
|
|
|
@ -15,140 +15,147 @@ along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
/*
|
||||
* File used for functions related to video history.
|
||||
*/
|
||||
* File used for functions related to video history.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a video to the history database file
|
||||
*
|
||||
* @param {string} videoId - The video ID of the video to be saved.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function addToHistory(data){
|
||||
historyDb.findOne({ videoId: data.videoId }, function (err, doc) {
|
||||
if(doc === null) {
|
||||
historyDb.insert(data, (err, newDoc) => {});
|
||||
let videoIndex = subscriptionView.fullVideoList.findIndex((video) => {
|
||||
return video.videoId == data.videoId;
|
||||
});
|
||||
* Add a video to the history database file
|
||||
*
|
||||
* @param {string} videoId - The video ID of the video to be saved.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function addToHistory(data) {
|
||||
historyDb.findOne({
|
||||
videoId: data.videoId
|
||||
}, function (err, doc) {
|
||||
if (doc === null) {
|
||||
historyDb.insert(data, (err, newDoc) => {});
|
||||
let videoIndex = subscriptionView.fullVideoList.findIndex((video) => {
|
||||
return video.videoId == data.videoId;
|
||||
});
|
||||
|
||||
if (videoIndex >= 0) {
|
||||
subscriptionView.fullVideoList[videoIndex].watched = true;
|
||||
addSubsToView(subscriptionView.fullVideoList);
|
||||
}
|
||||
} else {
|
||||
historyDb.update(
|
||||
{ videoId: data.videoId },
|
||||
{
|
||||
videoId: data.videoId,
|
||||
author: data.author,
|
||||
authorId: data.authorId,
|
||||
published: data.published,
|
||||
publishedText: data.publishedText,
|
||||
description: data.description,
|
||||
viewCount: data.viewCount,
|
||||
title: data.title,
|
||||
lengthSeconds: data.lengthSeconds,
|
||||
videoThumbnails: data.videoThumbnails,
|
||||
liveNow: false,
|
||||
paid: false,
|
||||
type: 'video',
|
||||
timeWatched: data.timeWatched,
|
||||
watchProgress: data.watchProgress,
|
||||
}, {}, (err, newDoc) => {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a video from the history database file
|
||||
*
|
||||
* @param {string} videoId - The video ID of the video to be removed.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function removeFromHistory(videoId, toast = true){
|
||||
const data = {videoId: videoId};
|
||||
historyDb.remove(data, {}, (err, numRemoved) => {
|
||||
if (toast) {
|
||||
if (!err) {
|
||||
showToast('Video removed from history');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the watch progress video from the history database file
|
||||
*
|
||||
* @param {string} videoId - The video ID of the video to be removed.
|
||||
*
|
||||
* @param {double} lengthSeconds - The amount of time the video has been watched in seconds.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function updateWatchProgress(videoId, lengthSeconds){
|
||||
historyDb.findOne({ videoId: videoId }, function (err, doc) {
|
||||
if(doc !== null) {
|
||||
historyDb.update(
|
||||
{ videoId: videoId },
|
||||
{
|
||||
$set: { watchProgress: lengthSeconds }
|
||||
}, {}, (err, newDoc) => {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the videos within the history database.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function showHistory(){
|
||||
ft.log('checking history');
|
||||
|
||||
historyView.videoList = [];
|
||||
|
||||
historyDb.find({}).sort({
|
||||
timeWatched: -1
|
||||
}).exec((err, docs) => {
|
||||
docs.forEach((video, index) => {
|
||||
if (video.authorId === undefined) {
|
||||
// History data is from old version of FreeTube, update data for future calls.
|
||||
invidiousAPI('videos', video.videoId, {}, (data) => {
|
||||
let publishedText = new Date(data.published * 1000);
|
||||
publishedText = dateFormat(publishedText, "mmm dS, yyyy");
|
||||
let videoData = {
|
||||
videoId: video.videoId,
|
||||
if (videoIndex >= 0) {
|
||||
subscriptionView.fullVideoList[videoIndex].watched = true;
|
||||
addSubsToView(subscriptionView.fullVideoList);
|
||||
}
|
||||
} else {
|
||||
historyDb.update({
|
||||
videoId: data.videoId
|
||||
}, {
|
||||
videoId: data.videoId,
|
||||
author: data.author,
|
||||
authorId: data.authorId,
|
||||
published: data.published,
|
||||
publishedText: publishedText,
|
||||
publishedText: data.publishedText,
|
||||
description: data.description,
|
||||
viewCount: data.viewCount,
|
||||
title: data.title,
|
||||
lengthSeconds: data.lengthSeconds,
|
||||
videoThumbnails: data.videoThumbnails[4].url,
|
||||
author: data.author,
|
||||
authorId: data.authorId,
|
||||
videoThumbnails: data.videoThumbnails,
|
||||
liveNow: false,
|
||||
paid: false,
|
||||
type: 'video',
|
||||
timeWatched: video.timeWatched,
|
||||
watchProgress: 0,
|
||||
};
|
||||
addToHistory(videoData);
|
||||
videoData.position = index;
|
||||
displayVideo(videoData, 'history');
|
||||
}, () => {
|
||||
removeFromHistory(video.videoId, false);
|
||||
});
|
||||
}
|
||||
else{
|
||||
video.position = index;
|
||||
displayVideo(video, 'history');
|
||||
timeWatched: data.timeWatched,
|
||||
watchProgress: data.watchProgress,
|
||||
}, {}, (err, newDoc) => {});
|
||||
}
|
||||
});
|
||||
|
||||
loadingView.seen = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a video from the history database file
|
||||
*
|
||||
* @param {string} videoId - The video ID of the video to be removed.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function removeFromHistory(videoId, toast = true) {
|
||||
const data = {
|
||||
videoId: videoId
|
||||
};
|
||||
historyDb.remove(data, {}, (err, numRemoved) => {
|
||||
if (toast) {
|
||||
if (!err) {
|
||||
showToast('Video removed from history');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the watch progress video from the history database file
|
||||
*
|
||||
* @param {string} videoId - The video ID of the video to be removed.
|
||||
*
|
||||
* @param {double} lengthSeconds - The amount of time the video has been watched in seconds.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function updateWatchProgress(videoId, lengthSeconds) {
|
||||
historyDb.findOne({
|
||||
videoId: videoId
|
||||
}, function (err, doc) {
|
||||
if (doc !== null) {
|
||||
historyDb.update({
|
||||
videoId: videoId
|
||||
}, {
|
||||
$set: {
|
||||
watchProgress: lengthSeconds
|
||||
}
|
||||
}, {}, (err, newDoc) => {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the videos within the history database.
|
||||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function showHistory() {
|
||||
ft.log('checking history');
|
||||
|
||||
historyView.videoList = [];
|
||||
|
||||
historyDb.find({}).sort({
|
||||
timeWatched: -1
|
||||
}).exec((err, docs) => {
|
||||
docs.forEach((video, index) => {
|
||||
if (video.authorId === undefined) {
|
||||
// History data is from old version of FreeTube, update data for future calls.
|
||||
invidiousAPI('videos', video.videoId, {}, (data) => {
|
||||
let publishedText = new Date(data.published * 1000);
|
||||
publishedText = dateFormat(publishedText, "mmm dS, yyyy");
|
||||
let videoData = {
|
||||
videoId: video.videoId,
|
||||
published: data.published,
|
||||
publishedText: publishedText,
|
||||
description: data.description,
|
||||
viewCount: data.viewCount,
|
||||
title: data.title,
|
||||
lengthSeconds: data.lengthSeconds,
|
||||
videoThumbnails: data.videoThumbnails[4].url,
|
||||
author: data.author,
|
||||
authorId: data.authorId,
|
||||
liveNow: false,
|
||||
paid: false,
|
||||
type: 'video',
|
||||
timeWatched: video.timeWatched,
|
||||
watchProgress: 0,
|
||||
};
|
||||
addToHistory(videoData);
|
||||
videoData.position = index;
|
||||
displayVideo(videoData, 'history');
|
||||
}, () => {
|
||||
removeFromHistory(video.videoId, false);
|
||||
});
|
||||
} else {
|
||||
video.position = index;
|
||||
displayVideo(video, 'history');
|
||||
}
|
||||
});
|
||||
|
||||
loadingView.seen = false;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -23,50 +23,50 @@ let mouseTimeout; // Timeout for hiding the mouse cursor on video playback
|
|||
let checkedSettings = false;
|
||||
|
||||
let miniPlayerView = new Vue({
|
||||
el: '#miniPlayer',
|
||||
data: {
|
||||
videoId: '',
|
||||
videoUrl: '',
|
||||
videoTitle: '',
|
||||
video360p: '',
|
||||
valid360p: true,
|
||||
video720p: '',
|
||||
valid720p: true,
|
||||
videoAudio: '',
|
||||
validAudio: true,
|
||||
videoDash: '',
|
||||
validDash: true,
|
||||
videoLive: '',
|
||||
validLive: false,
|
||||
subtitleHtml: '',
|
||||
videoThumbnail: '',
|
||||
defaultPlaybackRate: '',
|
||||
quality: '',
|
||||
volume: '',
|
||||
currentTime: '',
|
||||
playerSeen: true,
|
||||
legacySeen: false,
|
||||
autoplay: true,
|
||||
enableSubtitles: false,
|
||||
thumbnailInterval: 5,
|
||||
},
|
||||
methods: {
|
||||
legacyFormats: () => {
|
||||
checkedSettings = false;
|
||||
miniPlayerView.legacySeen = true;
|
||||
miniPlayerView.playerSeen = false;
|
||||
el: '#miniPlayer',
|
||||
data: {
|
||||
videoId: '',
|
||||
videoUrl: '',
|
||||
videoTitle: '',
|
||||
video360p: '',
|
||||
valid360p: true,
|
||||
video720p: '',
|
||||
valid720p: true,
|
||||
videoAudio: '',
|
||||
validAudio: true,
|
||||
videoDash: '',
|
||||
validDash: true,
|
||||
videoLive: '',
|
||||
validLive: false,
|
||||
subtitleHtml: '',
|
||||
videoThumbnail: '',
|
||||
defaultPlaybackRate: '',
|
||||
quality: '',
|
||||
volume: '',
|
||||
currentTime: '',
|
||||
playerSeen: true,
|
||||
legacySeen: false,
|
||||
autoplay: true,
|
||||
enableSubtitles: false,
|
||||
thumbnailInterval: 5,
|
||||
},
|
||||
dashFormats: () => {
|
||||
checkedSettings = false;
|
||||
miniPlayerView.legacySeen = false;
|
||||
miniPlayerView.playerSeen = true;
|
||||
methods: {
|
||||
legacyFormats: () => {
|
||||
checkedSettings = false;
|
||||
miniPlayerView.legacySeen = true;
|
||||
miniPlayerView.playerSeen = false;
|
||||
},
|
||||
dashFormats: () => {
|
||||
checkedSettings = false;
|
||||
miniPlayerView.legacySeen = false;
|
||||
miniPlayerView.playerSeen = true;
|
||||
},
|
||||
embedPlayer: () => {
|
||||
checkedSettings = false;
|
||||
miniPlayerView.legacySeen = false;
|
||||
miniPlayerView.playerSeen = false;
|
||||
}
|
||||
},
|
||||
embedPlayer: () => {
|
||||
checkedSettings = false;
|
||||
miniPlayerView.legacySeen = false;
|
||||
miniPlayerView.playerSeen = false;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -97,7 +97,7 @@ function checkDashSettings() {
|
|||
// Mediaelement.js for some reason calls onLoadStart() multiple times
|
||||
// This check is here to force checkVideoSettings to only run once.
|
||||
if (checkedSettings) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
checkedSettings = true;
|
||||
|
@ -108,173 +108,168 @@ function checkDashSettings() {
|
|||
let parseDash = true;
|
||||
let quality = 'Auto';
|
||||
|
||||
let declarePlayer = function() {
|
||||
if (!checkedDash) {
|
||||
return;
|
||||
}
|
||||
let declarePlayer = function () {
|
||||
if (!checkedDash) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (miniPlayerView.validLive) {
|
||||
quality = 'Live';
|
||||
}
|
||||
if (miniPlayerView.validLive) {
|
||||
quality = 'Live';
|
||||
}
|
||||
|
||||
let player = new MediaElementPlayer('player', {
|
||||
features: ['playpause', 'current', 'progress', 'duration', 'volume', 'stop', 'speed', 'quality', 'loop', 'tracks', 'fullscreen', 'timerailthumbnails', 'title'],
|
||||
speeds: ['2', '1.75', '1.5', '1.25', '1', '0.75', '0.5', '0.25'],
|
||||
renderers: ['native_dash', 'native_hls', 'html5'],
|
||||
defaultSpeed: miniPlayerView.defaultPlaybackRate,
|
||||
autoGenerate: true,
|
||||
autoDash: true,
|
||||
autoHLS: false,
|
||||
title: miniPlayerView.videoTitle,
|
||||
qualityText: 'Quality',
|
||||
defaultQuality: 'Auto',
|
||||
stretching: 'responsive',
|
||||
startVolume: miniPlayerView.volume,
|
||||
timeRailThumbnailsSeconds: miniPlayerView.thumbnailInterval,
|
||||
features: ['playpause', 'current', 'progress', 'duration', 'volume', 'stop', 'speed', 'quality', 'loop', 'tracks', 'fullscreen', 'timerailthumbnails', 'title'],
|
||||
speeds: ['2', '1.75', '1.5', '1.25', '1', '0.75', '0.5', '0.25'],
|
||||
renderers: ['native_dash', 'native_hls', 'html5'],
|
||||
defaultSpeed: miniPlayerView.defaultPlaybackRate,
|
||||
autoGenerate: true,
|
||||
autoDash: true,
|
||||
autoHLS: false,
|
||||
title: miniPlayerView.videoTitle,
|
||||
qualityText: 'Quality',
|
||||
defaultQuality: 'Auto',
|
||||
stretching: 'responsive',
|
||||
startVolume: miniPlayerView.volume,
|
||||
timeRailThumbnailsSeconds: miniPlayerView.thumbnailInterval,
|
||||
|
||||
success: function(mediaElement, originalNode, instance) {
|
||||
ft.log(mediaElement,originalNode,instance);
|
||||
success: function (mediaElement, originalNode, instance) {
|
||||
ft.log(mediaElement, originalNode, instance);
|
||||
|
||||
if (miniPlayerView.autoplay) {
|
||||
instance.play();
|
||||
};
|
||||
if (miniPlayerView.autoplay) {
|
||||
instance.play();
|
||||
};
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (miniPlayerView.enableSubtitles && typeof($('.mejs__captions-button').get(0)) !== 'undefined') {
|
||||
window.setTimeout(() => {
|
||||
if (miniPlayerView.enableSubtitles && typeof ($('.mejs__captions-button').get(0)) !== 'undefined') {
|
||||
let captionOptions = $('.mejs__captions-selector-input').get();
|
||||
captionOptions[1].click();
|
||||
};
|
||||
}, 2000);
|
||||
|
||||
let initializeSettings = function() {
|
||||
let qualityOptions = $('.mejs__qualities-selector-input').get();
|
||||
let initializeSettings = function () {
|
||||
let qualityOptions = $('.mejs__qualities-selector-input').get();
|
||||
|
||||
if (qualityOptions.length < 2) {
|
||||
// Other plugin hasn't finished making the qualities. Let's try again in a moment.
|
||||
if (qualityOptions.length < 2) {
|
||||
// Other plugin hasn't finished making the qualities. Let's try again in a moment.
|
||||
|
||||
window.setTimeout(initializeSettings, 500);
|
||||
return;
|
||||
}
|
||||
window.setTimeout(initializeSettings, 500);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof(miniPlayerView.currentTime) !== 'undefined') {
|
||||
instance.currentTime = miniPlayerView.currentTime;
|
||||
miniPlayerView.currentTime = undefined;
|
||||
}
|
||||
if (typeof (miniPlayerView.currentTime) !== 'undefined') {
|
||||
instance.currentTime = miniPlayerView.currentTime;
|
||||
miniPlayerView.currentTime = undefined;
|
||||
}
|
||||
|
||||
let selectedOption = false;
|
||||
qualityOptions.reverse().forEach((option, index) => {
|
||||
if (option.value === miniPlayerView.quality || option.value === miniPlayerView.quality + 'p') {
|
||||
option.click();
|
||||
selectedOption = true;
|
||||
}
|
||||
});
|
||||
let selectedOption = false;
|
||||
qualityOptions.reverse().forEach((option, index) => {
|
||||
if (option.value === miniPlayerView.quality || option.value === miniPlayerView.quality + 'p') {
|
||||
option.click();
|
||||
selectedOption = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (selectedOption === false) {
|
||||
// Assume user selected a higher quality as their default. Select the highest option available.
|
||||
ft.log('Quality not available.');
|
||||
ft.log(qualityOptions.reverse()[0]);
|
||||
if (selectedOption === false) {
|
||||
// Assume user selected a higher quality as their default. Select the highest option available.
|
||||
ft.log('Quality not available.');
|
||||
ft.log(qualityOptions.reverse()[0]);
|
||||
|
||||
qualityOptions.reverse()[0].click();
|
||||
}
|
||||
};
|
||||
qualityOptions.reverse()[0].click();
|
||||
}
|
||||
};
|
||||
|
||||
initializeSettings();
|
||||
},
|
||||
initializeSettings();
|
||||
},
|
||||
|
||||
error: function(error, originalNode, instance) {
|
||||
ft.log(error);
|
||||
ft.log(originalNode);
|
||||
ft.log(instance);
|
||||
checkedSettings = false;
|
||||
miniPlayerView.currentTime = instance.currentTime;
|
||||
miniPlayerView.legacyFormats();
|
||||
}
|
||||
error: function (error, originalNode, instance) {
|
||||
ft.log(error);
|
||||
ft.log(originalNode);
|
||||
ft.log(instance);
|
||||
checkedSettings = false;
|
||||
miniPlayerView.currentTime = instance.currentTime;
|
||||
miniPlayerView.legacyFormats();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (miniPlayerView.validDash !== false) {
|
||||
validateUrl(miniPlayerView.videoDash, (valid) => {
|
||||
miniPlayerView.validDash = valid;
|
||||
validateUrl(miniPlayerView.videoDash, (valid) => {
|
||||
miniPlayerView.validDash = valid;
|
||||
checkedDash = true;
|
||||
declarePlayer();
|
||||
});
|
||||
} else if (miniPlayerView.validLive !== false) {
|
||||
checkedDash = true;
|
||||
declarePlayer();
|
||||
});
|
||||
}
|
||||
else if (miniPlayerView.validLive !== false) {
|
||||
checkedDash = true;
|
||||
declarePlayer();
|
||||
}
|
||||
else {
|
||||
miniPlayerView.legacyFormats();
|
||||
} else {
|
||||
miniPlayerView.legacyFormats();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function checkLegacySettings() {
|
||||
let legacyPlayer = document.getElementById('legacyPlayer');
|
||||
let legacyPlayer = document.getElementById('legacyPlayer');
|
||||
|
||||
let checked720p = false;
|
||||
let checked360p = false;
|
||||
let checkedAudio = false;
|
||||
let checked720p = false;
|
||||
let checked360p = false;
|
||||
let checkedAudio = false;
|
||||
|
||||
let declarePlayer = function() {
|
||||
if (!checked720p || !checked360p || !checkedAudio) {
|
||||
return;
|
||||
let declarePlayer = function () {
|
||||
if (!checked720p || !checked360p || !checkedAudio) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof (miniPlayerView.currentTime) !== 'undefined') {
|
||||
legacyPlayer.currentTime = miniPlayerView.currentTime;
|
||||
miniPlayerView.currentTime = undefined;
|
||||
}
|
||||
|
||||
if (miniPlayerView.autoplay) {
|
||||
legacyPlayer.play();
|
||||
}
|
||||
|
||||
if (miniPlayerView.enableSubtitles) {
|
||||
legacyPlayer.textTracks[0].mode = 'showing';
|
||||
}
|
||||
|
||||
changeVideoSpeed(miniPlayerView.defaultPlaybackRate);
|
||||
};
|
||||
|
||||
if (miniPlayerView.valid360p !== false) {
|
||||
validateUrl(miniPlayerView.video360p, (valid) => {
|
||||
miniPlayerView.valid360p = valid;
|
||||
checked360p = true;
|
||||
declarePlayer();
|
||||
});
|
||||
} else {
|
||||
checked360p = true;
|
||||
declarePlayer();
|
||||
}
|
||||
|
||||
if (typeof(miniPlayerView.currentTime) !== 'undefined') {
|
||||
legacyPlayer.currentTime = miniPlayerView.currentTime;
|
||||
miniPlayerView.currentTime = undefined;
|
||||
if (miniPlayerView.valid720p !== false) {
|
||||
validateUrl(miniPlayerView.video720p, (valid) => {
|
||||
miniPlayerView.valid720p = valid;
|
||||
checked720p = true;
|
||||
declarePlayer();
|
||||
});
|
||||
} else {
|
||||
checked720p = true;
|
||||
declarePlayer();
|
||||
}
|
||||
|
||||
if (miniPlayerView.autoplay) {
|
||||
legacyPlayer.play();
|
||||
if (miniPlayerView.validAudio !== false) {
|
||||
validateUrl(miniPlayerView.videoAudio, (valid) => {
|
||||
miniPlayerView.validAudio = valid;
|
||||
checkedAudio = true;
|
||||
declarePlayer();
|
||||
});
|
||||
} else {
|
||||
checkedAudio = true;
|
||||
declarePlayer();
|
||||
}
|
||||
|
||||
if (miniPlayerView.enableSubtitles) {
|
||||
legacyPlayer.textTracks[0].mode = 'showing';
|
||||
}
|
||||
|
||||
changeVideoSpeed(miniPlayerView.defaultPlaybackRate);
|
||||
};
|
||||
|
||||
if (miniPlayerView.valid360p !== false) {
|
||||
validateUrl(miniPlayerView.video360p, (valid) => {
|
||||
miniPlayerView.valid360p = valid;
|
||||
checked360p = true;
|
||||
declarePlayer();
|
||||
});
|
||||
}
|
||||
else {
|
||||
checked360p = true;
|
||||
declarePlayer();
|
||||
}
|
||||
|
||||
if (miniPlayerView.valid720p !== false) {
|
||||
validateUrl(miniPlayerView.video720p, (valid) => {
|
||||
miniPlayerView.valid720p = valid;
|
||||
checked720p = true;
|
||||
declarePlayer();
|
||||
});
|
||||
}
|
||||
else {
|
||||
checked720p = true;
|
||||
declarePlayer();
|
||||
}
|
||||
|
||||
if (miniPlayerView.validAudio !== false) {
|
||||
validateUrl(miniPlayerView.videoAudio, (valid) => {
|
||||
miniPlayerView.validAudio = valid;
|
||||
checkedAudio = true;
|
||||
declarePlayer();
|
||||
});
|
||||
}
|
||||
else {
|
||||
checkedAudio = true;
|
||||
declarePlayer();
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
function validateUrl(videoUrl, callback) {
|
||||
|
@ -312,141 +307,148 @@ function validateUrl(videoUrl, callback) {
|
|||
* @return {Void}
|
||||
*/
|
||||
function changeVideoSpeed(speed) {
|
||||
if (miniPlayerView.legacySeen) {
|
||||
$('#currentSpeed').html(speed);
|
||||
$('.videoPlayer').get(0).playbackRate = speed;
|
||||
}
|
||||
else {
|
||||
let speedOptions = $('.mejs__speed-selector-input').get();
|
||||
speedOptions.forEach((option, index) => {
|
||||
if (option.value == speed) {
|
||||
option.click();
|
||||
player.playbackRate = speed;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (miniPlayerView.legacySeen) {
|
||||
$('#currentSpeed').html(speed);
|
||||
$('.videoPlayer').get(0).playbackRate = speed;
|
||||
} else {
|
||||
let speedOptions = $('.mejs__speed-selector-input').get();
|
||||
speedOptions.forEach((option, index) => {
|
||||
if (option.value == speed) {
|
||||
option.click();
|
||||
player.playbackRate = speed;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function hideConfirmFunction() {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
electron.ipcRenderer.on('ping', function(event, message) {
|
||||
console.log(message);
|
||||
electron.ipcRenderer.on('ping', function (event, message) {
|
||||
console.log(message);
|
||||
|
||||
miniPlayerView.videoId = message.videoId;
|
||||
miniPlayerView.videoUrl = message.videoUrl;
|
||||
miniPlayerView.videoTitle = message.videoTitle;
|
||||
miniPlayerView.video360p = message.video360p;
|
||||
miniPlayerView.valid360p = message.valid360p;
|
||||
miniPlayerView.video720p = message.video720p;
|
||||
miniPlayerView.valid720p = message.valid720p;
|
||||
miniPlayerView.videoAudio = message.videoAudio;
|
||||
miniPlayerView.validAudio = message.validAudio;
|
||||
miniPlayerView.videoDash = message.videoDash;
|
||||
miniPlayerView.validDash = message.validDash;
|
||||
miniPlayerView.videoLive = message.videoLive;
|
||||
miniPlayerView.validLive = message.validLive;
|
||||
miniPlayerView.subtitleHtml = message.subtitleHtml;
|
||||
miniPlayerView.videoThumbnail = message.videoThumbnail;
|
||||
miniPlayerView.defaultPlaybackRate = message.defaultPlaybackRate;
|
||||
miniPlayerView.quality = message.quality;
|
||||
miniPlayerView.volume = message.volume;
|
||||
miniPlayerView.currentTime = message.currentTime;
|
||||
miniPlayerView.playerSeen = message.playerSeen;
|
||||
miniPlayerView.legacySeen = message.legacySeen;
|
||||
miniPlayerView.autoplay = message.autoplay;
|
||||
miniPlayerView.enableSubtitles = message.enableSubtitles;
|
||||
miniPlayerView.thumbnailInterval = message.thumbnailInterval;
|
||||
miniPlayerView.videoId = message.videoId;
|
||||
miniPlayerView.videoUrl = message.videoUrl;
|
||||
miniPlayerView.videoTitle = message.videoTitle;
|
||||
miniPlayerView.video360p = message.video360p;
|
||||
miniPlayerView.valid360p = message.valid360p;
|
||||
miniPlayerView.video720p = message.video720p;
|
||||
miniPlayerView.valid720p = message.valid720p;
|
||||
miniPlayerView.videoAudio = message.videoAudio;
|
||||
miniPlayerView.validAudio = message.validAudio;
|
||||
miniPlayerView.videoDash = message.videoDash;
|
||||
miniPlayerView.validDash = message.validDash;
|
||||
miniPlayerView.videoLive = message.videoLive;
|
||||
miniPlayerView.validLive = message.validLive;
|
||||
miniPlayerView.subtitleHtml = message.subtitleHtml;
|
||||
miniPlayerView.videoThumbnail = message.videoThumbnail;
|
||||
miniPlayerView.defaultPlaybackRate = message.defaultPlaybackRate;
|
||||
miniPlayerView.quality = message.quality;
|
||||
miniPlayerView.volume = message.volume;
|
||||
miniPlayerView.currentTime = message.currentTime;
|
||||
miniPlayerView.playerSeen = message.playerSeen;
|
||||
miniPlayerView.legacySeen = message.legacySeen;
|
||||
miniPlayerView.autoplay = message.autoplay;
|
||||
miniPlayerView.enableSubtitles = message.enableSubtitles;
|
||||
miniPlayerView.thumbnailInterval = message.thumbnailInterval;
|
||||
|
||||
window.setTimeout(checkDashSettings, 100);
|
||||
window.setTimeout(checkDashSettings, 100);
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('play360p', function(event, message) {
|
||||
if (miniPlayerView.valid360p === false || miniPlayerView.legacySeen === false) {
|
||||
return;
|
||||
}
|
||||
electron.ipcRenderer.on('play360p', function (event, message) {
|
||||
if (miniPlayerView.valid360p === false || miniPlayerView.legacySeen === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
let videoPlayer = $('.videoPlayer').get(0);
|
||||
let videoPlayer = $('.videoPlayer').get(0);
|
||||
|
||||
videoPlayer.pause();
|
||||
videoPlayer.pause();
|
||||
|
||||
let time = videoPlayer.currentTime;
|
||||
let time = videoPlayer.currentTime;
|
||||
|
||||
console.log(time);
|
||||
console.log(time);
|
||||
|
||||
miniPlayerView.videoUrl = miniPlayerView.video360p;
|
||||
miniPlayerView.videoUrl = miniPlayerView.video360p;
|
||||
|
||||
setTimeout(() => {videoPlayer.currentTime = time; videoPlayer.play();}, 100);
|
||||
setTimeout(() => {
|
||||
videoPlayer.currentTime = time;
|
||||
videoPlayer.play();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('play720p', function(event, message) {
|
||||
if (miniPlayerView.valid720p === false || miniPlayerView.legacySeen === false) {
|
||||
return;
|
||||
}
|
||||
electron.ipcRenderer.on('play720p', function (event, message) {
|
||||
if (miniPlayerView.valid720p === false || miniPlayerView.legacySeen === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
let videoPlayer = $('.videoPlayer').get(0);
|
||||
let videoPlayer = $('.videoPlayer').get(0);
|
||||
|
||||
videoPlayer.pause();
|
||||
videoPlayer.pause();
|
||||
|
||||
let time = videoPlayer.currentTime;
|
||||
let time = videoPlayer.currentTime;
|
||||
|
||||
console.log(time);
|
||||
console.log(time);
|
||||
|
||||
miniPlayerView.videoUrl = miniPlayerView.video720p;
|
||||
miniPlayerView.videoUrl = miniPlayerView.video720p;
|
||||
|
||||
setTimeout(() => {videoPlayer.currentTime = time; videoPlayer.play();}, 100);
|
||||
setTimeout(() => {
|
||||
videoPlayer.currentTime = time;
|
||||
videoPlayer.play();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('playAudio', function(event, message) {
|
||||
if (miniPlayerView.validAudio === false || miniPlayerView.legacySeen === false) {
|
||||
return;
|
||||
}
|
||||
electron.ipcRenderer.on('playAudio', function (event, message) {
|
||||
if (miniPlayerView.validAudio === false || miniPlayerView.legacySeen === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
let videoPlayer = $('.videoPlayer').get(0);
|
||||
let videoPlayer = $('.videoPlayer').get(0);
|
||||
|
||||
videoPlayer.pause();
|
||||
videoPlayer.pause();
|
||||
|
||||
let time = videoPlayer.currentTime;
|
||||
let time = videoPlayer.currentTime;
|
||||
|
||||
console.log(time);
|
||||
console.log(time);
|
||||
|
||||
miniPlayerView.videoUrl = miniPlayerView.videoAudio;
|
||||
miniPlayerView.videoUrl = miniPlayerView.videoAudio;
|
||||
|
||||
setTimeout(() => {videoPlayer.currentTime = time; videoPlayer.play();}, 100);
|
||||
setTimeout(() => {
|
||||
videoPlayer.currentTime = time;
|
||||
videoPlayer.play();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('videoSpeed', function(event, message) {
|
||||
changeVideoSpeed(message);
|
||||
electron.ipcRenderer.on('videoSpeed', function (event, message) {
|
||||
changeVideoSpeed(message);
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('videoLoop', function(event, message) {
|
||||
let videoPlayer = $('.videoPlayer').get(0);
|
||||
electron.ipcRenderer.on('videoLoop', function (event, message) {
|
||||
let videoPlayer = $('.videoPlayer').get(0);
|
||||
|
||||
videoPlayer.loop = !videoPlayer.loop;
|
||||
videoPlayer.loop = !videoPlayer.loop;
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('dashPlayer', function(event, message) {
|
||||
miniPlayerView.dashFormats();
|
||||
electron.ipcRenderer.on('dashPlayer', function (event, message) {
|
||||
miniPlayerView.dashFormats();
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('legacyPlayer', function(event, message) {
|
||||
miniPlayerView.legacyFormats();
|
||||
electron.ipcRenderer.on('legacyPlayer', function (event, message) {
|
||||
miniPlayerView.legacyFormats();
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('youtubePlayer', function(event, message) {
|
||||
miniPlayerView.embedPlayer();
|
||||
electron.ipcRenderer.on('youtubePlayer', function (event, message) {
|
||||
miniPlayerView.embedPlayer();
|
||||
});
|
||||
|
||||
window.onbeforeunload = (e) => {
|
||||
let lengthSeconds = 0;
|
||||
let lengthSeconds = 0;
|
||||
|
||||
if (miniPlayerView.legacySeen === false) {
|
||||
lengthSeconds = player.currentTime;
|
||||
}
|
||||
else {
|
||||
lengthSeconds = $('.videoPlayer').get(0).currentTime;
|
||||
}
|
||||
if (miniPlayerView.legacySeen === false) {
|
||||
lengthSeconds = player.currentTime;
|
||||
} else {
|
||||
lengthSeconds = $('.videoPlayer').get(0).currentTime;
|
||||
}
|
||||
|
||||
updateWatchProgress(miniPlayerView.videoId, lengthSeconds);
|
||||
updateWatchProgress(miniPlayerView.videoId, lengthSeconds);
|
||||
};
|
||||
|
|
192
src/js/player.js
192
src/js/player.js
|
@ -52,7 +52,7 @@ function playVideo(videoId, playlistId = '') {
|
|||
playerView.videoDash = invidiousInstance + '/api/manifest/dash/' + videoId + '.mpd';
|
||||
|
||||
if (settingsView.proxyVideos) {
|
||||
playerView.videoDash = playerView.videoDash + '?local=true';
|
||||
playerView.videoDash = playerView.videoDash + '?local=true';
|
||||
}
|
||||
|
||||
playerView.embededHtml = "<iframe width='560' height='315' src='https://www.youtube-nocookie.com/embed/" + videoId + "?rel=0' frameborder='0' allow='autoplay; encrypted-media' allowfullscreen></iframe>";
|
||||
|
@ -61,19 +61,19 @@ function playVideo(videoId, playlistId = '') {
|
|||
let player;
|
||||
|
||||
switch (defaultPlayer) {
|
||||
case 'dash':
|
||||
playerView.playerSeen = true;
|
||||
playerView.legacySeen = false;
|
||||
break;
|
||||
case 'legacy':
|
||||
playerView.playerSeen = false;
|
||||
playerView.legacySeen = true;
|
||||
break;
|
||||
case 'embed':
|
||||
playerView.playerSeen = false;
|
||||
playerView.legacySeen = false;
|
||||
break;
|
||||
default:
|
||||
case 'dash':
|
||||
playerView.playerSeen = true;
|
||||
playerView.legacySeen = false;
|
||||
break;
|
||||
case 'legacy':
|
||||
playerView.playerSeen = false;
|
||||
playerView.legacySeen = true;
|
||||
break;
|
||||
case 'embed':
|
||||
playerView.playerSeen = false;
|
||||
playerView.legacySeen = false;
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
|
@ -124,14 +124,14 @@ function playVideo(videoId, playlistId = '') {
|
|||
// Search through the returned object to get the 360p and 720p video URLs (If available)
|
||||
Object.keys(videoUrls).forEach((key) => {
|
||||
switch (videoUrls[key]['itag']) {
|
||||
case '18':
|
||||
playerView.video360p = decodeURIComponent(videoUrls[key]['url']);
|
||||
// ft.log(playerView.video360p);
|
||||
break;
|
||||
case '22':
|
||||
playerView.video720p = decodeURIComponent(videoUrls[key]['url']);
|
||||
// ft.log(playerView.video720p);
|
||||
break;
|
||||
case '18':
|
||||
playerView.video360p = decodeURIComponent(videoUrls[key]['url']);
|
||||
// ft.log(playerView.video360p);
|
||||
break;
|
||||
case '22':
|
||||
playerView.video720p = decodeURIComponent(videoUrls[key]['url']);
|
||||
// ft.log(playerView.video720p);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -143,7 +143,7 @@ function playVideo(videoId, playlistId = '') {
|
|||
playerView.legacySeen = true;
|
||||
}
|
||||
|
||||
if (typeof(playerView.videoAudio) === 'undefined') {
|
||||
if (typeof (playerView.videoAudio) === 'undefined') {
|
||||
ft.log(playerView.videoAudio);
|
||||
playerView.validAudio = false;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ function playVideo(videoId, playlistId = '') {
|
|||
let useEmbedPlayer = false;
|
||||
|
||||
// Default to the embeded player if the URLs cannot be found.
|
||||
if (typeof(playerView.video720p) === 'undefined' && typeof(playerView.video360p) === 'undefined') {
|
||||
if (typeof (playerView.video720p) === 'undefined' && typeof (playerView.video360p) === 'undefined') {
|
||||
//useEmbedPlayer = true;
|
||||
playerView.currentQuality = 'EMBED';
|
||||
playerView.playerSeen = false;
|
||||
|
@ -160,7 +160,7 @@ function playVideo(videoId, playlistId = '') {
|
|||
playerView.video720p = '';
|
||||
//useEmbedPlayer = true;
|
||||
showToast('Unable to get video file. Reverting to embeded player.');
|
||||
} else if (typeof(playerView.video720p) === 'undefined' && typeof(playerView.video360p) !== 'undefined') {
|
||||
} else if (typeof (playerView.video720p) === 'undefined' && typeof (playerView.video360p) !== 'undefined') {
|
||||
// Default to the 360p video if the 720p URL cannot be found.
|
||||
ft.log('Found');
|
||||
playerView.videoUrl = playerView.video360p;
|
||||
|
@ -269,7 +269,7 @@ function playVideo(videoId, playlistId = '') {
|
|||
playerView.recommendedVideoList = playerView.recommendedVideoList.concat(data);
|
||||
});
|
||||
|
||||
if (typeof(data.captions) !== 'undefined') {
|
||||
if (typeof (data.captions) !== 'undefined') {
|
||||
data.captions.forEach((caption) => {
|
||||
let subtitleUrl = invidiousInstance + caption.url;
|
||||
|
||||
|
@ -286,23 +286,23 @@ function playVideo(videoId, playlistId = '') {
|
|||
// Search through the returned object to get the 360p and 720p video URLs (If available)
|
||||
Object.keys(videoUrls).forEach((key) => {
|
||||
switch (videoUrls[key]['itag']) {
|
||||
case '18':
|
||||
playerView.video360p = decodeURIComponent(videoUrls[key]['url']);
|
||||
// ft.log(playerView.video360p);
|
||||
break;
|
||||
case '22':
|
||||
playerView.video720p = decodeURIComponent(videoUrls[key]['url']);
|
||||
// ft.log(playerView.video720p);
|
||||
break;
|
||||
case '18':
|
||||
playerView.video360p = decodeURIComponent(videoUrls[key]['url']);
|
||||
// ft.log(playerView.video360p);
|
||||
break;
|
||||
case '22':
|
||||
playerView.video720p = decodeURIComponent(videoUrls[key]['url']);
|
||||
// ft.log(playerView.video720p);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof(playerView.video360p) === 'undefined') {
|
||||
if (typeof (playerView.video360p) === 'undefined') {
|
||||
playerView.video360p = '';
|
||||
playerView.valid360p = false;
|
||||
}
|
||||
|
||||
if (typeof(playerView.video720p) === 'undefined') {
|
||||
if (typeof (playerView.video720p) === 'undefined') {
|
||||
playerView.video720p = '';
|
||||
playerView.valid720p = false;
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ function playVideo(videoId, playlistId = '') {
|
|||
playerView.legacySeen = true;
|
||||
}
|
||||
|
||||
if (typeof(playerView.videoAudio) === 'undefined') {
|
||||
if (typeof (playerView.videoAudio) === 'undefined') {
|
||||
ft.log(playerView.videoAudio);
|
||||
playerView.videoAudio = '';
|
||||
playerView.validAudio = false;
|
||||
|
@ -395,7 +395,7 @@ function playVideo(videoId, playlistId = '') {
|
|||
if (rememberHistory === true) {
|
||||
historyDb.findOne({
|
||||
videoId: playerView.videoId
|
||||
}, function(err, doc) {
|
||||
}, function (err, doc) {
|
||||
let watchProgress = 0;
|
||||
|
||||
if (doc !== null) {
|
||||
|
@ -440,7 +440,7 @@ function openMiniPlayer() {
|
|||
let videoPlayer;
|
||||
// Grabs whatever the HTML is for the current video player. Done this way to grab
|
||||
// the HTML5 player (with varying qualities) as well as the YouTube embeded player.
|
||||
if (typeof(player) !== 'undefined') {
|
||||
if (typeof (player) !== 'undefined') {
|
||||
videoPlayer = player;
|
||||
} else {
|
||||
videoPlayer = $('.videoPlayer').get(0);
|
||||
|
@ -630,14 +630,14 @@ function openMiniPlayer() {
|
|||
};
|
||||
miniPlayer.webContents.send('ping', playerData);
|
||||
|
||||
let tmpSize = [0,0];
|
||||
let tmpSize = [0, 0];
|
||||
|
||||
miniPlayer.on('resize', (e)=>{
|
||||
var size = miniPlayer.getSize()
|
||||
if( Math.abs(size[0]-tmpSize[0]) > 2 || Math.abs(size[1]-tmpSize[1]) > 2){
|
||||
miniPlayer.setSize(size[0], parseInt(size[0] * 9 / 16))
|
||||
}
|
||||
tmpSize = size;
|
||||
miniPlayer.on('resize', (e) => {
|
||||
var size = miniPlayer.getSize()
|
||||
if (Math.abs(size[0] - tmpSize[0]) > 2 || Math.abs(size[1] - tmpSize[1]) > 2) {
|
||||
miniPlayer.setSize(size[0], parseInt(size[0] * 9 / 16))
|
||||
}
|
||||
tmpSize = size;
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -655,7 +655,7 @@ function clickMiniPlayer(videoId) {
|
|||
|
||||
showToast("Opening in mini player, Please wait.");
|
||||
|
||||
let playVideo = function(videoData) {
|
||||
let playVideo = function (videoData) {
|
||||
if (videoData.checked720p === false || videoData.checked360p === false || videoData.checkedAudio === false || videoData.checkedDash === false || videoData.checkedLive === false) {
|
||||
return;
|
||||
}
|
||||
|
@ -813,14 +813,14 @@ function clickMiniPlayer(videoId) {
|
|||
miniPlayer.webContents.send('ping', videoData);
|
||||
showToast('Video has been opened in a new window.');
|
||||
|
||||
let tmpSize = [0,0];
|
||||
let tmpSize = [0, 0];
|
||||
|
||||
miniPlayer.on('resize', (e)=>{
|
||||
var size = miniPlayer.getSize()
|
||||
if( Math.abs(size[0]-tmpSize[0]) > 2 || Math.abs(size[1]-tmpSize[1]) > 2){
|
||||
miniPlayer.setSize(size[0], parseInt(size[0] * 9 / 16))
|
||||
}
|
||||
tmpSize = size;
|
||||
miniPlayer.on('resize', (e) => {
|
||||
var size = miniPlayer.getSize()
|
||||
if (Math.abs(size[0] - tmpSize[0]) > 2 || Math.abs(size[1] - tmpSize[1]) > 2) {
|
||||
miniPlayer.setSize(size[0], parseInt(size[0] * 9 / 16))
|
||||
}
|
||||
tmpSize = size;
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -847,7 +847,7 @@ function clickMiniPlayer(videoId) {
|
|||
}
|
||||
};
|
||||
|
||||
let validateData = function(data) {
|
||||
let validateData = function (data) {
|
||||
let newData = data;
|
||||
newData.checked720p = false;
|
||||
newData.checked360p = false;
|
||||
|
@ -903,7 +903,7 @@ function clickMiniPlayer(videoId) {
|
|||
videoData.videoDash = invidiousInstance + '/api/manifest/dash/' + videoId + '.mpd?unique_res=1';
|
||||
|
||||
if (settingsView.proxyVideos) {
|
||||
videoData.videoDash = videoData.videoDash + '&local=true';
|
||||
videoData.videoDash = videoData.videoDash + '&local=true';
|
||||
}
|
||||
|
||||
videoData.autoplay = autoplay;
|
||||
|
@ -914,7 +914,7 @@ function clickMiniPlayer(videoId) {
|
|||
|
||||
historyDb.findOne({
|
||||
videoId: videoData.videoId
|
||||
}, function(err, doc) {
|
||||
}, function (err, doc) {
|
||||
if (doc !== null) {
|
||||
videoData.currentTime = doc.watchProgress;
|
||||
} else {
|
||||
|
@ -939,12 +939,12 @@ function clickMiniPlayer(videoId) {
|
|||
|
||||
Object.keys(videoUrls).forEach((key) => {
|
||||
switch (videoUrls[key]['itag']) {
|
||||
case '18':
|
||||
videoData.video360p = videoUrls[key]['url'];
|
||||
break;
|
||||
case '22':
|
||||
videoData.video720p = videoUrls[key]['url'];
|
||||
break;
|
||||
case '18':
|
||||
videoData.video360p = videoUrls[key]['url'];
|
||||
break;
|
||||
case '22':
|
||||
videoData.video720p = videoUrls[key]['url'];
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -967,12 +967,12 @@ function clickMiniPlayer(videoId) {
|
|||
|
||||
Object.keys(videoUrls).forEach((key) => {
|
||||
switch (videoUrls[key]['itag']) {
|
||||
case '18':
|
||||
videoData.video360p = videoUrls[key]['url'];
|
||||
break;
|
||||
case '22':
|
||||
videoData.video720p = videoUrls[key]['url'];
|
||||
break;
|
||||
case '18':
|
||||
videoData.video360p = videoUrls[key]['url'];
|
||||
break;
|
||||
case '22':
|
||||
videoData.video720p = videoUrls[key]['url'];
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -988,7 +988,7 @@ function clickMiniPlayer(videoId) {
|
|||
|
||||
let videoHtml = '';
|
||||
|
||||
if (typeof(data.captions) !== 'undefined') {
|
||||
if (typeof (data.captions) !== 'undefined') {
|
||||
data.captions.forEach((caption) => {
|
||||
let subtitleUrl = invidiousInstance + caption.url;
|
||||
|
||||
|
@ -1043,7 +1043,7 @@ function checkDashSettings() {
|
|||
let parseDash = true;
|
||||
let quality = 'Auto';
|
||||
|
||||
let declarePlayer = function() {
|
||||
let declarePlayer = function () {
|
||||
if (!checkedDash) {
|
||||
return;
|
||||
}
|
||||
|
@ -1067,7 +1067,7 @@ function checkDashSettings() {
|
|||
startVolume: currentVolume,
|
||||
timeRailThumbnailsSeconds: playerView.thumbnailInterval,
|
||||
|
||||
success: function(mediaElement, originalNode, instance) {
|
||||
success: function (mediaElement, originalNode, instance) {
|
||||
ft.log(mediaElement, originalNode, instance);
|
||||
|
||||
if (autoplay) {
|
||||
|
@ -1076,7 +1076,7 @@ function checkDashSettings() {
|
|||
};
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (enableSubtitles && typeof($('.mejs__captions-button').get(0)) !== 'undefined') {
|
||||
if (enableSubtitles && typeof ($('.mejs__captions-button').get(0)) !== 'undefined') {
|
||||
let captionOptions = $('.mejs__captions-selector-input').get();
|
||||
if (captionOptions.length > 1) {
|
||||
captionOptions[1].click();
|
||||
|
@ -1088,7 +1088,7 @@ function checkDashSettings() {
|
|||
};
|
||||
}, 2000);
|
||||
|
||||
let initializeSettings = function() {
|
||||
let initializeSettings = function () {
|
||||
let qualityOptions = $('.mejs__qualities-selector-input').get();
|
||||
|
||||
if (qualityOptions.length < 2) {
|
||||
|
@ -1116,26 +1116,26 @@ function checkDashSettings() {
|
|||
}
|
||||
|
||||
window.setTimeout(() => {
|
||||
historyDb.findOne({
|
||||
videoId: playerView.videoId
|
||||
}, function(err, doc) {
|
||||
if (doc !== null) {
|
||||
console.log('History');
|
||||
if (typeof(playerView.currentTime) !== 'undefined') {
|
||||
instance.currentTime = playerView.currentTime;
|
||||
playerView.currentTime = undefined;
|
||||
} else if (doc.watchProgress < instance.duration - 5 && playerView.validLive === false) {
|
||||
instance.currentTime = doc.watchProgress;
|
||||
}
|
||||
}
|
||||
});
|
||||
historyDb.findOne({
|
||||
videoId: playerView.videoId
|
||||
}, function (err, doc) {
|
||||
if (doc !== null) {
|
||||
console.log('History');
|
||||
if (typeof (playerView.currentTime) !== 'undefined') {
|
||||
instance.currentTime = playerView.currentTime;
|
||||
playerView.currentTime = undefined;
|
||||
} else if (doc.watchProgress < instance.duration - 5 && playerView.validLive === false) {
|
||||
instance.currentTime = doc.watchProgress;
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 200);
|
||||
};
|
||||
|
||||
initializeSettings();
|
||||
},
|
||||
|
||||
error: function(error, originalNode, instance) {
|
||||
error: function (error, originalNode, instance) {
|
||||
ft.log(error);
|
||||
ft.log(originalNode);
|
||||
ft.log(instance);
|
||||
|
@ -1170,12 +1170,12 @@ function checkLegacySettings() {
|
|||
let checked360p = false;
|
||||
let checkedAudio = false;
|
||||
|
||||
let declarePlayer = function() {
|
||||
let declarePlayer = function () {
|
||||
if (!checked720p || !checked360p || !checkedAudio) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof(playerView.currentTime) !== 'undefined') {
|
||||
if (typeof (playerView.currentTime) !== 'undefined') {
|
||||
player.currentTime = playerView.currentTime;
|
||||
}
|
||||
|
||||
|
@ -1188,9 +1188,9 @@ function checkLegacySettings() {
|
|||
window.setTimeout(() => {
|
||||
historyDb.findOne({
|
||||
videoId: playerView.videoId
|
||||
}, function(err, doc) {
|
||||
}, function (err, doc) {
|
||||
if (doc !== null) {
|
||||
if (doc.watchProgress < player.duration - 5 && typeof(playerView.currentTime) === 'undefined') {
|
||||
if (doc.watchProgress < player.duration - 5 && typeof (playerView.currentTime) === 'undefined') {
|
||||
player.currentTime = doc.watchProgress;
|
||||
}
|
||||
|
||||
|
@ -1244,10 +1244,10 @@ function checkLegacySettings() {
|
|||
|
||||
function playNext(timeLeft) {
|
||||
if (playerView.playlistSeen && !settingsView.autoplayPlaylists) {
|
||||
return;
|
||||
return;
|
||||
};
|
||||
if (!playerView.playlistSeen && !settingsView.playNextVideo) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
const clearHtml = "<span class='link' onclick='stopPlayNext()'>Cancel</span>";
|
||||
|
||||
|
@ -1310,8 +1310,8 @@ function playNextVideo() {
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
loadingView.seen = true;
|
||||
playVideo(playerView.recommendedVideoList[0].id);
|
||||
loadingView.seen = true;
|
||||
playVideo(playerView.recommendedVideoList[0].id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,87 +16,88 @@
|
|||
*/
|
||||
|
||||
function showPlaylist(playlistId) {
|
||||
hideViews();
|
||||
loadingView.seen = true;
|
||||
hideViews();
|
||||
loadingView.seen = true;
|
||||
|
||||
playlistView.videoList = [];
|
||||
playlistView.videoList = [];
|
||||
|
||||
invidiousAPI('playlists', playlistId, {}, (data) => {
|
||||
ft.log(data);
|
||||
|
||||
playlistView.playlistId = playlistId;
|
||||
playlistView.channelName = data.author;
|
||||
playlistView.channelId = data.authorId;
|
||||
playlistView.channelThumbnail = data.authorThumbnails[3].url;
|
||||
playlistView.title = data.title;
|
||||
playlistView.videoCount = data.videoCount;
|
||||
playlistView.viewCount = data.viewCount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
playlistView.thumbnail = data.videos[Math.floor((Math.random() * data.videos.length) + 1)].videoThumbnails[0].url;
|
||||
playlistView.description = data.descriptionHtml;
|
||||
let dateString = new Date(data.updated * 1000);
|
||||
dateString.setDate(dateString.getDate() + 1);
|
||||
playlistView.lastUpdated = dateFormat(dateString, "mmm dS, yyyy");
|
||||
|
||||
let amountOfPages = Math.ceil(data.videoCount / 100);
|
||||
|
||||
ft.log(amountOfPages);
|
||||
|
||||
for (let i = 1; i <= amountOfPages; i++) {
|
||||
invidiousAPI('playlists', playlistId, {page: i}, (data) => {
|
||||
invidiousAPI('playlists', playlistId, {}, (data) => {
|
||||
ft.log(data);
|
||||
data.videos.forEach((video) => {
|
||||
let videoData = {};
|
||||
|
||||
let time = video.lengthSeconds;
|
||||
let hours = 0;
|
||||
playlistView.playlistId = playlistId;
|
||||
playlistView.channelName = data.author;
|
||||
playlistView.channelId = data.authorId;
|
||||
playlistView.channelThumbnail = data.authorThumbnails[3].url;
|
||||
playlistView.title = data.title;
|
||||
playlistView.videoCount = data.videoCount;
|
||||
playlistView.viewCount = data.viewCount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
playlistView.thumbnail = data.videos[Math.floor((Math.random() * data.videos.length) + 1)].videoThumbnails[0].url;
|
||||
playlistView.description = data.descriptionHtml;
|
||||
let dateString = new Date(data.updated * 1000);
|
||||
dateString.setDate(dateString.getDate() + 1);
|
||||
playlistView.lastUpdated = dateFormat(dateString, "mmm dS, yyyy");
|
||||
|
||||
if (time >= 3600) {
|
||||
hours = Math.floor(time / 3600);
|
||||
time = time - hours * 3600;
|
||||
}
|
||||
let amountOfPages = Math.ceil(data.videoCount / 100);
|
||||
|
||||
let minutes = Math.floor(time / 60);
|
||||
let seconds = time - minutes * 60;
|
||||
ft.log(amountOfPages);
|
||||
|
||||
if (seconds < 10) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
for (let i = 1; i <= amountOfPages; i++) {
|
||||
invidiousAPI('playlists', playlistId, {
|
||||
page: i
|
||||
}, (data) => {
|
||||
ft.log(data);
|
||||
data.videos.forEach((video) => {
|
||||
let videoData = {};
|
||||
|
||||
if (minutes < 10 && hours > 0) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
let time = video.lengthSeconds;
|
||||
let hours = 0;
|
||||
|
||||
if (hours > 0) {
|
||||
videoData.duration = hours + ":" + minutes + ":" + seconds;
|
||||
} else {
|
||||
videoData.duration = minutes + ":" + seconds;
|
||||
}
|
||||
if (time >= 3600) {
|
||||
hours = Math.floor(time / 3600);
|
||||
time = time - hours * 3600;
|
||||
}
|
||||
|
||||
videoData.id = video.videoId;
|
||||
videoData.title = video.title;
|
||||
videoData.channelName = video.author;
|
||||
videoData.channelId = video.authorId;
|
||||
videoData.thumbnail = video.videoThumbnails[4].url;
|
||||
let minutes = Math.floor(time / 60);
|
||||
let seconds = time - minutes * 60;
|
||||
|
||||
playlistView.videoList[video.index] = videoData;
|
||||
});
|
||||
if (playlistView.seen !== false) {
|
||||
playlistView.seen = false;
|
||||
playlistView.seen = true;
|
||||
if (seconds < 10) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
|
||||
if (minutes < 10 && hours > 0) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
|
||||
if (hours > 0) {
|
||||
videoData.duration = hours + ":" + minutes + ":" + seconds;
|
||||
} else {
|
||||
videoData.duration = minutes + ":" + seconds;
|
||||
}
|
||||
|
||||
videoData.id = video.videoId;
|
||||
videoData.title = video.title;
|
||||
videoData.channelName = video.author;
|
||||
videoData.channelId = video.authorId;
|
||||
videoData.thumbnail = video.videoThumbnails[4].url;
|
||||
|
||||
playlistView.videoList[video.index] = videoData;
|
||||
});
|
||||
if (playlistView.seen !== false) {
|
||||
playlistView.seen = false;
|
||||
playlistView.seen = true;
|
||||
}
|
||||
});
|
||||
|
||||
loadingView.seen = false;
|
||||
playlistView.seen = true;
|
||||
}
|
||||
});
|
||||
|
||||
loadingView.seen = false;
|
||||
playlistView.seen = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function togglePlaylist() {
|
||||
if (playerView.playlistShowList !== false) {
|
||||
playerView.playlistShowList = false;
|
||||
}
|
||||
else{
|
||||
playerView.playlistShowList = true;
|
||||
}
|
||||
if (playerView.playlistShowList !== false) {
|
||||
playerView.playlistShowList = false;
|
||||
} else {
|
||||
playerView.playlistShowList = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,30 +33,30 @@ function addSavedVideo(videoId) {
|
|||
|
||||
checkIfSaved.then((saved) => {
|
||||
if (saved === false) {
|
||||
invidiousAPI('videos', videoId, {}, (data) => {
|
||||
let publishedText = new Date(data.published * 1000);
|
||||
publishedText = dateFormat(publishedText, "mmm dS, yyyy");
|
||||
let videoData = {
|
||||
videoId: videoId,
|
||||
published: data.published,
|
||||
publishedText: publishedText,
|
||||
description: data.description,
|
||||
viewCount: data.viewCount,
|
||||
title: data.title,
|
||||
lengthSeconds: data.lengthSeconds,
|
||||
videoThumbnails: data.videoThumbnails[4].url,
|
||||
author: data.author,
|
||||
authorId: data.authorId,
|
||||
liveNow: false,
|
||||
paid: false,
|
||||
type: 'video',
|
||||
timeSaved: new Date().getTime(),
|
||||
};
|
||||
invidiousAPI('videos', videoId, {}, (data) => {
|
||||
let publishedText = new Date(data.published * 1000);
|
||||
publishedText = dateFormat(publishedText, "mmm dS, yyyy");
|
||||
let videoData = {
|
||||
videoId: videoId,
|
||||
published: data.published,
|
||||
publishedText: publishedText,
|
||||
description: data.description,
|
||||
viewCount: data.viewCount,
|
||||
title: data.title,
|
||||
lengthSeconds: data.lengthSeconds,
|
||||
videoThumbnails: data.videoThumbnails[4].url,
|
||||
author: data.author,
|
||||
authorId: data.authorId,
|
||||
liveNow: false,
|
||||
paid: false,
|
||||
type: 'video',
|
||||
timeSaved: new Date().getTime(),
|
||||
};
|
||||
|
||||
savedVidsDb.insert(videoData, (err, newDoc) => {
|
||||
showToast('The video has been favorited!');
|
||||
});
|
||||
});
|
||||
savedVidsDb.insert(videoData, (err, newDoc) => {
|
||||
showToast('The video has been favorited!');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
showToast('The video has already been favorited!')
|
||||
}
|
||||
|
@ -75,10 +75,10 @@ function removeSavedVideo(videoId, toast = true) {
|
|||
videoId: videoId
|
||||
}, {}, (err, numRemoved) => {
|
||||
if (toast) {
|
||||
showToast('Video has been removed from the favorites list.');
|
||||
showToast('Video has been removed from the favorites list.');
|
||||
}
|
||||
if (savedView.seen === true) {
|
||||
showSavedVideos();
|
||||
showSavedVideos();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -144,40 +144,40 @@ function showSavedVideos() {
|
|||
timeSaved: -1
|
||||
}).exec((err, docs) => {
|
||||
docs.forEach((video, index) => {
|
||||
if (typeof(video.author) === 'undefined'){
|
||||
invidiousAPI('videos', video.videoId, {}, (data) => {
|
||||
let publishedText = new Date(data.published * 1000);
|
||||
publishedText = dateFormat(publishedText, "mmm dS, yyyy");
|
||||
let videoData = {
|
||||
videoId: video.videoId,
|
||||
published: data.published,
|
||||
publishedText: publishedText,
|
||||
description: data.description,
|
||||
viewCount: data.viewCount,
|
||||
title: data.title,
|
||||
lengthSeconds: data.lengthSeconds,
|
||||
videoThumbnails: data.videoThumbnails[4].url,
|
||||
author: data.author,
|
||||
authorId: data.authorId,
|
||||
liveNow: false,
|
||||
paid: false,
|
||||
type: 'video',
|
||||
};
|
||||
if (typeof (video.author) === 'undefined') {
|
||||
invidiousAPI('videos', video.videoId, {}, (data) => {
|
||||
let publishedText = new Date(data.published * 1000);
|
||||
publishedText = dateFormat(publishedText, "mmm dS, yyyy");
|
||||
let videoData = {
|
||||
videoId: video.videoId,
|
||||
published: data.published,
|
||||
publishedText: publishedText,
|
||||
description: data.description,
|
||||
viewCount: data.viewCount,
|
||||
title: data.title,
|
||||
lengthSeconds: data.lengthSeconds,
|
||||
videoThumbnails: data.videoThumbnails[4].url,
|
||||
author: data.author,
|
||||
authorId: data.authorId,
|
||||
liveNow: false,
|
||||
paid: false,
|
||||
type: 'video',
|
||||
};
|
||||
|
||||
savedVidsDb.update(
|
||||
{ videoId: data.videoId },
|
||||
videoData, {}, (err, newDoc) => {});
|
||||
savedVidsDb.update({
|
||||
videoId: data.videoId
|
||||
},
|
||||
videoData, {}, (err, newDoc) => {});
|
||||
|
||||
videoData.position = index;
|
||||
displayVideo(videoData, 'saved');
|
||||
}, () => {
|
||||
removeSavedVideo(video.videoId, false);
|
||||
});
|
||||
}
|
||||
else {
|
||||
video.position = index;
|
||||
displayVideo(video, 'saved');
|
||||
}
|
||||
videoData.position = index;
|
||||
displayVideo(videoData, 'saved');
|
||||
}, () => {
|
||||
removeSavedVideo(video.videoId, false);
|
||||
});
|
||||
} else {
|
||||
video.position = index;
|
||||
displayVideo(video, 'saved');
|
||||
}
|
||||
});
|
||||
|
||||
loadingView.seen = false;
|
||||
|
|
|
@ -181,12 +181,10 @@ function checkDefaultSettings() {
|
|||
'distractionFreeMode': false,
|
||||
'hideWatchedSubs': false,
|
||||
'videoView': 'grid',
|
||||
'profileList': [
|
||||
{
|
||||
'profileList': [{
|
||||
name: 'All Channels',
|
||||
color: randomColor
|
||||
},
|
||||
],
|
||||
}, ],
|
||||
'defaultProfile': 'All Channels',
|
||||
};
|
||||
|
||||
|
|
|
@ -97,11 +97,13 @@ function removeSubscription(channelId, profile = profileSelectView.activeProfile
|
|||
value: profile
|
||||
}
|
||||
}
|
||||
}, { multi: true },(err, numRemoved) => {
|
||||
}, {
|
||||
multi: true
|
||||
}, (err, numRemoved) => {
|
||||
// Refresh the list of subscriptions on the side navigation bar.
|
||||
displaySubs();
|
||||
if (displayToast) {
|
||||
showToast('Removed channel from subscriptions.');
|
||||
showToast('Removed channel from subscriptions.');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@ -111,7 +113,7 @@ function removeSubscription(channelId, profile = profileSelectView.activeProfile
|
|||
// Refresh the list of subscriptions on the side navigation bar.
|
||||
displaySubs();
|
||||
if (displayToast) {
|
||||
showToast('Removed channel from subscriptions.');
|
||||
showToast('Removed channel from subscriptions.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -203,9 +205,9 @@ function addSubsToView(videoList) {
|
|||
}
|
||||
|
||||
if (profileSelectView.activeProfile.name !== 'All Channels') {
|
||||
videoList = videoList.filter(a => {
|
||||
return a.profile.map(x => x.value).indexOf(profileSelectView.activeProfile.name) !== -1
|
||||
});
|
||||
videoList = videoList.filter(a => {
|
||||
return a.profile.map(x => x.value).indexOf(profileSelectView.activeProfile.name) !== -1
|
||||
});
|
||||
}
|
||||
|
||||
videoList.sort((a, b) => {
|
||||
|
@ -233,6 +235,13 @@ function addSubsToView(videoList) {
|
|||
checkSubscriptions = true;
|
||||
}, 7200000);
|
||||
|
||||
let profileLockTimer = window.setInterval(() => {
|
||||
if (videoList.length === subscriptionView.videoList.length || subscriptionView.videoList.length === 100) {
|
||||
profileSelectView.profileLock = false;
|
||||
clearInterval(profileLockTimer);
|
||||
}
|
||||
}, 500);
|
||||
|
||||
ft.log('Done');
|
||||
}
|
||||
|
||||
|
@ -288,13 +297,14 @@ function displaySubs() {
|
|||
channelName: 1
|
||||
}).exec((err, subs) => {
|
||||
let subFilter;
|
||||
if (profileSelectView.activeProfile.name === 'All Channels' || typeof(profileSelectView.activeProfile.name) === 'undefined') {
|
||||
subFilter = subs;
|
||||
}
|
||||
else {
|
||||
subFilter = subs.filter(a => {
|
||||
return a.profile.find((name) => {return name.value === profileSelectView.activeProfile.name });
|
||||
});
|
||||
if (profileSelectView.activeProfile.name === 'All Channels' || typeof (profileSelectView.activeProfile.name) === 'undefined') {
|
||||
subFilter = subs;
|
||||
} else {
|
||||
subFilter = subs.filter(a => {
|
||||
return a.profile.find((name) => {
|
||||
return name.value === profileSelectView.activeProfile.name
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
subFilter.forEach((channel) => {
|
||||
|
|
|
@ -167,11 +167,11 @@ let searchSuggestionsView = new Vue({
|
|||
suggestionList: [],
|
||||
},
|
||||
methods: {
|
||||
newSearchTerm: (text) => {
|
||||
document.getElementById('search').value = text;
|
||||
getSearchSuggestion();
|
||||
searchSuggestionsView.seen = false;
|
||||
},
|
||||
newSearchTerm: (text) => {
|
||||
document.getElementById('search').value = text;
|
||||
getSearchSuggestion();
|
||||
searchSuggestionsView.seen = false;
|
||||
},
|
||||
},
|
||||
template: searchSuggestionsViewTemplate
|
||||
});
|
||||
|
@ -573,22 +573,22 @@ let channelView = new Vue({
|
|||
},
|
||||
methods: {
|
||||
videoTab: () => {
|
||||
channelVideosView.seen = true;
|
||||
channelView.aboutTabSeen = false;
|
||||
channelPlaylistsView.seen = false;
|
||||
channelSearchView.seen = false;
|
||||
channelVideosView.seen = true;
|
||||
channelView.aboutTabSeen = false;
|
||||
channelPlaylistsView.seen = false;
|
||||
channelSearchView.seen = false;
|
||||
},
|
||||
playlistTab: () => {
|
||||
channelPlaylistsView.seen = true;
|
||||
channelVideosView.seen = false;
|
||||
channelView.aboutTabSeen = false;
|
||||
channelSearchView.seen = false;
|
||||
channelPlaylistsView.seen = true;
|
||||
channelVideosView.seen = false;
|
||||
channelView.aboutTabSeen = false;
|
||||
channelSearchView.seen = false;
|
||||
},
|
||||
aboutTab: () => {
|
||||
channelView.aboutTabSeen = true;
|
||||
channelVideosView.seen = false;
|
||||
channelPlaylistsView.seen = false;
|
||||
channelSearchView.seen = false;
|
||||
channelView.aboutTabSeen = true;
|
||||
channelVideosView.seen = false;
|
||||
channelPlaylistsView.seen = false;
|
||||
channelSearchView.seen = false;
|
||||
},
|
||||
subscription: (channelId) => {
|
||||
let channelData = {
|
||||
|
@ -599,48 +599,62 @@ let channelView = new Vue({
|
|||
toggleSubscription(channelData);
|
||||
},
|
||||
sort: () => {
|
||||
if (channelVideosView.seen) {
|
||||
channelVideosView.page = 1;
|
||||
channelVideosView.videoList = [];
|
||||
channelNextPage();
|
||||
}
|
||||
else {
|
||||
// Playlist View is active
|
||||
channelPlaylistsView.continuationString = '';
|
||||
channelPlaylistsView.videoList = [];
|
||||
channelPlaylistNextPage();
|
||||
}
|
||||
if (channelVideosView.seen) {
|
||||
channelVideosView.page = 1;
|
||||
channelVideosView.videoList = [];
|
||||
channelNextPage();
|
||||
} else {
|
||||
// Playlist View is active
|
||||
channelPlaylistsView.continuationString = '';
|
||||
channelPlaylistsView.videoList = [];
|
||||
channelPlaylistNextPage();
|
||||
}
|
||||
},
|
||||
search: () => {
|
||||
channelSearchView.page = 1;
|
||||
channelSearchView.videoList = [];
|
||||
channelView.aboutTabSeen = false;
|
||||
channelVideosView.seen = false;
|
||||
channelPlaylistsView.seen = false;
|
||||
channelSearchView.seen = true;
|
||||
searchChannel();
|
||||
channelSearchView.page = 1;
|
||||
channelSearchView.videoList = [];
|
||||
channelView.aboutTabSeen = false;
|
||||
channelVideosView.seen = false;
|
||||
channelPlaylistsView.seen = false;
|
||||
channelSearchView.seen = true;
|
||||
searchChannel();
|
||||
},
|
||||
goToChannel: (channelId) => {
|
||||
goToChannel(channelId);
|
||||
goToChannel(channelId);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
sortOptions: () => {
|
||||
if (channelVideosView.seen) {
|
||||
return [
|
||||
{value: 'newest', label: 'Newest'},
|
||||
{value: 'oldest', label: 'Oldest'},
|
||||
{value: 'popular', label: 'Most Popular'},
|
||||
];
|
||||
}
|
||||
else {
|
||||
return [
|
||||
{value: 'newest', label: 'Newest'},
|
||||
{value: 'oldest', label: 'Oldest'},
|
||||
{value: 'last', label: 'Last Video Added'},
|
||||
];
|
||||
}
|
||||
},
|
||||
sortOptions: () => {
|
||||
if (channelVideosView.seen) {
|
||||
return [{
|
||||
value: 'newest',
|
||||
label: 'Newest'
|
||||
},
|
||||
{
|
||||
value: 'oldest',
|
||||
label: 'Oldest'
|
||||
},
|
||||
{
|
||||
value: 'popular',
|
||||
label: 'Most Popular'
|
||||
},
|
||||
];
|
||||
} else {
|
||||
return [{
|
||||
value: 'newest',
|
||||
label: 'Newest'
|
||||
},
|
||||
{
|
||||
value: 'oldest',
|
||||
label: 'Oldest'
|
||||
},
|
||||
{
|
||||
value: 'last',
|
||||
label: 'Last Video Added'
|
||||
},
|
||||
];
|
||||
}
|
||||
},
|
||||
},
|
||||
template: channelTemplate
|
||||
});
|
||||
|
@ -962,12 +976,10 @@ let backButtonView = new Vue({
|
|||
|
||||
// reset this.lastView
|
||||
this.lastView = false;
|
||||
}
|
||||
else if (isSubManager) {
|
||||
subscriptionManagerView.seen = true;
|
||||
this.lastView = false;
|
||||
}
|
||||
else {
|
||||
} else if (isSubManager) {
|
||||
subscriptionManagerView.seen = true;
|
||||
this.lastView = false;
|
||||
} else {
|
||||
// if not search then this.lastView has to be playlistView
|
||||
|
||||
// Change back to playlistView
|
||||
|
@ -994,6 +1006,7 @@ let profileSelectView = new Vue({
|
|||
activeProfileInitial: '',
|
||||
activeProfileInitialColor: '#000000',
|
||||
profileList: [],
|
||||
profileLock: false,
|
||||
},
|
||||
methods: {
|
||||
showSubscriptionManager: function () {
|
||||
|
@ -1001,6 +1014,17 @@ let profileSelectView = new Vue({
|
|||
subscriptionManagerView.seen = true;
|
||||
},
|
||||
setActiveProfile: function (index) {
|
||||
if (profileSelectView.profileLock !== false) {
|
||||
console.log('Lock is active');
|
||||
window.setTimeout(() => {
|
||||
profileSelectView.setActiveProfile(index);
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
profileSelectView.profileLock = true;
|
||||
console.log('Set to true');
|
||||
|
||||
this.activeProfile = this.profileList[index];
|
||||
this.activeProfileInitial = this.profileInitials[index];
|
||||
this.activeProfileInitialColor = this.profileTextColor[index];
|
||||
|
@ -1102,37 +1126,35 @@ let subscriptionManagerView = new Vue({
|
|||
editProfileView.newProfileName = this.profileList[index].name;
|
||||
editProfileView.newProfileColorText = this.profileList[index].color;
|
||||
if (this.profileList[index].name === 'All Channels') {
|
||||
// Sort alphabetically
|
||||
subDb.find({
|
||||
}).sort({
|
||||
channelName: 1
|
||||
}).exec((err, subs) => {
|
||||
let list = [];
|
||||
subs.forEach((sub) => {
|
||||
sub.checked = false;
|
||||
list.push(sub);
|
||||
// Sort alphabetically
|
||||
subDb.find({}).sort({
|
||||
channelName: 1
|
||||
}).exec((err, subs) => {
|
||||
let list = [];
|
||||
subs.forEach((sub) => {
|
||||
sub.checked = false;
|
||||
list.push(sub);
|
||||
});
|
||||
editProfileView.subscriptionList = list;
|
||||
});
|
||||
editProfileView.subscriptionList = list;
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Sort alphabetically
|
||||
subDb.find({
|
||||
profile: {
|
||||
$elemMatch: {
|
||||
value: this.profileList[index].name
|
||||
} else {
|
||||
// Sort alphabetically
|
||||
subDb.find({
|
||||
profile: {
|
||||
$elemMatch: {
|
||||
value: this.profileList[index].name
|
||||
}
|
||||
}
|
||||
}
|
||||
}).sort({
|
||||
channelName: 1
|
||||
}).exec((err, subs) => {
|
||||
let list = [];
|
||||
subs.forEach((sub) => {
|
||||
sub.checked = false;
|
||||
list.push(sub);
|
||||
}).sort({
|
||||
channelName: 1
|
||||
}).exec((err, subs) => {
|
||||
let list = [];
|
||||
subs.forEach((sub) => {
|
||||
sub.checked = false;
|
||||
list.push(sub);
|
||||
});
|
||||
editProfileView.subscriptionList = list;
|
||||
});
|
||||
editProfileView.subscriptionList = list;
|
||||
});
|
||||
}
|
||||
}
|
||||
editProfileView.seen = true;
|
||||
|
@ -1200,8 +1222,8 @@ let editProfileView = new Vue({
|
|||
},
|
||||
defaultProfile: function () {
|
||||
if (editProfileView.profileName === settingsView.defaultProfile) {
|
||||
showToast('This profile is already set as your default.');
|
||||
return;
|
||||
showToast('This profile is already set as your default.');
|
||||
return;
|
||||
}
|
||||
|
||||
settingsDb.update({
|
||||
|
@ -1280,8 +1302,8 @@ let editProfileView = new Vue({
|
|||
},
|
||||
updateProfile: function (updateView = true) {
|
||||
if (this.newProfileName === '') {
|
||||
showToast('Profile name cannot be blank.');
|
||||
return;
|
||||
showToast('Profile name cannot be blank.');
|
||||
return;
|
||||
}
|
||||
|
||||
let patt = new RegExp("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
|
||||
|
@ -1578,8 +1600,8 @@ let editProfileView = new Vue({
|
|||
let amountDeleted = 0;
|
||||
|
||||
if (this.amountSelected === 0) {
|
||||
showToast('A channel must be selected before it can be deleted.');
|
||||
return;
|
||||
showToast('A channel must be selected before it can be deleted.');
|
||||
return;
|
||||
}
|
||||
|
||||
confirmFunction(confirmString, () => {
|
||||
|
@ -1589,16 +1611,16 @@ let editProfileView = new Vue({
|
|||
removeSubscription(channel.channelId, editProfileView.profileName, false);
|
||||
|
||||
|
||||
let subViewListMap = subscriptionView.fullVideoList.map(x => x.author === channel.channelName);
|
||||
let subViewListMap = subscriptionView.fullVideoList.map(x => x.author === channel.channelName);
|
||||
|
||||
for (let i = 0; i < subViewListMap.length; i++) {
|
||||
if (subViewListMap[i]) {
|
||||
let subProfileIndex = subscriptionView.fullVideoList[i].profile.findIndex(x => x.value === editProfileView.profileName);
|
||||
subscriptionView.fullVideoList[i].profile.splice(subProfileIndex, 1);
|
||||
}
|
||||
for (let i = 0; i < subViewListMap.length; i++) {
|
||||
if (subViewListMap[i]) {
|
||||
let subProfileIndex = subscriptionView.fullVideoList[i].profile.findIndex(x => x.value === editProfileView.profileName);
|
||||
subscriptionView.fullVideoList[i].profile.splice(subProfileIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
amountDeleted++;
|
||||
amountDeleted++;
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1608,7 +1630,7 @@ let editProfileView = new Vue({
|
|||
addSubsToView(subscriptionView.fullVideoList);
|
||||
showToast(amountDeleted + ' channel(s) have been deleted from this profile.');
|
||||
this.subscriptionList = this.subscriptionList.filter(a => {
|
||||
return !a.checked;
|
||||
return !a.checked;
|
||||
});
|
||||
}, 500);
|
||||
});
|
||||
|
@ -1616,12 +1638,11 @@ let editProfileView = new Vue({
|
|||
},
|
||||
computed: {
|
||||
newProfileColor: function () {
|
||||
if (this.newProfileColorText[0] === '#') {
|
||||
return this.newProfileColorText;
|
||||
}
|
||||
else {
|
||||
return '#' + this.newProfileColorText;
|
||||
}
|
||||
if (this.newProfileColorText[0] === '#') {
|
||||
return this.newProfileColorText;
|
||||
} else {
|
||||
return '#' + this.newProfileColorText;
|
||||
}
|
||||
},
|
||||
isDefaultProfile: function () {
|
||||
return settingsView.defaultProfile === this.profileName;
|
||||
|
|
|
@ -22,47 +22,47 @@
|
|||
*/
|
||||
|
||||
function checkForNewUpdate() {
|
||||
const requestUrl = 'https://api.github.com/repos/freetubeapp/freetube/releases';
|
||||
const requestUrl = 'https://api.github.com/repos/freetubeapp/freetube/releases';
|
||||
|
||||
let success = function(data) {
|
||||
let currentVersion = require('electron').remote.app.getVersion();
|
||||
let versionNumber = data[0].tag_name.replace('v', '');
|
||||
versionNumber = versionNumber.replace('-beta', '');
|
||||
let success = function (data) {
|
||||
let currentVersion = require('electron').remote.app.getVersion();
|
||||
let versionNumber = data[0].tag_name.replace('v', '');
|
||||
versionNumber = versionNumber.replace('-beta', '');
|
||||
|
||||
let blogRegexPattern = /\(.*\)/;
|
||||
let blogRegexPattern = /\(.*\)/;
|
||||
|
||||
let blogUrl = blogRegexPattern.exec(data[0].body);
|
||||
blogUrl = blogUrl[0].replace(/\(|\)/g, '');
|
||||
let blogUrl = blogRegexPattern.exec(data[0].body);
|
||||
blogUrl = blogUrl[0].replace(/\(|\)/g, '');
|
||||
|
||||
if (versionNumber > currentVersion) {
|
||||
confirmFunction(data[0].name + ` is now available! Would you like to download the update? <a href="${blogUrl}">Changelog</a>`, openReleasePage);
|
||||
if (versionNumber > currentVersion) {
|
||||
confirmFunction(data[0].name + ` is now available! Would you like to download the update? <a href="${blogUrl}">Changelog</a>`, openReleasePage);
|
||||
}
|
||||
};
|
||||
|
||||
if (useTor) {
|
||||
proxyRequest(() => {
|
||||
$.getJSON(
|
||||
requestUrl,
|
||||
success
|
||||
).fail((xhr, textStatus, error) => {
|
||||
fail(xhr);
|
||||
ft.log(xhr);
|
||||
ft.log(textStatus);
|
||||
ft.log(requestUrl);
|
||||
});
|
||||
})
|
||||
|
||||
} else {
|
||||
$.getJSON(
|
||||
requestUrl,
|
||||
success
|
||||
).fail((xhr, textStatus, error) => {
|
||||
fail(xhr);
|
||||
ft.log(xhr);
|
||||
ft.log(textStatus);
|
||||
ft.log(requestUrl);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (useTor) {
|
||||
proxyRequest(() => {
|
||||
$.getJSON(
|
||||
requestUrl,
|
||||
success
|
||||
).fail((xhr, textStatus, error) => {
|
||||
fail(xhr);
|
||||
ft.log(xhr);
|
||||
ft.log(textStatus);
|
||||
ft.log(requestUrl);
|
||||
});
|
||||
})
|
||||
|
||||
} else {
|
||||
$.getJSON(
|
||||
requestUrl,
|
||||
success
|
||||
).fail((xhr, textStatus, error) => {
|
||||
fail(xhr);
|
||||
ft.log(xhr);
|
||||
ft.log(textStatus);
|
||||
ft.log(requestUrl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const openReleasePage = function () {
|
||||
|
|
188
src/js/videos.js
188
src/js/videos.js
|
@ -21,7 +21,7 @@ let trendingTimer;
|
|||
let checkTrending = true;
|
||||
|
||||
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -66,20 +66,20 @@ function search(page = 1) {
|
|||
ft.log(data);
|
||||
|
||||
data.forEach((video) => {
|
||||
switch (video.type) {
|
||||
switch (video.type) {
|
||||
case 'video':
|
||||
displayVideo(video, 'search');
|
||||
break;
|
||||
displayVideo(video, 'search');
|
||||
break;
|
||||
case 'channel':
|
||||
displayChannel(video);
|
||||
break;
|
||||
displayChannel(video);
|
||||
break;
|
||||
case 'playlist':
|
||||
if (video.videoCount > 0) {
|
||||
displayPlaylist(video, 'search');
|
||||
}
|
||||
break;
|
||||
if (video.videoCount > 0) {
|
||||
displayPlaylist(video, 'search');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
searchView.page = searchView.page + 1;
|
||||
|
@ -88,9 +88,9 @@ function search(page = 1) {
|
|||
}
|
||||
|
||||
function getSearchSuggestion() {
|
||||
const query = document.getElementById('search').value;
|
||||
const query = document.getElementById('search').value;
|
||||
|
||||
invidiousAPI('search/suggestions', '', {
|
||||
invidiousAPI('search/suggestions', '', {
|
||||
q: query,
|
||||
}, function (data) {
|
||||
searchSuggestionsView.suggestionList = data.suggestions;
|
||||
|
@ -98,9 +98,9 @@ function getSearchSuggestion() {
|
|||
}
|
||||
|
||||
function hideSearchSuggestion() {
|
||||
if (!$('.searchSuggestions').is(':hover')) {
|
||||
searchSuggestionsView.seen = false;
|
||||
}
|
||||
if (typeof ($('.searchSuggestions').get(0)) !== 'undefined' && !$('.searchSuggestions').is(':hover')) {
|
||||
searchSuggestionsView.seen = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,14 +114,14 @@ function hideSearchSuggestion() {
|
|||
*/
|
||||
function displayVideo(videoData, listType = '') {
|
||||
if (videoData.paid) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
let video = {};
|
||||
video.id = videoData.videoId;
|
||||
|
||||
if (videoData.type == 'playlist') {
|
||||
video.isPlaylist = true;
|
||||
video.isPlaylist = true;
|
||||
}
|
||||
|
||||
historyDb.findOne({
|
||||
|
@ -137,54 +137,51 @@ function displayVideo(videoData, listType = '') {
|
|||
video.views = videoData.viewCount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
let time = videoData.lengthSeconds;
|
||||
|
||||
if (videoData.liveNow === true || time < 0){
|
||||
video.liveText = 'LIVE NOW';
|
||||
video.duration = '';
|
||||
video.publishedDate = '';
|
||||
video.viewText = 'watching';
|
||||
}
|
||||
else{
|
||||
let now = Date.now();
|
||||
video.liveText = '';
|
||||
if (videoData.liveNow === true || time < 0) {
|
||||
video.liveText = 'LIVE NOW';
|
||||
video.duration = '';
|
||||
video.publishedDate = '';
|
||||
video.viewText = 'watching';
|
||||
} else {
|
||||
let now = Date.now();
|
||||
video.liveText = '';
|
||||
|
||||
if (video.views <= 1) {
|
||||
video.viewText = 'view';
|
||||
}
|
||||
else{
|
||||
video.viewText = 'views';
|
||||
}
|
||||
|
||||
let published = new Date(videoData.published * 1000);
|
||||
let hours = 0;
|
||||
|
||||
if (now < published.getTime()) {
|
||||
video.publishedDate = 'Premieres on ' + published.toLocaleString();
|
||||
}
|
||||
else {
|
||||
if (time >= 3600) {
|
||||
hours = Math.floor(time / 3600);
|
||||
time = time - hours * 3600;
|
||||
}
|
||||
|
||||
let minutes = Math.floor(time / 60);
|
||||
let seconds = time - minutes * 60;
|
||||
|
||||
if (seconds < 10) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
|
||||
if (minutes < 10 && hours > 0) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
|
||||
if (hours > 0) {
|
||||
video.duration = hours + ":" + minutes + ":" + seconds;
|
||||
if (video.views <= 1) {
|
||||
video.viewText = 'view';
|
||||
} else {
|
||||
video.duration = minutes + ":" + seconds;
|
||||
video.viewText = 'views';
|
||||
}
|
||||
|
||||
video.publishedDate = videoData.publishedText;
|
||||
}
|
||||
let published = new Date(videoData.published * 1000);
|
||||
let hours = 0;
|
||||
|
||||
if (now < published.getTime()) {
|
||||
video.publishedDate = 'Premieres on ' + published.toLocaleString();
|
||||
} else {
|
||||
if (time >= 3600) {
|
||||
hours = Math.floor(time / 3600);
|
||||
time = time - hours * 3600;
|
||||
}
|
||||
|
||||
let minutes = Math.floor(time / 60);
|
||||
let seconds = time - minutes * 60;
|
||||
|
||||
if (seconds < 10) {
|
||||
seconds = '0' + seconds;
|
||||
}
|
||||
|
||||
if (minutes < 10 && hours > 0) {
|
||||
minutes = '0' + minutes;
|
||||
}
|
||||
|
||||
if (hours > 0) {
|
||||
video.duration = hours + ":" + minutes + ":" + seconds;
|
||||
} else {
|
||||
video.duration = minutes + ":" + seconds;
|
||||
}
|
||||
|
||||
video.publishedDate = videoData.publishedText;
|
||||
}
|
||||
}
|
||||
|
||||
// Include a remove icon in the list if the application is displaying the history list or saved videos.
|
||||
|
@ -199,11 +196,10 @@ function displayVideo(videoData, listType = '') {
|
|||
|
||||
video.youtubeUrl = 'https://youtube.com/watch?v=' + video.id;
|
||||
video.invidiousUrl = invidiousInstance + '/watch?v=' + video.id;
|
||||
if (typeof(videoData.videoThumbnails) === 'string'){
|
||||
video.thumbnail = videoData.videoThumbnails;
|
||||
}
|
||||
else {
|
||||
video.thumbnail = videoData.videoThumbnails[4].url;
|
||||
if (typeof (videoData.videoThumbnails) === 'string') {
|
||||
video.thumbnail = videoData.videoThumbnails;
|
||||
} else {
|
||||
video.thumbnail = videoData.videoThumbnails[4].url;
|
||||
}
|
||||
video.title = videoData.title;
|
||||
video.channelName = videoData.author;
|
||||
|
@ -268,7 +264,7 @@ function displayPlaylist(playlist, listType) {
|
|||
playListData.videoCount = playlist.videoCount;
|
||||
|
||||
if (playlist.videoCount === 0) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
playListData.isPlaylist = true;
|
||||
|
@ -281,25 +277,24 @@ function displayPlaylist(playlist, listType) {
|
|||
|
||||
|
||||
if (playlist.videoCount.length > 2) {
|
||||
playListData.description = playlist.videos[0].title + "\r\n" + playlist.videos[1].title;
|
||||
}
|
||||
else {
|
||||
playListData.description = playlist.videos[0].title;
|
||||
playListData.description = playlist.videos[0].title + "\r\n" + playlist.videos[1].title;
|
||||
} else {
|
||||
playListData.description = playlist.videos[0].title;
|
||||
}
|
||||
|
||||
if (playListData.channelName == 'YouTube' && playListData.title.includes('Mix')){
|
||||
// Hide Mix playlists.
|
||||
return;
|
||||
if (playListData.channelName == 'YouTube' && playListData.title.includes('Mix')) {
|
||||
// Hide Mix playlists.
|
||||
return;
|
||||
}
|
||||
|
||||
switch (listType) {
|
||||
case 'channelPlaylist':
|
||||
case 'channelPlaylist':
|
||||
channelPlaylistsView.videoList = channelPlaylistsView.videoList.concat(playListData);
|
||||
break;
|
||||
case 'channelSearch':
|
||||
case 'channelSearch':
|
||||
channelSearchView.videoList = channelSearchView.videoList.concat(playListData);
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
searchView.videoList = searchView.videoList.concat(playListData);
|
||||
}
|
||||
}
|
||||
|
@ -357,13 +352,13 @@ function parseSearchText(url = '') {
|
|||
* @return {Void}
|
||||
*/
|
||||
function showMostPopular() {
|
||||
if (checkPopular === false && popularView.videoList.length > 0) {
|
||||
ft.log('Will not load popular. Timer still on.');
|
||||
loadingView.seen = false;
|
||||
return;
|
||||
} else {
|
||||
checkPopular = false;
|
||||
}
|
||||
if (checkPopular === false && popularView.videoList.length > 0) {
|
||||
ft.log('Will not load popular. Timer still on.');
|
||||
loadingView.seen = false;
|
||||
return;
|
||||
} else {
|
||||
checkPopular = false;
|
||||
}
|
||||
|
||||
invidiousAPI('popular', '', {}, function (data) {
|
||||
ft.log(data);
|
||||
|
@ -395,7 +390,9 @@ function showTrending() {
|
|||
checkTrending = false;
|
||||
}
|
||||
|
||||
invidiousAPI('trending', '', {region: settingsView.region}, function (data) {
|
||||
invidiousAPI('trending', '', {
|
||||
region: settingsView.region
|
||||
}, function (data) {
|
||||
ft.log(data);
|
||||
popularView.videoList = [];
|
||||
|
||||
|
@ -495,9 +492,8 @@ function checkVideoUrls(video360p, video720p, videoAudio) {
|
|||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
else{
|
||||
playerView.validAudio = false;
|
||||
} else {
|
||||
playerView.validAudio = false;
|
||||
}
|
||||
|
||||
if (typeof (video360p) !== 'undefined') {
|
||||
|
@ -518,14 +514,13 @@ function checkVideoUrls(video360p, video720p, videoAudio) {
|
|||
default:
|
||||
ft.log('360p is valid');
|
||||
if (currentQuality === '720p' && typeof (video720p) === 'undefined') {
|
||||
playerView.currentQuality = '360p';
|
||||
playerView.currentQuality = '360p';
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
else{
|
||||
playerView.valid360p = false;
|
||||
} else {
|
||||
playerView.valid360p = false;
|
||||
}
|
||||
|
||||
if (typeof (video720p) !== 'undefined') {
|
||||
|
@ -536,7 +531,7 @@ function checkVideoUrls(video360p, video720p, videoAudio) {
|
|||
showToast('Found valid URL for 720p, but returned a 404. Video type might be available in the future.');
|
||||
playerView.valid720p = false;
|
||||
if (typeof (valid360) !== 'undefined') {
|
||||
playerView.currentQuality = '360p';
|
||||
playerView.currentQuality = '360p';
|
||||
}
|
||||
break;
|
||||
case 403:
|
||||
|
@ -549,8 +544,7 @@ function checkVideoUrls(video360p, video720p, videoAudio) {
|
|||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
else{
|
||||
playerView.valid720p = false;
|
||||
} else {
|
||||
playerView.valid720p = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,42 +25,41 @@
|
|||
* @return {Void}
|
||||
*/
|
||||
|
||||
function invidiousAPI(resource, id, params, success, fail = function(xhr){
|
||||
if (typeof(xhr.responseJSON.error) !== 'undefined') {
|
||||
showToast('Invidious API Error: ' + xhr.responseJSON.error);
|
||||
}
|
||||
else {
|
||||
showToast('There was an error calling the Invidious API');
|
||||
}
|
||||
loadingView.seen = false;
|
||||
function invidiousAPI(resource, id, params, success, fail = function (xhr) {
|
||||
if (typeof (xhr.responseJSON.error) !== 'undefined') {
|
||||
showToast('Invidious API Error: ' + xhr.responseJSON.error);
|
||||
} else {
|
||||
showToast('There was an error calling the Invidious API');
|
||||
}
|
||||
loadingView.seen = false;
|
||||
}) {
|
||||
let requestUrl = invidiousInstance + '/api/v1/' + resource + '/' + id + '?' + $.param(params);
|
||||
let requestUrl = invidiousInstance + '/api/v1/' + resource + '/' + id + '?' + $.param(params);
|
||||
|
||||
if (useTor) {
|
||||
if (useTor) {
|
||||
|
||||
proxyRequest(() => {
|
||||
$.getJSON(
|
||||
requestUrl,
|
||||
success
|
||||
).fail((xhr, textStatus, error) => {
|
||||
fail(xhr);
|
||||
ft.log(xhr);
|
||||
ft.log(textStatus);
|
||||
ft.log(requestUrl);
|
||||
});
|
||||
})
|
||||
proxyRequest(() => {
|
||||
$.getJSON(
|
||||
requestUrl,
|
||||
success
|
||||
).fail((xhr, textStatus, error) => {
|
||||
fail(xhr);
|
||||
ft.log(xhr);
|
||||
ft.log(textStatus);
|
||||
ft.log(requestUrl);
|
||||
});
|
||||
})
|
||||
|
||||
} else {
|
||||
$.getJSON(
|
||||
requestUrl,
|
||||
success
|
||||
).fail((xhr, textStatus, error) => {
|
||||
fail(xhr);
|
||||
ft.log(xhr);
|
||||
ft.log(textStatus);
|
||||
ft.log(requestUrl);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
$.getJSON(
|
||||
requestUrl,
|
||||
success
|
||||
).fail((xhr, textStatus, error) => {
|
||||
fail(xhr);
|
||||
ft.log(xhr);
|
||||
ft.log(textStatus);
|
||||
ft.log(requestUrl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,14 +75,14 @@ function youtubedlGetInfo(videoId, callback) {
|
|||
let url = 'https://youtube.com/watch?v=' + videoId;
|
||||
let options = ['--all-subs', '--write-subs'];
|
||||
|
||||
ytdl.getInfo(url, options, function(err, info) {
|
||||
if (err) {
|
||||
showToast(err.message);
|
||||
loadingView.seen = false;
|
||||
ft.log(err);
|
||||
ft.log(info);
|
||||
return;
|
||||
}
|
||||
ytdl.getInfo(url, options, function (err, info) {
|
||||
if (err) {
|
||||
showToast(err.message);
|
||||
loadingView.seen = false;
|
||||
ft.log(err);
|
||||
ft.log(info);
|
||||
return;
|
||||
}
|
||||
|
||||
ft.log('Success');
|
||||
callback(info);
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
*/
|
||||
|
||||
.channelDefaultBanner {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.channelViewBanner {
|
||||
|
@ -66,15 +66,15 @@
|
|||
}
|
||||
|
||||
.channelTabOption {
|
||||
display: inline-block;
|
||||
padding: 15px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin-bottom: -8px;
|
||||
-webkit-transition: background 0.2s ease-out;
|
||||
-moz-transition: background 0.2s ease-out;
|
||||
-o-transition: background 0.2s ease-out;
|
||||
transition: background 0.2s ease-out;
|
||||
display: inline-block;
|
||||
padding: 15px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin-bottom: -8px;
|
||||
-webkit-transition: background 0.2s ease-out;
|
||||
-moz-transition: background 0.2s ease-out;
|
||||
-o-transition: background 0.2s ease-out;
|
||||
transition: background 0.2s ease-out;
|
||||
}
|
||||
|
||||
.channelTabOption:hover {
|
||||
|
@ -84,20 +84,20 @@
|
|||
}
|
||||
|
||||
.channelVideosSortSelect {
|
||||
float: right;
|
||||
top: 10px;
|
||||
margin-right: 10px;
|
||||
float: right;
|
||||
top: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.channelSearch {
|
||||
float: left;
|
||||
margin-left: 15px;
|
||||
width: 300px;
|
||||
float: left;
|
||||
margin-left: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.channelSearch input {
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.channelViewDescription {
|
||||
|
@ -105,11 +105,11 @@
|
|||
}
|
||||
|
||||
.featuredChannel {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.featuredChannel img {
|
||||
border-radius: 200px 200px 200px 200px;
|
||||
-webkit-border-radius: 200px 200px 200px 200px;
|
||||
border-radius: 200px 200px 200px 200px;
|
||||
-webkit-border-radius: 200px 200px 200px 200px;
|
||||
}
|
||||
|
|
|
@ -44,24 +44,24 @@ input[type=text] {
|
|||
}
|
||||
|
||||
.select-text {
|
||||
border-bottom: 1px solid #E0E0E0;
|
||||
color: white;
|
||||
border-bottom: 1px solid #E0E0E0;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.select-text option {
|
||||
color: black;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.select-text:focus {
|
||||
border-bottom: 1px solid #EEEEEE;
|
||||
border-bottom: 1px solid #EEEEEE;
|
||||
}
|
||||
|
||||
.select:after {
|
||||
border-top: 6px solid #E0E0E0;
|
||||
border-top: 6px solid #E0E0E0;
|
||||
}
|
||||
|
||||
.select-label {
|
||||
color: #F5F5F5;
|
||||
color: #F5F5F5;
|
||||
}
|
||||
|
||||
.searchBar ::-webkit-input-placeholder {
|
||||
|
@ -69,12 +69,12 @@ input[type=text] {
|
|||
}
|
||||
|
||||
.searchSuggestions {
|
||||
background-color: #424242;
|
||||
color: white;
|
||||
background-color: #424242;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.searchSuggestions p:hover {
|
||||
background-color: #262626;
|
||||
background-color: #262626;
|
||||
}
|
||||
|
||||
.topNav {
|
||||
|
@ -99,7 +99,7 @@ input[type=text] {
|
|||
}
|
||||
|
||||
#searchFilter {
|
||||
background-color: #424242;
|
||||
background-color: #424242;
|
||||
}
|
||||
|
||||
.jumpToInput {
|
||||
|
@ -107,11 +107,11 @@ input[type=text] {
|
|||
}
|
||||
|
||||
.settingsSlider span {
|
||||
color: white;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: #424242;
|
||||
background-color: #424242;
|
||||
}
|
||||
|
||||
.message {
|
||||
|
@ -123,7 +123,7 @@ input[type=text] {
|
|||
}
|
||||
|
||||
.channelViewContainer {
|
||||
background-color: #424242;
|
||||
background-color: #424242;
|
||||
}
|
||||
|
||||
.channelViewImage {
|
||||
|
@ -284,7 +284,7 @@ input[type=text] {
|
|||
}
|
||||
|
||||
#backButton {
|
||||
color: white;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#channelIcon {
|
||||
|
@ -335,7 +335,7 @@ input[type=text] {
|
|||
}
|
||||
|
||||
#miniPL {
|
||||
background-color: #424242;
|
||||
background-color: #424242;
|
||||
}
|
||||
|
||||
#profileSelect {
|
||||
|
|
|
@ -40,19 +40,19 @@ body {
|
|||
}
|
||||
|
||||
.select-text {
|
||||
border-bottom: 1px solid rgba(0,0,0, 0.12);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.select-text:focus {
|
||||
border-bottom: 1px solid rgba(0,0,0, 0);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.select:after {
|
||||
border-top: 6px solid rgba(0, 0, 0, 0.12);
|
||||
border-top: 6px solid rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.select-label {
|
||||
color: rgba(0,0,0, 0.26);
|
||||
color: rgba(0, 0, 0, 0.26);
|
||||
}
|
||||
|
||||
.searchBar ::-webkit-input-placeholder {
|
||||
|
@ -60,11 +60,11 @@ body {
|
|||
}
|
||||
|
||||
.searchSuggestions {
|
||||
background-color: white;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.searchSuggestions p:hover {
|
||||
background-color: #e0e0e0;
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.topNav {
|
||||
|
@ -85,7 +85,7 @@ body {
|
|||
}
|
||||
|
||||
#searchFilter {
|
||||
background-color: white;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.jumpToInput {
|
||||
|
@ -93,7 +93,7 @@ body {
|
|||
}
|
||||
|
||||
.card {
|
||||
background-color: #ffffff;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.message {
|
||||
|
@ -105,7 +105,7 @@ body {
|
|||
}
|
||||
|
||||
.channelViewContainer {
|
||||
background-color: white;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.channelViewImage {
|
||||
|
@ -242,7 +242,7 @@ body {
|
|||
}
|
||||
|
||||
#backButton {
|
||||
color: #000000;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
#channelIcon {
|
||||
|
@ -271,7 +271,7 @@ body {
|
|||
}
|
||||
|
||||
#miniPL {
|
||||
background-color: white;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#profileSelect {
|
||||
|
|
|
@ -333,30 +333,30 @@ a {
|
|||
}
|
||||
|
||||
.searchSuggestions {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
overflow-y: scroll;
|
||||
margin-top: -5px;
|
||||
-webkit-box-shadow: -15px 25px 50px -30px rgba(0, 0, 0, 0.75);
|
||||
-moz-box-shadow: -15px 25px 50px -30px rgba(0, 0, 0, 0.75);
|
||||
box-shadow: -15px 25px 50px -30px rgba(0, 0, 0, 0.75);
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
overflow-y: scroll;
|
||||
margin-top: -5px;
|
||||
-webkit-box-shadow: -15px 25px 50px -30px rgba(0, 0, 0, 0.75);
|
||||
-moz-box-shadow: -15px 25px 50px -30px rgba(0, 0, 0, 0.75);
|
||||
box-shadow: -15px 25px 50px -30px rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.searchSuggestions p {
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
padding: 15px;
|
||||
margin: 0;
|
||||
-webkit-transition: background 0.2s ease-out;
|
||||
-moz-transition: background 0.2s ease-out;
|
||||
-o-transition: background 0.2s ease-out;
|
||||
transition: background 0.2s ease-out;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
padding: 15px;
|
||||
margin: 0;
|
||||
-webkit-transition: background 0.2s ease-out;
|
||||
-moz-transition: background 0.2s ease-out;
|
||||
-o-transition: background 0.2s ease-out;
|
||||
transition: background 0.2s ease-out;
|
||||
}
|
||||
|
||||
.searchSuggestions p:hover {
|
||||
-moz-transition: background 0.2s ease-in;
|
||||
-o-transition: background 0.2s ease-in;
|
||||
transition: background 0.2s ease-in;
|
||||
-moz-transition: background 0.2s ease-in;
|
||||
-o-transition: background 0.2s ease-in;
|
||||
transition: background 0.2s ease-in;
|
||||
}
|
||||
|
||||
#searchFilter {
|
||||
|
|
|
@ -3,7 +3,7 @@ This file is to fix some of the resizing issues introduced when full screening t
|
|||
*/
|
||||
|
||||
#player_native_dash {
|
||||
max-height: 80vh;
|
||||
max-height: 80vh;
|
||||
}
|
||||
|
||||
.mejs__container {
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
.playlistSideView {
|
||||
float: left;
|
||||
position: fixed;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
float: left;
|
||||
position: fixed;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.playlistSideView img {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.playlistVideo {
|
||||
height: 115px;
|
||||
overflow: hidden;
|
||||
height: 115px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.playlistVideoView {
|
||||
float: right;
|
||||
width: 58%;
|
||||
float: right;
|
||||
width: 58%;
|
||||
}
|
||||
|
||||
.playlistVideoThumbnail {
|
||||
width: 200px;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playlistVideoThumbnail img {
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playlistChannel {
|
||||
height: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.playlistChannel img {
|
||||
|
@ -43,41 +43,41 @@
|
|||
}
|
||||
|
||||
.playlistChannel h3 {
|
||||
float: left;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin-left: 10px;
|
||||
top: 5px;
|
||||
font-size: 15px;
|
||||
float: left;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin-left: 10px;
|
||||
top: 5px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.playlistVideoSave {
|
||||
background-color: black;
|
||||
color: white;
|
||||
opacity: 0.7;
|
||||
padding: 4px;
|
||||
position: relative;
|
||||
left: 176px;
|
||||
bottom: 117px;
|
||||
cursor: pointer;
|
||||
background-color: black;
|
||||
color: white;
|
||||
opacity: 0.7;
|
||||
padding: 4px;
|
||||
position: relative;
|
||||
left: 176px;
|
||||
bottom: 117px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playlistVideoTitle {
|
||||
position: relative;
|
||||
bottom: 160px;
|
||||
margin-left: 210px;
|
||||
font-weight: bold;
|
||||
width: 50%;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
bottom: 160px;
|
||||
margin-left: 210px;
|
||||
font-weight: bold;
|
||||
width: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playlistChannelName {
|
||||
position: relative;
|
||||
bottom: 160px;
|
||||
margin-left: 210px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
bottom: 160px;
|
||||
margin-left: 210px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playlistVideoOptions {
|
||||
|
@ -86,8 +86,8 @@
|
|||
}
|
||||
|
||||
.playlistVideoOptions i {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playlistVideoOptions ul {
|
||||
|
@ -125,76 +125,76 @@
|
|||
}
|
||||
|
||||
#miniPL {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.miniPLVideo {
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
height: 70px;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.miniPLThumbnail {
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
margin-right: 5px;
|
||||
float: left;
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
margin-right: 5px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.miniPLIndex {
|
||||
float: left;
|
||||
position: relative;
|
||||
width: 15px;
|
||||
top: 30px;
|
||||
margin-right: 35px;
|
||||
float: left;
|
||||
position: relative;
|
||||
width: 15px;
|
||||
top: 30px;
|
||||
margin-right: 35px;
|
||||
}
|
||||
|
||||
.miniPLVideoTitle {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.miniPLVideoChannelName {
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
bottom: 10px;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
#miniPLTitle {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
margin-left: 20px;
|
||||
padding-top: 25px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
margin-left: 20px;
|
||||
padding-top: 25px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#miniPLChannelName {
|
||||
font-size: 15px;
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#miniPLVideoList {
|
||||
padding: 10px;
|
||||
overflow: scroll;
|
||||
height: 375px;
|
||||
padding: 10px;
|
||||
overflow: scroll;
|
||||
height: 375px;
|
||||
}
|
||||
|
||||
#miniPLLoop {
|
||||
margin-left: 20px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin-left: 20px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#miniPLShuffle {
|
||||
margin-left: 20px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin-left: 20px;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#miniPLDropdown {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: 20px;
|
||||
right: 15px;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: 20px;
|
||||
right: 15px;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
.videoDivider {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inlineBlock {
|
||||
width: 285px;
|
||||
height: 285px;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
width: 285px;
|
||||
height: 285px;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.flexGrid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.video {
|
||||
|
@ -29,20 +29,20 @@
|
|||
}
|
||||
|
||||
.videoThumbnail img {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.videoThumbnail i {
|
||||
color: white;
|
||||
background-color: black;
|
||||
padding: 6px;
|
||||
opacity: 0.7;
|
||||
position: relative;
|
||||
color: white;
|
||||
background-color: black;
|
||||
padding: 6px;
|
||||
opacity: 0.7;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.videoSave {
|
||||
bottom: 159px;
|
||||
left: 247px;
|
||||
bottom: 159px;
|
||||
left: 247px;
|
||||
}
|
||||
|
||||
.channelThumbnail {
|
||||
|
@ -70,9 +70,9 @@
|
|||
}
|
||||
|
||||
.videoOptions i {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
margin-left: 118px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
margin-left: 118px;
|
||||
}
|
||||
|
||||
.videoOptions ul {
|
||||
|
@ -128,7 +128,7 @@
|
|||
}
|
||||
|
||||
.videoDescription {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.videoDuration {
|
||||
|
@ -144,56 +144,56 @@
|
|||
}
|
||||
|
||||
.videoWatched {
|
||||
width: 100%;
|
||||
height: 155px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
position: relative;
|
||||
bottom: 187px;
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
height: 155px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
position: relative;
|
||||
bottom: 187px;
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.watchedProgressBar {
|
||||
background-color: #f44336;
|
||||
height: 3px;
|
||||
position: relative;
|
||||
bottom: 190px;
|
||||
opacity: 0.8;
|
||||
background-color: #f44336;
|
||||
height: 3px;
|
||||
position: relative;
|
||||
bottom: 190px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.videoPlaylist {
|
||||
float: right;
|
||||
width: 45%;
|
||||
position: relative;
|
||||
bottom: 159px;
|
||||
height: 155px;
|
||||
background-color: black;
|
||||
opacity: 0.7;
|
||||
float: right;
|
||||
width: 45%;
|
||||
position: relative;
|
||||
bottom: 159px;
|
||||
height: 155px;
|
||||
background-color: black;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.videoPlaylistTotals {
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
left: 50px;
|
||||
top: 40px;
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
left: 50px;
|
||||
top: 40px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.videoPlaylistIcon {
|
||||
font-size: 25px;
|
||||
top: 70px;
|
||||
left: 10px;
|
||||
background-color: inherit;
|
||||
opacity: 1;
|
||||
bottom: 0px;
|
||||
font-size: 25px;
|
||||
top: 70px;
|
||||
left: 10px;
|
||||
background-color: inherit;
|
||||
opacity: 1;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
.viewPlaylist {
|
||||
position: relative;
|
||||
left: 10px;
|
||||
top: 60px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
left: 10px;
|
||||
top: 60px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.live {
|
||||
|
|
|
@ -24,20 +24,20 @@
|
|||
}
|
||||
|
||||
.videoThumbnail img {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.videoThumbnail i {
|
||||
color: white;
|
||||
background-color: black;
|
||||
padding: 6px;
|
||||
opacity: 0.7;
|
||||
position: relative;
|
||||
color: white;
|
||||
background-color: black;
|
||||
padding: 6px;
|
||||
opacity: 0.7;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.videoSave {
|
||||
bottom: 159px;
|
||||
left: 247px;
|
||||
bottom: 159px;
|
||||
left: 247px;
|
||||
}
|
||||
|
||||
.channelThumbnail {
|
||||
|
@ -61,8 +61,8 @@
|
|||
}
|
||||
|
||||
.videoOptions i {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.videoOptions ul {
|
||||
|
@ -141,56 +141,56 @@
|
|||
}
|
||||
|
||||
.videoWatched {
|
||||
width: 100%;
|
||||
height: 155px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
position: relative;
|
||||
bottom: 187px;
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
height: 155px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
position: relative;
|
||||
bottom: 187px;
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.watchedProgressBar {
|
||||
background-color: #f44336;
|
||||
height: 3px;
|
||||
position: relative;
|
||||
bottom: 190px;
|
||||
opacity: 0.8;
|
||||
background-color: #f44336;
|
||||
height: 3px;
|
||||
position: relative;
|
||||
bottom: 190px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.videoPlaylist {
|
||||
float: right;
|
||||
width: 45%;
|
||||
position: relative;
|
||||
bottom: 159px;
|
||||
height: 155px;
|
||||
background-color: black;
|
||||
opacity: 0.7;
|
||||
float: right;
|
||||
width: 45%;
|
||||
position: relative;
|
||||
bottom: 159px;
|
||||
height: 155px;
|
||||
background-color: black;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.videoPlaylistTotals {
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
left: 50px;
|
||||
top: 40px;
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
left: 50px;
|
||||
top: 40px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.videoPlaylistIcon {
|
||||
font-size: 25px;
|
||||
top: 70px;
|
||||
left: 10px;
|
||||
background-color: inherit;
|
||||
opacity: 1;
|
||||
bottom: 0px;
|
||||
font-size: 25px;
|
||||
top: 70px;
|
||||
left: 10px;
|
||||
background-color: inherit;
|
||||
opacity: 1;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
.viewPlaylist {
|
||||
position: relative;
|
||||
left: 10px;
|
||||
top: 60px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
left: 10px;
|
||||
top: 60px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.live {
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
<div v-if='seen' class='channelViewContainer'>
|
||||
<img class='channelViewBanner' :src='banner' />
|
||||
<br />
|
||||
<div class='channelViewTitle'>
|
||||
<img class='channelViewImage' :src='icon' />
|
||||
<span class='channelViewName'>{{name}}</span>
|
||||
<img class='channelViewBanner' :src='banner' />
|
||||
<br />
|
||||
<span class='channelViewSubs'>{{subCount}} Subscribers</span>
|
||||
<div id='subscribeButton' class='channelSubButton' v-on:click='subscription(id);'>
|
||||
{{subButtonText}}
|
||||
<div class='channelViewTitle'>
|
||||
<img class='channelViewImage' :src='icon' />
|
||||
<span class='channelViewName'>{{name}}</span>
|
||||
<br />
|
||||
<span class='channelViewSubs'>{{subCount}} Subscribers</span>
|
||||
<div id='subscribeButton' class='channelSubButton' v-on:click='subscription(id);'>
|
||||
{{subButtonText}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<div class="select channelVideosSortSelect" v-if='!aboutTabSeen'>
|
||||
<select id='channelVideosSortValue' class="select-text" v-on:change='sort' >
|
||||
<option v-for='option in sortOptions' :value='option.value'>{{option.label}}</option>
|
||||
</select>
|
||||
<span class="select-highlight"></span>
|
||||
<span class="select-bar"></span>
|
||||
<label class="select-label">Sort By</label>
|
||||
</div>
|
||||
<div class="input-text-settings channelSearch">
|
||||
<label for="channelSearchInput">Search Channel</label>
|
||||
<input type="text" id="channelSearchInput" onkeyup="channelSearchKeypress(event)" name="set-name" v-model="channelSearchValue" />
|
||||
<span class='searchButton' v-on:click='search'><i class="fas fa-arrow-right" style='position: relative; float: right; right: 5px; bottom: 30px; cursor: pointer' title='Search'></i></span>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div v-on:click='videoTab' class='channelTabOption'>
|
||||
VIDEOS
|
||||
</div>
|
||||
<div v-on:click='playlistTab' class='channelTabOption'>
|
||||
PLAYLISTS
|
||||
</div>
|
||||
<div v-on:click='aboutTab' class='channelTabOption'>
|
||||
ABOUT
|
||||
</div>
|
||||
<div v-if='aboutTabSeen'>
|
||||
<hr />
|
||||
<div class='channelViewDescription'>
|
||||
<span v-html='description'></span>
|
||||
<br />
|
||||
<br />
|
||||
<div class="select channelVideosSortSelect" v-if='!aboutTabSeen'>
|
||||
<select id='channelVideosSortValue' class="select-text" v-on:change='sort'>
|
||||
<option v-for='option in sortOptions' :value='option.value'>{{option.label}}</option>
|
||||
</select>
|
||||
<span class="select-highlight"></span>
|
||||
<span class="select-bar"></span>
|
||||
<label class="select-label">Sort By</label>
|
||||
</div>
|
||||
<div class="input-text-settings channelSearch">
|
||||
<label for="channelSearchInput">Search Channel</label>
|
||||
<input type="text" id="channelSearchInput" onkeyup="channelSearchKeypress(event)" name="set-name" v-model="channelSearchValue" />
|
||||
<span class='searchButton' v-on:click='search'><i class="fas fa-arrow-right" style='position: relative; float: right; right: 5px; bottom: 30px; cursor: pointer' title='Search'></i></span>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div v-on:click='videoTab' class='channelTabOption'>
|
||||
VIDEOS
|
||||
</div>
|
||||
<div v-on:click='playlistTab' class='channelTabOption'>
|
||||
PLAYLISTS
|
||||
</div>
|
||||
<div v-on:click='aboutTab' class='channelTabOption'>
|
||||
ABOUT
|
||||
</div>
|
||||
<div v-if='aboutTabSeen'>
|
||||
<hr />
|
||||
<div class='channelViewDescription'>
|
||||
<span v-html='description'></span>
|
||||
</div>
|
||||
<hr />
|
||||
<br />
|
||||
<div v-if='featuredChannels.length > 0' class='center'>
|
||||
<h2>Featured Channels</h2>
|
||||
<div class='profileEditPadding' v-for='channel in featuredChannels' v-on:click='goToChannel(channel.authorId)'>
|
||||
<img class='profileEdit' :src='channel.authorThumbnails[3].url' style='cursor: pointer;' />
|
||||
<div class='profileEditName'><span>{{channel.author}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<br />
|
||||
<div v-if='featuredChannels.length > 0' class='center'>
|
||||
<h2>Featured Channels</h2>
|
||||
<div class='profileEditPadding' v-for='channel in featuredChannels' v-on:click='goToChannel(channel.authorId)'>
|
||||
<img class='profileEdit' :src='channel.authorThumbnails[3].url' style='cursor: pointer;' />
|
||||
<div class='profileEditName'><span>{{channel.author}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
<div onclick='goToChannel("{{authorId}}")' style="float:left;margin-right: 1em; width:48px">
|
||||
<img class="userIcon" src="{{authorThumbnail}}" alt="" class="user-icon" />
|
||||
</div>
|
||||
<div class="comment-data">
|
||||
<p onclick='goToChannel("{{authorId}}")' style='cursor: pointer; margin-left: 65px; font-weight: bold;'>{{author}}</p>
|
||||
<p style="margin-bottom: 0; margin-left: 65px; word-break: break-word;">{{authorComment}}</p>
|
||||
<p style="font-size:80%; padding: 0; margin-left: 65px;">{{published}}</p>
|
||||
<div class="comment-data">
|
||||
<p onclick='goToChannel("{{authorId}}")' style='cursor: pointer; margin-left: 65px; font-weight: bold;'>{{author}}</p>
|
||||
<p style="margin-bottom: 0; margin-left: 65px; word-break: break-word;">{{authorComment}}</p>
|
||||
<p style="font-size:80%; padding: 0; margin-left: 65px;">{{published}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="line"></div>
|
||||
<br />
|
||||
<div class="line"></div>
|
||||
{{/comments}}
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
<div v-if='seen'>
|
||||
<div v-if='!isNewProfile' class='card'>
|
||||
<div v-if="subscriptionList.length === 0" >
|
||||
<h2>Subscription List for {{profileName}} Profile</h2>
|
||||
<h4>This profile is empty. Add subscriptions to this profile to manage them.</h4>
|
||||
</div>
|
||||
<div v-else >
|
||||
<h2>Subscription List for {{profileName}} Profile</h2>
|
||||
<h3>{{amountSelected}} Selected</h3>
|
||||
<br />
|
||||
<div class='profileEditPadding' v-on:click='channel.checked = !channel.checked' v-for='channel in subscriptionList'>
|
||||
<div class='profileEdit' :style="{ backgroundImage: 'url(' + channel.channelThumbnail + ')' }" style='cursor: pointer; background-size: contain;'>
|
||||
</div>
|
||||
<div v-if='channel.checked' class='profileEditSelected'><i class='fas fa-check'></i></div>
|
||||
<div class='profileEditName'><span>{{channel.channelName}}</span></div>
|
||||
<div v-if="subscriptionList.length === 0">
|
||||
<h2>Subscription List for {{profileName}} Profile</h2>
|
||||
<h4>This profile is empty. Add subscriptions to this profile to manage them.</h4>
|
||||
</div>
|
||||
<br /><br /><br />
|
||||
<div class='center'>
|
||||
<div v-on:click='selectAll' class='settingsButton'>
|
||||
SELECT ALL
|
||||
<div v-else>
|
||||
<h2>Subscription List for {{profileName}} Profile</h2>
|
||||
<h3>{{amountSelected}} Selected</h3>
|
||||
<br />
|
||||
<div class='profileEditPadding' v-on:click='channel.checked = !channel.checked' v-for='channel in subscriptionList'>
|
||||
<div class='profileEdit' :style="{ backgroundImage: 'url(' + channel.channelThumbnail + ')' }" style='cursor: pointer; background-size: contain;'>
|
||||
</div>
|
||||
<div v-if='channel.checked' class='profileEditSelected'><i class='fas fa-check'></i></div>
|
||||
<div class='profileEditName'><span>{{channel.channelName}}</span></div>
|
||||
</div>
|
||||
<div v-on:click='selectNone' class='settingsButton'>
|
||||
SELECT NONE
|
||||
<br /><br /><br />
|
||||
<div class='center'>
|
||||
<div v-on:click='selectAll' class='settingsButton'>
|
||||
SELECT ALL
|
||||
</div>
|
||||
<div v-on:click='selectNone' class='settingsButton'>
|
||||
SELECT NONE
|
||||
</div>
|
||||
<div v-if="profileName !== 'All Channels'" v-on:click='move' class='settingsButton'>
|
||||
MOVE SELECTED TO
|
||||
</div>
|
||||
<div v-on:click='copy' class='settingsButton'>
|
||||
COPY SELECTED TO
|
||||
</div>
|
||||
<div v-on:click='deleteChannel' style='color: #f44336' class='settingsButton'>
|
||||
DELETE SELECTED
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="profileName !== 'All Channels'" v-on:click='move' class='settingsButton'>
|
||||
MOVE SELECTED TO
|
||||
</div>
|
||||
<div v-on:click='copy' class='settingsButton'>
|
||||
COPY SELECTED TO
|
||||
</div>
|
||||
<div v-on:click='deleteChannel' style='color: #f44336' class='settingsButton'>
|
||||
DELETE SELECTED
|
||||
<br />
|
||||
<div class="select center">
|
||||
<select id="profileListSelect" class="select-text" v-model='selectedProfile' required>
|
||||
<option v-for='profile in profileList' :value='profile.name'>{{profile.name}}</option>
|
||||
</select>
|
||||
<span class="select-highlight"></span>
|
||||
<span class="select-bar"></span>
|
||||
<label class="select-label">Profile Select</label>
|
||||
</div>
|
||||
<h4 v-if="profileName === 'All Channels'">NOTE: Deleting a channel from the "All Channels" profile will also delete the channel from all other profiles.</h4>
|
||||
</div>
|
||||
<br />
|
||||
<div class="select center">
|
||||
<select id="profileListSelect" class="select-text" v-model='selectedProfile' required>
|
||||
<option v-for='profile in profileList' :value='profile.name'>{{profile.name}}</option>
|
||||
</select>
|
||||
<span class="select-highlight"></span>
|
||||
<span class="select-bar"></span>
|
||||
<label class="select-label">Profile Select</label>
|
||||
</div>
|
||||
<h4 v-if="profileName === 'All Channels'">NOTE: Deleting a channel from the "All Channels" profile will also delete the channel from all other profiles.</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class='card'>
|
||||
<h2 v-if='isNewProfile'>Add New Profile</h2>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div v-if="seen">
|
||||
<h2 style='margin-left: 15px;'>{{ title }}</h2>
|
||||
<hr />
|
||||
<h2 style='margin-left: 15px;'>{{ title }}</h2>
|
||||
<hr />
|
||||
</div>
|
||||
|
|
|
@ -19,13 +19,14 @@
|
|||
body {
|
||||
background-color: #424242;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
margin:0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#legacyPlayer {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
<link rel="stylesheet" href="../style/mediaelementplayer.css" />
|
||||
<link rel="stylesheet" href="../js/plugins/quality/quality.min.css" />
|
||||
|
@ -33,13 +34,14 @@ body {
|
|||
<link rel="stylesheet" href="../js/plugins/speed/speed.css" />
|
||||
<link rel="stylesheet" href="../js/plugins/context-menu/context-menu.css" />
|
||||
<link rel="stylesheet" href="../js/plugins/title/title.css" />
|
||||
<div id='miniPlayer'>
|
||||
<div id='miniPlayer'>
|
||||
<div v-if='playerSeen && !legacySeen' class='videoPlayer'>
|
||||
<video id='player' onmousemove="hideMouseTimeout()" onmouseleave="removeMouseTimeout()" :poster="videoThumbnail">
|
||||
<source v-if='validDash' data-quality='Auto' type="application/dash+xml" :src="videoDash" />
|
||||
<source v-if='validLive' data-quality='Live' type="application/x-mpegURL" :src="videoLive" />
|
||||
<span v-html="subtitleHtml"></span>
|
||||
<track kind="metadata" srclang='' class="time-rail-thumbnails" :src="'https://invidio.us/api/v1/storyboards/' + videoId + '?height=90'"></track>
|
||||
<track kind="metadata" srclang='' class="time-rail-thumbnails" :src="'https://invidio.us/api/v1/storyboards/' + videoId + '?height=90'">
|
||||
</track>
|
||||
</video>
|
||||
</div>
|
||||
<div v-else-if='!playerSeen && legacySeen'>
|
||||
|
@ -49,8 +51,11 @@ body {
|
|||
<div v-else>
|
||||
<span v-html="embededHtml"></span>
|
||||
</div>
|
||||
</div>
|
||||
<script>window.$ = window.jQuery = require('jquery');</script>
|
||||
</div>
|
||||
<script>
|
||||
window.$ = window.jQuery = require('jquery');
|
||||
|
||||
</script>
|
||||
<script src="../js/dash.all.min.js"></script>
|
||||
<script src="../js/mediaelement-and-player.js"></script>
|
||||
<script src="../js/plugins/quality/quality.js"></script>
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
<div v-if='seen'>
|
||||
<div v-if='playerSeen && !legacySeen' class='videoPlayer'>
|
||||
<video id='player' onloadstart='checkDashSettings()' onmousemove="hideMouseTimeout()" onmouseleave="removeMouseTimeout()" :poster="videoThumbnail" onended='playNext(5)' onvolumechange='updateVolume()' >
|
||||
<video id='player' onloadstart='checkDashSettings()' onmousemove="hideMouseTimeout()" onmouseleave="removeMouseTimeout()" :poster="videoThumbnail" onended='playNext(5)' onvolumechange='updateVolume()'>
|
||||
<source v-if='validDash' data-quality='Auto' type="application/dash+xml" :src="videoDash" />
|
||||
<source v-if='validLive' data-quality='Live' type="application/x-mpegURL" :src="videoLive" />
|
||||
<span v-html="subtitleHtml"></span>
|
||||
<track kind="metadata" srclang='' class="time-rail-thumbnails" :src="storyBoardUrl"></track>
|
||||
<track kind="metadata" srclang='' class="time-rail-thumbnails" :src="storyBoardUrl">
|
||||
</track>
|
||||
</video>
|
||||
|
||||
</div>
|
||||
<div v-else-if='!playerSeen && legacySeen'>
|
||||
<video id='legacyPlayer' class='videoPlayer' onloadstart='checkLegacySettings()' onmousemove="hideMouseTimeout()" onmouseleave="removeMouseTimeout()" :poster="videoThumbnail" onended='playNextVideo()' onvolumechange='updateVolume()' :src='videoUrl' controls="controls" v-html="subtitleHtml" >
|
||||
<video id='legacyPlayer' class='videoPlayer' onloadstart='checkLegacySettings()' onmousemove="hideMouseTimeout()" onmouseleave="removeMouseTimeout()" :poster="videoThumbnail" onended='playNextVideo()' onvolumechange='updateVolume()' :src='videoUrl' controls="controls" v-html="subtitleHtml">
|
||||
</video>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
|
|
@ -21,46 +21,46 @@
|
|||
<div class='playlistThumbnail'>
|
||||
<img :src='thumbnail' />
|
||||
</div>
|
||||
<h2>{{title}}</h2>
|
||||
<hr />
|
||||
<div v-on:click='channel(channelId)' class='playlistChannel'>
|
||||
<img :src='channelThumbnail' />
|
||||
<h3>{{channelName}}</h3>
|
||||
<h2>{{title}}</h2>
|
||||
<hr />
|
||||
<div v-on:click='channel(channelId)' class='playlistChannel'>
|
||||
<img :src='channelThumbnail' />
|
||||
<h3>{{channelName}}</h3>
|
||||
</div>
|
||||
<p>{{videoCount}} videos - {{viewCount}} views - Last updated on {{lastUpdated}}</p>
|
||||
<hr />
|
||||
<p v-html='description'></p>
|
||||
</div>
|
||||
<p>{{videoCount}} videos - {{viewCount}} views - Last updated on {{lastUpdated}}</p>
|
||||
<hr />
|
||||
<p v-html='description'></p>
|
||||
</div>
|
||||
<div class='playlistVideoView'>
|
||||
<div v-for="video in videoList">
|
||||
<div class='playlistVideoOptions'>
|
||||
<i class="fas fa-ellipsis-v" onclick='showVideoOptions(this)'></i>
|
||||
<ul>
|
||||
<a v-on:click='openYouTube(video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>
|
||||
<div class='playlistVideoView'>
|
||||
<div v-for="video in videoList">
|
||||
<div class='playlistVideoOptions'>
|
||||
<i class="fas fa-ellipsis-v" onclick='showVideoOptions(this)'></i>
|
||||
<ul>
|
||||
<a v-on:click='openYouTube(video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>
|
||||
<li>Open in YouTube</li>
|
||||
</a>
|
||||
<li v-on:click='copyYouTube(video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>Copy YouTube Link</li>
|
||||
<a v-on:click='openInvidious(video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>
|
||||
<li v-on:click='copyYouTube(video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>Copy YouTube Link</li>
|
||||
<a v-on:click='openInvidious(video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>
|
||||
<li>Open in Invidious</li>
|
||||
</a>
|
||||
<li v-on:click='copyInvidious(video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>Copy Invidious Link</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='playlistVideo'>
|
||||
<div class='playlistVideoThumbnail'>
|
||||
<img v-on:click='play(video.id)' :src='video.thumbnail' />
|
||||
<p v-on:click='play(video.id)' class='videoDuration'>{{video.duration}}</p>
|
||||
<i class="fas fa-history playlistVideoSave" v-on:click='toggleSave(video.id)'></i>
|
||||
<div v-if='video.watched' class='videoWatched'>
|
||||
WATCHED
|
||||
</div>
|
||||
<li v-on:click='copyInvidious(video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>Copy Invidious Link</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p v-on:click='play(video.id)' class='playlistVideoTitle'>{{video.title}}</p>
|
||||
<p v-on:click='channel(video.channelId)' class='playlistChannelName'>{{video.channelName}}</p>
|
||||
<p v-on:click='play(video.id)' class='live'>{{video.liveText}}</p>
|
||||
<div class='playlistVideo'>
|
||||
<div class='playlistVideoThumbnail'>
|
||||
<img v-on:click='play(video.id)' :src='video.thumbnail' />
|
||||
<p v-on:click='play(video.id)' class='videoDuration'>{{video.duration}}</p>
|
||||
<i class="fas fa-history playlistVideoSave" v-on:click='toggleSave(video.id)'></i>
|
||||
<div v-if='video.watched' class='videoWatched'>
|
||||
WATCHED
|
||||
</div>
|
||||
</div>
|
||||
<p v-on:click='play(video.id)' class='playlistVideoTitle'>{{video.title}}</p>
|
||||
<p v-on:click='channel(video.channelId)' class='playlistChannelName'>{{video.channelName}}</p>
|
||||
<p v-on:click='play(video.id)' class='live'>{{video.liveText}}</p>
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
<hr />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<div v-if='seen'>
|
||||
<span id='progressBar' :style='{ width: progressWidth + "%" }'></span>
|
||||
<span id='progressBar' :style='{ width: progressWidth + "%" }'></span>
|
||||
</div>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div v-if='seen'>
|
||||
<div v-if='suggestionList.length > 0' onfocus='searchSuggestionView.seen = true' class='searchSuggestions' >
|
||||
<p v-for='suggestion in suggestionList' v-on:click='newSearchTerm(suggestion)'>{{suggestion}}</p>
|
||||
</div>
|
||||
<div v-if='suggestionList.length > 0' onfocus='searchSuggestionView.seen = true' class='searchSuggestions'>
|
||||
<p v-for='suggestion in suggestionList' v-on:click='newSearchTerm(suggestion)'>{{suggestion}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
<div class='videoOptions'>
|
||||
<i class="fas fa-ellipsis-v" onclick='showVideoOptions(this)'></i>
|
||||
<ul>
|
||||
<div v-if='video.watched'>
|
||||
<li v-on:click='history(video.id)' onclick='showVideoOptions(this.parentNode.parentNode.previousSibling);'>Remove From History</li>
|
||||
</div>
|
||||
<div v-if='video.watched'>
|
||||
<li v-on:click='history(video.id)' onclick='showVideoOptions(this.parentNode.parentNode.previousSibling);'>Remove From History</li>
|
||||
</div>
|
||||
<a :href='video.youtubeUrl' onclick='showVideoOptions(this.parentNode.previousSibling);'>
|
||||
<li>Open in YouTube</li>
|
||||
</a>
|
||||
|
@ -59,17 +59,17 @@
|
|||
<div class='channelThumbnail'>
|
||||
<img v-on:click='channel(video.channelId)' :src='video.thumbnail' />
|
||||
</div>
|
||||
<p v-on:click='channel(video.channelId)' class='videoTitle'>{{video.channelName}}</p>
|
||||
<p v-on:click='channel(video.channelId)' class='channelName'>{{video.subscriberCount}} subscribers - {{video.videoCount}} videos</p>
|
||||
<p v-on:click='channel(video.channelId)' class='videoDescription'>{{video.channelDescription}}</p>
|
||||
<p v-on:click='channel(video.channelId)' class='videoTitle'>{{video.channelName}}</p>
|
||||
<p v-on:click='channel(video.channelId)' class='channelName'>{{video.subscriberCount}} subscribers - {{video.videoCount}} videos</p>
|
||||
<p v-on:click='channel(video.channelId)' class='videoDescription'>{{video.channelDescription}}</p>
|
||||
</div>
|
||||
<hr class='videoDivider' />
|
||||
</div>
|
||||
<hr class='videoDivider' />
|
||||
</div>
|
||||
</div>
|
||||
<div class='getNextPage' v-if='isSearch'>
|
||||
<div v-on:click='nextPage' id='getNextPage'>
|
||||
<i class="fas fa-search"></i> Fetch more results…
|
||||
<div class='getNextPage' v-if='isSearch'>
|
||||
<div v-on:click='nextPage' id='getNextPage'>
|
||||
<i class="fas fa-search"></i> Fetch more results…
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue