mirror of https://github.com/FreeTubeApp/FreeTube
[Fix] Usability Issues
Subscriptions don't refresh automatically nearly as often Added a new button to force subscriptions to refresh. Remove individual videos from history
This commit is contained in:
parent
cb32ae7db3
commit
15dde57ba0
|
@ -34,6 +34,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="topNav">
|
<div class="topNav">
|
||||||
<i onclick='toggleSideNavigation()' class="fas fa-bars" id='menuButton'></i>
|
<i onclick='toggleSideNavigation()' class="fas fa-bars" id='menuButton'></i>
|
||||||
|
<i onclick='forceSubscriptions()' class="fas fa-sync" id='reloadButton' title='Force Subscription Reload'></i>
|
||||||
<div class="searchBar">
|
<div class="searchBar">
|
||||||
<input id='search' class="search" type="text" placeholder="Search / Go to URL">
|
<input id='search' class="search" type="text" placeholder="Search / Go to URL">
|
||||||
<i onclick='parseSearchText()' class="fas fa-search searchButton" style='margin-right: -10px; cursor: pointer'></i>
|
<i onclick='parseSearchText()' class="fas fa-search searchButton" style='margin-right: -10px; cursor: pointer'></i>
|
||||||
|
|
|
@ -42,7 +42,11 @@ function addToHistory(videoId){
|
||||||
*/
|
*/
|
||||||
function removeFromHistory(videoId){
|
function removeFromHistory(videoId){
|
||||||
const data = {videoId: videoId};
|
const data = {videoId: videoId};
|
||||||
historyDb.remove(data, {}, (err, numRemoved) => {});
|
historyDb.remove(data, {}, (err, numRemoved) => {
|
||||||
|
if (!err) {
|
||||||
|
showToast('Video removed from history');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -318,12 +318,14 @@ function setTheme(option) {
|
||||||
document.getElementById('menuText').src = 'icons/textBlack.png';
|
document.getElementById('menuText').src = 'icons/textBlack.png';
|
||||||
document.getElementById('menuIcon').src = 'icons/iconBlack.png';
|
document.getElementById('menuIcon').src = 'icons/iconBlack.png';
|
||||||
document.getElementById('menuButton').style.color = 'black';
|
document.getElementById('menuButton').style.color = 'black';
|
||||||
|
document.getElementById('reloadButton').style.color = 'black';
|
||||||
break;
|
break;
|
||||||
case 'dark':
|
case 'dark':
|
||||||
cssFile = './style/darkTheme.css';
|
cssFile = './style/darkTheme.css';
|
||||||
document.getElementById('menuText').src = 'icons/textColor.png';
|
document.getElementById('menuText').src = 'icons/textColor.png';
|
||||||
document.getElementById('menuIcon').src = 'icons/iconColor.png';
|
document.getElementById('menuIcon').src = 'icons/iconColor.png';
|
||||||
document.getElementById('menuButton').style.color = 'white';
|
document.getElementById('menuButton').style.color = 'white';
|
||||||
|
document.getElementById('reloadButton').style.color = 'white';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Default to the light theme
|
// Default to the light theme
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let subscriptionTimer;
|
let subscriptionTimer;
|
||||||
|
let forceTimer;
|
||||||
let checkSubscriptions = true;
|
let checkSubscriptions = true;
|
||||||
|
let forceSubs = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a channel to the user's subscription database.
|
* Add a channel to the user's subscription database.
|
||||||
|
@ -108,15 +110,15 @@ function loadSubscriptions() {
|
||||||
progressView.progressWidth = (counter / results.length) * 100;
|
progressView.progressWidth = (counter / results.length) * 100;
|
||||||
|
|
||||||
if (counter === results.length) {
|
if (counter === results.length) {
|
||||||
addSubsToView(videoList);
|
addSubsToView(videoList);
|
||||||
|
}
|
||||||
|
}, (errorData) => {
|
||||||
|
showToast('Unable to load channel: ' + results[i]['channelName']);
|
||||||
|
counter = counter + 1;
|
||||||
|
progressView.progressWidth = (counter / results.length) * 100;
|
||||||
|
if (counter === results.length) {
|
||||||
|
addSubsToView(videoList);
|
||||||
}
|
}
|
||||||
},(errorData) => {
|
|
||||||
showToast('Unable to load channel: ' + results[i]['channelName']);
|
|
||||||
counter = counter + 1;
|
|
||||||
progressView.progressWidth = (counter / results.length) * 100;
|
|
||||||
if (counter === results.length) {
|
|
||||||
addSubsToView(videoList);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -128,33 +130,51 @@ function loadSubscriptions() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSubsToView (videoList) {
|
function addSubsToView(videoList) {
|
||||||
videoList.sort((a, b) => {
|
videoList.sort((a, b) => {
|
||||||
return b.published - a.published;
|
return b.published - a.published;
|
||||||
});
|
});
|
||||||
|
|
||||||
subscriptionView.videoList = [];
|
subscriptionView.videoList = [];
|
||||||
console.log(videoList);
|
console.log(videoList);
|
||||||
|
|
||||||
if (videoList.length > 100) {
|
if (videoList.length > 100) {
|
||||||
for (let i = 0; i < 100; i++) {
|
for (let i = 0; i < 100; i++) {
|
||||||
displayVideo(videoList[i], 'subscriptions');
|
displayVideo(videoList[i], 'subscriptions');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
videoList.forEach((video) => {
|
videoList.forEach((video) => {
|
||||||
displayVideo(video, 'subscriptions');
|
displayVideo(video, 'subscriptions');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingView.seen = false;
|
loadingView.seen = false;
|
||||||
progressView.seen = false;
|
progressView.seen = false;
|
||||||
progressView.progressWidth = 0;
|
progressView.progressWidth = 0;
|
||||||
|
|
||||||
subscriptionTimer = window.setTimeout(() => {
|
subscriptionTimer = window.setTimeout(() => {
|
||||||
checkSubscriptions = true;
|
checkSubscriptions = true;
|
||||||
}, 60000);
|
}, 7200000);
|
||||||
|
|
||||||
console.log('Done');
|
console.log('Done');
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceSubscriptions() {
|
||||||
|
if (progressView.progressWidth > 0) {
|
||||||
|
showToast('Please wait for subscriptions to finish loading before trying again.');
|
||||||
|
return;
|
||||||
|
} else if (forceSubs === false) {
|
||||||
|
showToast('Too many attempts. Please wait before loading subscriptions again.');
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
window.clearTimeout(subscriptionTimer);
|
||||||
|
checkSubscriptions = true;
|
||||||
|
loadSubscriptions();
|
||||||
|
forceSubs = false;
|
||||||
|
}
|
||||||
|
forceTimer = window.setTimeout(() => {
|
||||||
|
forceSubs = true;
|
||||||
|
}, 300000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -101,7 +101,7 @@ let sideNavBar = new Vue({
|
||||||
if (loadingView.seen !== false){
|
if (loadingView.seen !== false){
|
||||||
loadingView.seen = false;
|
loadingView.seen = false;
|
||||||
}
|
}
|
||||||
if(savedView.videoList.length === 0){
|
else{
|
||||||
loadingView.seen = true;
|
loadingView.seen = true;
|
||||||
}
|
}
|
||||||
headerView.seen = true;
|
headerView.seen = true;
|
||||||
|
@ -114,7 +114,7 @@ let sideNavBar = new Vue({
|
||||||
if (loadingView.seen !== false){
|
if (loadingView.seen !== false){
|
||||||
loadingView.seen = false;
|
loadingView.seen = false;
|
||||||
}
|
}
|
||||||
if(historyView.videoList.length === 0){
|
else{
|
||||||
loadingView.seen = true;
|
loadingView.seen = true;
|
||||||
}
|
}
|
||||||
headerView.seen = true;
|
headerView.seen = true;
|
||||||
|
@ -171,6 +171,9 @@ let subscriptionView = new Vue({
|
||||||
const url = 'https://' + site + '/watch?v=' + videoId;
|
const url = 'https://' + site + '/watch?v=' + videoId;
|
||||||
clipboard.writeText(url);
|
clipboard.writeText(url);
|
||||||
showToast('URL has been copied to the clipboard');
|
showToast('URL has been copied to the clipboard');
|
||||||
|
},
|
||||||
|
history: (videoId) => {
|
||||||
|
removeFromHistory(videoId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: videoListTemplate
|
template: videoListTemplate
|
||||||
|
@ -198,6 +201,9 @@ let popularView = new Vue({
|
||||||
const url = 'https://' + site + '/watch?v=' + videoId;
|
const url = 'https://' + site + '/watch?v=' + videoId;
|
||||||
clipboard.writeText(url);
|
clipboard.writeText(url);
|
||||||
showToast('URL has been copied to the clipboard');
|
showToast('URL has been copied to the clipboard');
|
||||||
|
},
|
||||||
|
history: (videoId) => {
|
||||||
|
removeFromHistory(videoId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: videoListTemplate
|
template: videoListTemplate
|
||||||
|
@ -225,6 +231,9 @@ let trendingView = new Vue({
|
||||||
const url = 'https://' + site + '/watch?v=' + videoId;
|
const url = 'https://' + site + '/watch?v=' + videoId;
|
||||||
clipboard.writeText(url);
|
clipboard.writeText(url);
|
||||||
showToast('URL has been copied to the clipboard');
|
showToast('URL has been copied to the clipboard');
|
||||||
|
},
|
||||||
|
history: (videoId) => {
|
||||||
|
removeFromHistory(videoId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: videoListTemplate
|
template: videoListTemplate
|
||||||
|
@ -252,6 +261,9 @@ let savedView = new Vue({
|
||||||
const url = 'https://' + site + '/watch?v=' + videoId;
|
const url = 'https://' + site + '/watch?v=' + videoId;
|
||||||
clipboard.writeText(url);
|
clipboard.writeText(url);
|
||||||
showToast('URL has been copied to the clipboard');
|
showToast('URL has been copied to the clipboard');
|
||||||
|
},
|
||||||
|
history: (videoId) => {
|
||||||
|
removeFromHistory(videoId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: videoListTemplate
|
template: videoListTemplate
|
||||||
|
@ -279,6 +291,9 @@ let historyView = new Vue({
|
||||||
const url = 'https://' + site + '/watch?v=' + videoId;
|
const url = 'https://' + site + '/watch?v=' + videoId;
|
||||||
clipboard.writeText(url);
|
clipboard.writeText(url);
|
||||||
showToast('URL has been copied to the clipboard');
|
showToast('URL has been copied to the clipboard');
|
||||||
|
},
|
||||||
|
history: (videoId) => {
|
||||||
|
removeFromHistory(videoId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: videoListTemplate
|
template: videoListTemplate
|
||||||
|
@ -314,6 +329,9 @@ let playlistView = new Vue({
|
||||||
const url = 'https://' + site + '/watch?v=' + videoId;
|
const url = 'https://' + site + '/watch?v=' + videoId;
|
||||||
clipboard.writeText(url);
|
clipboard.writeText(url);
|
||||||
showToast('URL has been copied to the clipboard');
|
showToast('URL has been copied to the clipboard');
|
||||||
|
},
|
||||||
|
history: (videoId) => {
|
||||||
|
removeFromHistory(videoId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: playlistViewTemplate
|
template: playlistViewTemplate
|
||||||
|
@ -426,6 +444,9 @@ let channelVideosView = new Vue({
|
||||||
clipboard.writeText(url);
|
clipboard.writeText(url);
|
||||||
showToast('URL has been copied to the clipboard');
|
showToast('URL has been copied to the clipboard');
|
||||||
},
|
},
|
||||||
|
history: (videoId) => {
|
||||||
|
removeFromHistory(videoId);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
template: videoListTemplate
|
template: videoListTemplate
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,6 +20,10 @@ let checkPopular = true;
|
||||||
let trendingTimer;
|
let trendingTimer;
|
||||||
let checkTrending = true;
|
let checkTrending = true;
|
||||||
|
|
||||||
|
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a search using the YouTube API. The search query is grabbed from the #search element.
|
* Perform a search using the YouTube API. The search query is grabbed from the #search element.
|
||||||
*
|
*
|
||||||
|
@ -105,14 +109,16 @@ function displayVideo(videoData, listType = '') {
|
||||||
}
|
}
|
||||||
|
|
||||||
video.views = videoData.viewCount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
video.views = videoData.viewCount.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
let time = videoData.lengthSeconds;
|
||||||
|
|
||||||
if (videoData.liveNow === true){
|
if (videoData.liveNow === true || time < 0){
|
||||||
video.liveText = (videoData.liveNow === true) ? 'LIVE NOW' : '';
|
video.liveText = 'LIVE NOW';
|
||||||
video.duration = '';
|
video.duration = '';
|
||||||
video.publishedDate = '';
|
video.publishedDate = '';
|
||||||
video.viewText = 'watching';
|
video.viewText = 'watching';
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
let now = Date.now();
|
||||||
video.liveText = '';
|
video.liveText = '';
|
||||||
|
|
||||||
if (video.views <= 1) {
|
if (video.views <= 1) {
|
||||||
|
@ -122,32 +128,37 @@ function displayVideo(videoData, listType = '') {
|
||||||
video.viewText = 'views';
|
video.viewText = 'views';
|
||||||
}
|
}
|
||||||
|
|
||||||
let time = videoData.lengthSeconds;
|
let published = new Date(videoData.published * 1000);
|
||||||
let hours = 0;
|
let hours = 0;
|
||||||
|
|
||||||
if (time >= 3600) {
|
if (now < published.getTime()) {
|
||||||
hours = Math.floor(time / 3600);
|
video.publishedDate = 'Premieres on ' + published.toLocaleString();
|
||||||
time = time - hours * 3600;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (time >= 3600) {
|
||||||
|
hours = Math.floor(time / 3600);
|
||||||
|
time = time - hours * 3600;
|
||||||
|
}
|
||||||
|
|
||||||
let minutes = Math.floor(time / 60);
|
let minutes = Math.floor(time / 60);
|
||||||
let seconds = time - minutes * 60;
|
let seconds = time - minutes * 60;
|
||||||
|
|
||||||
if (seconds < 10) {
|
if (seconds < 10) {
|
||||||
seconds = '0' + seconds;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//const searchMenu = $('#videoListContainer').html();
|
//const searchMenu = $('#videoListContainer').html();
|
||||||
|
|
|
@ -82,6 +82,15 @@ a {
|
||||||
top: 3px;
|
top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#reloadButton {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
#menuIcon {
|
#menuIcon {
|
||||||
width: 25px;
|
width: 25px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
CLEAR HISTORY
|
CLEAR HISTORY
|
||||||
</div>
|
</div>
|
||||||
<div onclick='confirmFunction("Are you sure you want to remove all saved videos?", clearFile, "saved")' class='settingsButton'>
|
<div onclick='confirmFunction("Are you sure you want to remove all saved videos?", clearFile, "saved")' class='settingsButton'>
|
||||||
CLEAR SAVED VIDEOS
|
CLEAR FAVORITED VIDEOS
|
||||||
</div>
|
</div>
|
||||||
<div onclick='confirmFunction("Are you sure you want to remove all subscriptions?", clearFile, "subscriptions")' class='settingsButton'>
|
<div onclick='confirmFunction("Are you sure you want to remove all subscriptions?", clearFile, "subscriptions")' class='settingsButton'>
|
||||||
CLEAR SUBSCRIPTIONS
|
CLEAR SUBSCRIPTIONS
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
<div class='videoOptions'>
|
<div class='videoOptions'>
|
||||||
<i class="fas fa-ellipsis-v" onclick='showVideoOptions(this)'></i>
|
<i class="fas fa-ellipsis-v" onclick='showVideoOptions(this)'></i>
|
||||||
<ul>
|
<ul>
|
||||||
|
<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);'>
|
<a :href='video.youtubeUrl' onclick='showVideoOptions(this.parentNode.previousSibling);'>
|
||||||
<li>Open in YouTube</li>
|
<li>Open in YouTube</li>
|
||||||
</a>
|
</a>
|
||||||
|
|
Loading…
Reference in New Issue