Add Search for channels, fix playlist view, fix quality select

This commit is contained in:
PrestonN 2019-08-06 14:53:00 -04:00
parent c436e37d5c
commit 8e82bbcefb
11 changed files with 333 additions and 41 deletions

View File

@ -151,6 +151,7 @@
<div id='mainHeaderView'></div>
<div id='channelVideosView'></div>
<div id='channelPlaylistsView'></div>
<div id='channelSearchView'></div>
<div id='searchView'></div>
<div id='subscriptionView'></div>
<div id='popularView'></div>

View File

@ -31,7 +31,8 @@
function goToChannel(channelId) {
channelView.channelId = channelId;
channelView.page = 2;
channelView.channelSearchValue = '';
channelVideosView.page = 2;
headerView.title = 'Latest Uploads';
hideViews();
@ -64,6 +65,8 @@ function goToChannel(channelId) {
channelVideosView.videoList = [];
channelView.featuredChannels = data.relatedChannels;
const views = [
aboutView,
headerView,
@ -116,14 +119,16 @@ function goToChannel(channelId) {
function channelNextPage() {
showToast('Fetching results, please wait…');
invidiousAPI('channels/videos', channelView.channelId, { 'page': channelView.page }, (data) => {
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');
});
});
channelView.page = channelView.page + 1;
channelVideosView.page = channelVideosView.page + 1;
}
function channelPlaylistNextPage() {
@ -134,15 +139,52 @@ function channelPlaylistNextPage() {
showToast('Fetching results, please wait…');
invidiousAPI('channels/playlists', channelView.channelId, { 'continuation': channelPlaylistsView.continuationString }, (data) => {
let sortValue = document.getElementById('channelVideosSortValue').value;
invidiousAPI('channels/playlists', channelView.channelId, {'sort_by': sortValue, 'continuation': channelPlaylistsView.continuationString }, (data) => {
console.log(data);
channelPlaylistsView.continuationString = data.continuation;
data.playlists.forEach((playlist) => {
displayPlaylist(playlist, 'channelPlaylist');
});
});
}
channelView.page = channelView.page + 1;
function channelSearchKeypress(e) {
if (e.keyCode === 13) {
channelView.search();
}
}
function searchChannel() {
if (channelView.channelSearchValue === '') {
return;
}
showToast('Fetching results, please wait…');
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');
}
break;
default:
}
});
channelSearchView.page = channelSearchView.page + 1;
});
}
/**

View File

@ -630,7 +630,7 @@ function openMiniPlayer() {
};
miniPlayer.webContents.send('ping', playerData);
var tmpSize = [0,0];
let tmpSize = [0,0];
miniPlayer.on('resize', (e)=>{
var size = miniPlayer.getSize()
@ -812,7 +812,16 @@ function clickMiniPlayer(videoId) {
miniPlayer.show();
miniPlayer.webContents.send('ping', videoData);
showToast('Video has been opened in a new window.');
// TODO: Add video to history once fully loaded.
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;
});
});
if (rememberHistory === true) {
@ -892,6 +901,11 @@ function clickMiniPlayer(videoId) {
videoData.videoId = videoId;
videoData.videoDash = invidiousInstance + '/api/manifest/dash/' + videoId + '.mpd?unique_res=1';
if (settingsView.proxyVideos) {
videoData.videoDash = videoData.videoDash + '&local=true';
}
videoData.autoplay = autoplay;
videoData.enableSubtitles = enableSubtitles;
videoData.quality = defaultQuality;
@ -1084,19 +1098,6 @@ function checkDashSettings() {
return;
}
historyDb.findOne({
videoId: playerView.videoId
}, function(err, doc) {
if (doc !== null) {
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;
}
}
});
let selectedOption = false;
qualityOptions.forEach((option, index) => {
if (option.value === defaultQuality || option.value === defaultQuality + 'p' || option.value === defaultQuality + 'p60') {
@ -1109,9 +1110,26 @@ function checkDashSettings() {
// Assume user selected a higher quality as their default. Select the highest option available.
ft.log('Quality not available.');
ft.log(qualityOptions.reverse()[0]);
console.log(selectedOption);
qualityOptions.reverse()[0].click();
$('.mejs__qualities-selector-input').get().reverse()[0].click();
}
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;
}
}
});
}, 200);
};
initializeSettings();

View File

@ -381,11 +381,19 @@ let playlistView = new Vue({
toggleSave: (videoId) => {
addSavedVideo(videoId);
},
openYouTube: (videoId) => {
const url = 'https://youtube.com/watch?v=' + videoId;
shell.openExternal(url);
},
copyYouTube: (videoId) => {
const url = 'https://youtube.com/watch?v=' + videoId;
clipboard.writeText(url);
showToast('URL has been copied to the clipboard');
},
openInvidious: (videoId) => {
const url = invidiousInstance + '/watch?v=' + videoId;
shell.openExternal(url);
},
copyInvidious: (videoId) => {
const url = invidiousInstance + '/watch?v=' + videoId;
clipboard.writeText(url);
@ -538,27 +546,32 @@ let channelView = new Vue({
id: '',
name: '',
icon: '',
baner: '',
banner: '',
subCount: '',
subButtonText: '',
description: '',
distractionFreeMode: false
channelSearchValue: '',
distractionFreeMode: false,
featuredChannels: [],
},
methods: {
videoTab: () => {
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;
},
aboutTab: () => {
channelView.aboutTabSeen = true;
channelVideosView.seen = false;
channelPlaylistsView.seen = false;
channelSearchView.seen = false;
},
subscription: (channelId) => {
let channelData = {
@ -568,6 +581,49 @@ 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();
}
},
search: () => {
channelSearchView.page = 1;
channelSearchView.videoList = [];
channelView.aboutTabSeen = false;
channelVideosView.seen = false;
channelPlaylistsView.seen = false;
channelSearchView.seen = true;
searchChannel();
},
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'},
];
}
},
},
template: channelTemplate
});
@ -576,7 +632,6 @@ let channelVideosView = new Vue({
el: '#channelVideosView',
data: {
seen: false,
channelId: '',
isSearch: true,
page: 2,
videoList: []
@ -619,7 +674,6 @@ let channelPlaylistsView = new Vue({
el: '#channelPlaylistsView',
data: {
seen: false,
channelId: '',
isSearch: true,
page: 2,
continuationString: '',
@ -642,6 +696,53 @@ let channelPlaylistsView = new Vue({
template: videoListTemplate
});
let channelSearchView = new Vue({
el: '#channelSearchView',
data: {
seen: false,
channelId: '',
isSearch: true,
page: 2,
videoList: []
},
methods: {
play: (videoId) => {
loadingView.seen = true;
playVideo(videoId);
},
channel: (channelId) => {
goToChannel(channelId);
},
playlist: (playlistId) => {
showPlaylist(playlistId);
},
toggleSave: (videoId) => {
addSavedVideo(videoId);
},
nextPage: () => {
showToast('Fetching results. Please wait…');
searchChannel();
},
copyYouTube: (videoId) => {
const url = 'https://youtube.com/watch?v=' + videoId;
clipboard.writeText(url);
showToast('URL has been copied to the clipboard');
},
copyInvidious: (videoId) => {
const url = invidiousInstance + '/watch?v=' + videoId;
clipboard.writeText(url);
showToast('URL has been copied to the clipboard');
},
history: (videoId) => {
removeFromHistory(videoId);
},
miniPlayer: (videoId) => {
clickMiniPlayer(videoId);
}
},
template: videoListTemplate
});
let playerView = new Vue({
el: '#playerView',
data: {
@ -1562,6 +1663,7 @@ function hideViews() {
channelView.seen = false;
channelVideosView.seen = false;
channelPlaylistsView.seen = false;
channelSearchView.seen = false;
profileSelectView.seen = false;
subscriptionManagerView.seen = false;
editProfileView.seen = false;

View File

@ -235,6 +235,10 @@ function displayVideo(videoData, listType = '') {
channelVideosView.videoList = channelVideosView.videoList.concat(video);
video.removeFromSave = false;
break;
case 'channelSearch':
channelSearchView.videoList = channelSearchView.videoList.concat(video);
video.removeFromSave = false;
break;
}
});
}
@ -286,6 +290,9 @@ function displayPlaylist(playlist, listType) {
case 'channelPlaylist':
channelPlaylistsView.videoList = channelPlaylistsView.videoList.concat(playListData);
break;
case 'channelSearch':
channelSearchView.videoList = channelSearchView.videoList.concat(playListData);
break;
default:
searchView.videoList = searchView.videoList.concat(playListData);
}

View File

@ -83,6 +83,33 @@
transition: background 0.2s ease-in;
}
.channelVideosSortSelect {
float: right;
top: 10px;
margin-right: 10px;
}
.channelSearch {
float: left;
margin-left: 15px;
width: 300px;
}
.channelSearch input {
width: 100%;
margin: auto;
}
.channelViewDescription {
white-space: pre-line;
}
.featuredChannel {
display: inline-block;
width: 120px;
}
.featuredChannel img {
border-radius: 200px 200px 200px 200px;
-webkit-border-radius: 200px 200px 200px 200px;
}

View File

@ -17,7 +17,7 @@
::-webkit-scrollbar {
height: 12px;
width: 12px;
width: 5px;
background: #262626;
}
@ -219,6 +219,19 @@ input[type=text] {
color: white;
}
.playlistVideoOptions ul {
background-color: #262626;
color: white;
}
.playlistVideoOptions li:hover {
background-color: #262626;
}
.playlistVideoOptions a {
color: white;
}
.profile:hover {
background-color: #616161;
}

View File

@ -17,7 +17,7 @@
::-webkit-scrollbar {
height: 12px;
width: 12px;
width: 5px;
background: white;
}
@ -188,6 +188,18 @@ body {
color: black;
}
.playlistVideoOptions ul {
background-color: #f5f5f5;
}
.playlistVideoOptions li:hover {
background-color: #e0e0e0;
}
.playlistVideoOptions a {
color: black;
}
.profile:hover {
background-color: #e0e0e0;
}

View File

@ -17,7 +17,7 @@
.playlistVideoView {
float: right;
width: 60%;
width: 58%;
}
.playlistVideoThumbnail {
@ -80,6 +80,50 @@
cursor: pointer;
}
.playlistVideoOptions {
float: right;
width: 37px;
}
.playlistVideoOptions i {
padding: 10px;
cursor: pointer;
}
.playlistVideoOptions ul {
width: 90px;
font-size: 12px;
position: relative;
right: 110px;
bottom: 10px;
list-style-type: none;
display: none;
-webkit-box-shadow: 4px 4px 33px -7px rgba(0, 0, 0, 0.75);
cursor: pointer;
z-index: 10;
}
.playlistVideoOptions li {
width: 110px;
position: relative;
right: 40px;
padding: 10px;
-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;
}
.playlistVideoOptions li:hover {
-moz-transition: background 0.2s ease-in;
-o-transition: background 0.2s ease-in;
transition: background 0.2s ease-in;
}
.playlistVideoOptions a {
text-decoration: none;
}
#miniPL {
width: 100%;
}

View File

@ -12,6 +12,24 @@
</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>
@ -26,7 +44,15 @@
<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 />
</div>

View File

@ -33,20 +33,20 @@
</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);'>
<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>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='videoOptions'>
<i class="fas fa-ellipsis-v" onclick='showVideoOptions(this)'></i>
<ul>
<a :href='video.youtubeUrl' onclick='showVideoOptions(this.parentNode.previousSibling);'>
<li>Open in YouTube</li>
</a>
<li v-on:click='copy("youtube.com", video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>Copy YouTube Link</li>
<a :href='video.invidiousUrl' onclick='showVideoOptions(this.parentNode.previousSibling);'>
<li>Open in Invidious</li>
</a>
<li v-on:click='copy("invidio.us", video.id)' onclick='showVideoOptions(this.parentNode.previousSibling);'>Copy Invidious Link</li>
</ul>
</div>
<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>