Fix issues from Vue.js Merge

This commit is contained in:
PrestonN 2018-08-02 22:18:08 -04:00
parent 787cfb18c7
commit 015fdfae57
11 changed files with 466 additions and 468 deletions

View File

@ -1,61 +1,79 @@
{
"name": "FreeTube",
"productName": "FreeTube",
"version": "0.3.2",
"description": "An Open Source YouTube app for privacy.",
"main": "src/js/init.js",
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
"make:all": "npm run make:mac && npm run make:linux:x86 && npm run make:linux:arm && npm run make:win",
"make:mac": "electron-forge make --platform=darwin",
"make:win": "electron-forge make --platform=win32",
"make:win:zip": "electron-forge make --platform=win32 --targets=zip",
"make:linux:x86": "electron-forge make --platform=linux --arch x64",
"make:linux:x86:zip": "electron-forge make --platform=linux --targets=zip --arch x64",
"make:linux:x86:deb": "electron-forge make --platform=linux --targets=deb --arch x64",
"make:linux:x86:rpm": "electron-forge make --platform=linux --targets=rpm --arch x64",
"make:linux:x86:snap": "electron-forge package && electron-installer-snap --src=out/FreeTube-linux-x64 --arch x64",
"make:linux:x86:flatpak": "electron-installer-flatpak --src out/FreeTube-linux-x64/ --dest out/make --arch x64",
"make:linux:x86:appimage": "electron-forge make --platform=linux --targets=electron-forge-maker-appimage --arch x64",
"make:linux:arm": "electron-forge make --platform=linux --arch arm64",
"make:linux:arm:zip": "electron-forge make --platform=linux --targets=zip --arch arm64",
"make:linux:arm:deb": "electron-forge make --platform=linux --targets=deb --arch arm64",
"make:linux:arm:rpm": "electron-forge make --platform=linux --targets=rpm --arch arm64",
"make:linux:arm:appimage": "electron-forge make --platform=linux --targets=electron-forge-maker-appimage --arch arm64"
},
"keywords": [],
"author": {
"name": "PrestonN",
"email": "FreeTubeApp@protonmail.com",
"url": "https://github.com/FreeTubeApp/FreeTube"
},
"license": "GPL-3.0-or-later",
"config": {
"forge": {
"make_targets": {
"win32": [
"squirrel"
],
"darwin": [
"zip"
],
"linux": [
"deb",
"rpm",
"electron-forge-maker-appimage",
"zip"
]
},
"protocols": [
{
"name": "freetube",
"role": "Viewer",
"schemes": [
"freetube"
]
"name": "FreeTube",
"productName": "FreeTube",
"version": "0.3.2",
"description": "An Open Source YouTube app for privacy.",
"main": "src/js/init.js",
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
"make:all": "npm run make:mac && npm run make:linux:x86 && npm run make:linux:arm && npm run make:win",
"make:mac": "electron-forge make --platform=darwin",
"make:win": "electron-forge make --platform=win32",
"make:win:zip": "electron-forge make --platform=win32 --targets=zip",
"make:linux:x86": "electron-forge make --platform=linux --arch x64",
"make:linux:x86:zip": "electron-forge make --platform=linux --targets=zip --arch x64",
"make:linux:x86:deb": "electron-forge make --platform=linux --targets=deb --arch x64",
"make:linux:x86:rpm": "electron-forge make --platform=linux --targets=rpm --arch x64",
"make:linux:x86:snap": "electron-forge package && electron-installer-snap --src=out/FreeTube-linux-x64 --arch x64",
"make:linux:x86:flatpak": "electron-installer-flatpak --src out/FreeTube-linux-x64/ --dest out/make --arch x64",
"make:linux:x86:appimage": "electron-forge make --platform=linux --targets=electron-forge-maker-appimage --arch x64",
"make:linux:arm": "electron-forge make --platform=linux --arch arm64",
"make:linux:arm:zip": "electron-forge make --platform=linux --targets=zip --arch arm64",
"make:linux:arm:deb": "electron-forge make --platform=linux --targets=deb --arch arm64",
"make:linux:arm:rpm": "electron-forge make --platform=linux --targets=rpm --arch arm64",
"make:linux:arm:appimage": "electron-forge make --platform=linux --targets=electron-forge-maker-appimage --arch arm64"
},
"keywords": [],
"author": {
"name": "PrestonN",
"email": "FreeTubeApp@protonmail.com",
"url": "https://github.com/FreeTubeApp/FreeTube"
},
"license": "GPL-3.0-or-later",
"config": {
"forge": {
"make_targets": {
"win32": [
"squirrel"
],
"darwin": [
"zip"
],
"linux": [
"deb",
"rpm",
"electron-forge-maker-appimage",
"zip"
]
},
"protocols": [
{
"name": "freetube",
"role": "Viewer",
"schemes": [
"freetube"
]
}
],
"electronPackagerConfig": {
"packageManager": "yarn",
"icon": "./src/icons/iconColor.icns"
},
"electronWinstallerConfig": {
"name": "freetube",
"iconUrl": "https://raw.githubusercontent.com/FreeTubeApp/FreeTubeApp.github.io/master/images/iconColor.ico",
"setupIcon": "./src/icons/iconColor.ico"
},
"electronInstallerDebian": {
"icon": "src/icons/iconColor.png"
},
"repository": {
"type": "git",
"url": "https://github.com/FreeTubeApp/FreeTube"
}
}
},
"devDependencies": {

View File

@ -20,10 +20,21 @@
<div class="double-bounce1"></div>
<div class="double-bounce2"></div>
</div>
<div id='confirmFunction'>
<span id='confirmMessage'>Would you like to perform the function?</span>
<div class='confirmButton' id='confirmYes'>Yes</div>
<div class='confirmButton' id='confirmNo'>No</div>
</div>
<div id='confirmFunction'>
<span id='confirmMessage'>Would you like to perform the function?</span>
<div class='confirmButton' id='confirmYes'>Yes</div>
<div class='confirmButton' id='confirmNo'>No</div>
</div>
<div id='toast'>
<span id='toastMessage'></span>
<i onclick='hideToast()' class="closeToast fas fa-times"></i>
</div>
<div class="topNav">
<i onclick='toggleSideNavigation()' class="fas fa-bars" id='menuButton'></i>
<div class="searchBar">
<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>
</div>
<img src='icons/iconBlack.png' id='menuIcon' /> &nbsp;
<img src='icons/textBlack.png' id='menuText' />
@ -70,6 +81,7 @@
</div>
<div id='progressView'></div>
</body>
<script src="js/general.js"></script>
<script src="js/youtubeApi.js"></script>
<script src="js/updates.js"></script>
<script src="js/db.js"></script>

View File

@ -62,7 +62,7 @@ function goToChannel(channelId) {
maxResults: 50,
order: 'date',
}, function (data) {
const channelData = data.items[0];
let grabDuration = getDuration(data.items);
grabDuration.then((videoList) => {
channelView.seen = true;
@ -72,8 +72,6 @@ function goToChannel(channelId) {
videoList.items.forEach((video) => {
displayVideo(video, 'channel');
});
$('#main').html(rendered);
stopLoadingAnimation();
// Grab the channel's latest uploads. API forces a max of 50.
youtubeAPI('search', {
@ -92,5 +90,7 @@ function goToChannel(channelId) {
});
});
});
});
});
}
});
}

View File

@ -1,53 +1,48 @@
/*
This file is part of FreeTube.
FreeTube is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FreeTube is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
This file is part of FreeTube.
FreeTube is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FreeTube is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
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(videoId) {
const data = {
videoId: videoId,
timeWatched: new Date().getTime(),
};
historyDb.insert(data, (err, newDoc) => {});
* Add a video to the history database file
*
* @param {string} videoId - The video ID of the video to be saved.
*
* @return {Void}
*/
function addToHistory(videoId){
const data = {
videoId: videoId,
timeWatched: new Date().getTime(),
};
historyDb.insert(data, (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) {
const data = {
videoId: videoId
};
historyDb.remove(data, {}, (err, numRemoved) => {});
* 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){
const data = {videoId: videoId};
historyDb.remove(data, {}, (err, numRemoved) => {});
}
/**
@ -60,21 +55,22 @@ function showHistory(){
//startLoadingAnimation();
console.log('checking history');
let videoList = '';
let videoList = '';
historyDb.find({}).sort({
timeWatched: -1
}).exec((err, docs) => {
if (docs.length > 49) {
// The YouTube API limits the search to 50 videos, so grab 50 most recent.
for (let i = 0; i < 49; i++) {
videoList = videoList + ',' + docs[i]['videoId'];
}
} else {
docs.forEach((video) => {
videoList = videoList + ',' + video['videoId'];
});
}
historyDb.find({}).sort({
timeWatched: -1
}).exec((err, docs) => {
if(docs.length > 49){
// The YouTube API limits the search to 50 videos, so grab 50 most recent.
for (let i = 0; i < 49; i++) {
videoList = videoList + ',' + docs[i]['videoId'];
}
}
else{
docs.forEach((video) => {
videoList = videoList + ',' + video['videoId'];
});
}
youtubeAPI('videos', {
part: 'snippet',
@ -91,4 +87,5 @@ function showHistory(){
});
});
});
}
});
}

View File

@ -17,19 +17,17 @@
import {
comment
} from "./comment.model";
import {comment} from "./comment.model";
/**
* Entire Comment Threads for a Video
*/
export class commentThread {
videoId;
nextPageToken;
pageInfo = {
totalResults,
resultsPerPage
videoId: ?string;
nextPageToken: ?string;
pageInfo: {
totalResults: number,
resultsPerPage: number
};
items;
}
items: comment[];
}

View File

@ -127,27 +127,25 @@ function playVideo(videoId) {
if (typeof(info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks) === 'object') {
const videoSubtitles = info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks;
if (subtitle.kind == 'asr') {
//subtitleUrl = subtitle.baseUrl;
return;
}
videoSubtitles.forEach((subtitle) => {
let subtitleUrl = 'https://www.youtube.com/api/timedtext?lang=' + subtitle.languageCode + '&fmt=vtt&name=&v=' + videoId;
videoHtml = videoHtml + '<track kind="subtitles" src="' + subtitleUrl + '" srclang="' + subtitle.languageCode + '" label="' + subtitle.name.simpleText + '">';
});
}
if (subtitle.kind == 'asr') {
//subtitleUrl = subtitle.baseUrl;
return;
}
//videoHtml = videoHtml + '</video>';
videoHtml = videoHtml + '<track kind="subtitles" src="' + subtitleUrl + '" srclang="' + subtitle.languageCode + '" label="' + subtitle.name.simpleText + '">';
});
}
}
playerView.subtitleHtml = videoHtml;
}
}
const checkSubscription = isSubscribed(playerView.channelId);
checkSubscription.then((results) => {
const subscribeButton = document.getElementById('subscribeButton');
checkSubscription.then((results) => {
if (results === false) {
if (subscribeButton != null) {
@ -181,10 +179,7 @@ function playVideo(videoId) {
});
}
window.setTimeout(checkVideoUrls, 5000, video480p, video720p);
window.setTimeout(checkVideoUrls, 5000, playerView.video480p, playerView.video720p);
});
}
@ -225,6 +220,7 @@ function openMiniPlayer() {
videoThumbnail: playerView.thumbnail,
startTime: lastTime,
});
});
}
/**
@ -340,4 +336,4 @@ function changeDurationBySeconds(seconds) {
function changeDurationByPercentage(percentage) {
const videoPlayer = $('.videoPlayer').get(0);
videoPlayer.currentTime = videoPlayer.duration * percentage;
}
}

View File

@ -152,4 +152,5 @@ function showSavedVideos(){
});
});
});
}
});
}

View File

@ -1,18 +1,15 @@
/*
This file is part of FreeTube.
FreeTube is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FreeTube is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
This file is part of FreeTube.
FreeTube is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FreeTube is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
*/
@ -81,19 +78,17 @@ function checkDefaultSettings() {
'useTor': false
};
ft.log('Default Settings: ', settingDefaults);
console.log(settingDefaults);
for (let key in settingDefaults) {
settingsDb.find({
_id: key
}, (err, docs) => {
if (jQuery.isEmptyObject(docs)) {
newSetting = {
_id: key,
value: settingDefaults[key]
};
for (let key in settingDefaults){
settingsDb.find({_id: key}, (err, docs) => {
if (jQuery.isEmptyObject(docs)) {
newSetting = {
_id: key,
value: settingDefaults[key]
};
settingsDb.insert(newSetting);
settingsDb.insert(newSetting);
if (key == 'theme'){
setTheme('light');
@ -129,20 +124,25 @@ function checkDefaultSettings() {
* @return {Void}
*/
function updateSettings() {
let themeSwitch = document.getElementById('themeSwitch').checked;
let torSwitch = document.getElementById('torSwitch').checked;
let key = document.getElementById('api-key').value;
let theme = 'light';
let themeSwitch = document.getElementById('themeSwitch').checked;
let torSwitch = document.getElementById('torSwitch').checked;
let key = document.getElementById('api-key').value;
let theme = 'light';
settingsView.apiKey = apiKeyBank[Math.floor(Math.random() * apiKeyBank.length)];
if (apiKeyBank.indexOf(key) == -1 && key !== '') {
settingsView.apiKey = key;
}
else{
settingsView.apiKey = apiKeyBank[Math.floor(Math.random() * apiKeyBank.length)];
}
ft.log('(Is the theme switch checked) themeSwitch: ', themeSwitch);
console.log(themeSwitch);
if (themeSwitch === true) {
theme = 'dark';
}
if (themeSwitch === true) {
theme = 'dark';
}
ft.log('Theme: ', theme);
console.log(theme);
// Update default theme
settingsDb.update({
@ -165,40 +165,14 @@ function updateSettings() {
useTor = torSwitch;
});
if (key !== '') {
settingsDb.update({
_id: 'theme'
}, {
value: theme
}, {}, function (err, numReplaced) {
ft.log('Error while updating theme: ', err);
ft.log('Number replaced: ', numReplaced);
});
// Update tor usage.
settingsDb.update({
_id: 'useTor'
}, {
value: settingsView.apiKey
}, {});
}
if (key != '') {
settingsDb.update({
_id: 'apiKey'
}, {
value: key
}, {});
} else {
// To any third party devs that fork the project, please be ethical and change the API key.
settingsDb.update({
_id: 'apiKey'
}, {
value: apiKey
}, {});
}
showToast('Settings have been saved.');
// To any third party devs that fork the project, please be ethical and change the API key.
settingsDb.update({
_id: 'apiKey'
}, {
value: settingsView.apiKey
}, {});
showToast('Settings have been saved.');
}
/**
@ -209,13 +183,13 @@ function updateSettings() {
* @return {Void}
*/
function toggleTheme(themeValue) {
if (themeValue.checked === true) {
setTheme('dark');
currentTheme = 'dark';
} else {
setTheme('light');
currentTheme = 'light';
}
if (themeValue.checked === true) {
setTheme('dark');
currentTheme = 'dark';
} else {
setTheme('light');
currentTheme = 'light';
}
}
/**
@ -226,86 +200,85 @@ function toggleTheme(themeValue) {
* @return {Void}
*/
function setTheme(option) {
let cssFile;
const currentTheme = document.getElementsByTagName("link").item(1);
let cssFile;
const currentTheme = document.getElementsByTagName("link").item(1);
// Create a link element
const newTheme = document.createElement("link");
newTheme.setAttribute("rel", "stylesheet");
newTheme.setAttribute("type", "text/css");
// Create a link element
const newTheme = document.createElement("link");
newTheme.setAttribute("rel", "stylesheet");
newTheme.setAttribute("type", "text/css");
// Grab the css file to be used.
switch (option) {
// Grab the css file to be used.
switch (option) {
case 'light':
cssFile = './style/lightTheme.css';
document.getElementById('menuText').src = 'icons/textBlack.png';
document.getElementById('menuIcon').src = 'icons/iconBlack.png';
document.getElementById('menuButton').style.color = 'black';
break;
cssFile = './style/lightTheme.css';
document.getElementById('menuText').src = 'icons/textBlack.png';
document.getElementById('menuIcon').src = 'icons/iconBlack.png';
document.getElementById('menuButton').style.color = 'black';
break;
case 'dark':
cssFile = './style/darkTheme.css';
document.getElementById('menuText').src = 'icons/textColor.png';
document.getElementById('menuIcon').src = 'icons/iconColor.png';
document.getElementById('menuButton').style.color = 'white';
break;
cssFile = './style/darkTheme.css';
document.getElementById('menuText').src = 'icons/textColor.png';
document.getElementById('menuIcon').src = 'icons/iconColor.png';
document.getElementById('menuButton').style.color = 'white';
break;
default:
// Default to the light theme
cssFile = './style/lightTheme.css';
break;
}
newTheme.setAttribute("href", cssFile);
// Default to the light theme
cssFile = './style/lightTheme.css';
break;
}
newTheme.setAttribute("href", cssFile);
// Replace the current theme with the new theme
document.getElementsByTagName("head").item(0).replaceChild(newTheme, currentTheme);
// Replace the current theme with the new theme
document.getElementsByTagName("head").item(0).replaceChild(newTheme, currentTheme);
}
/**
* Import Subscriptions from an OPML file.
*
* @param {string} subFile - The file location of the OPML file.
*
* @return {Void}
*/
function importOpmlSubs(json) {
if (!json[0]['folder'].includes('YouTube')) {
showToast('Invalid OPML File. Import is unsuccessful.');
return;
}
json.forEach((channel) => {
let channelId = channel['xmlurl'].replace('https://www.youtube.com/feeds/videos.xml?channel_id=', '');
addSubscription(channelId, false);
});
window.setTimeout(displaySubs, 1000);
showToast('Subscriptions have been imported!');
* Import Subscriptions from an OPML file.
*
* @param {string} subFile - The file location of the OPML file.
*
* @return {Void}
*/
function importOpmlSubs(json){
if(!json[0]['folder'].includes('YouTube')){
showToast('Invalid OPML File. Import is unsuccessful.');
return;
}
json.forEach((channel) => {
let channelId = channel['xmlurl'].replace('https://www.youtube.com/feeds/videos.xml?channel_id=', '');
addSubscription(channelId, false);
});
window.setTimeout(displaySubs, 1000);
showToast('Subscriptions have been imported!');
return;
}
/**
* Import a subscriptions file that the user provides.
*
* @return {Void}
*/
function importSubscriptions() {
const appDatabaseFile = localDataStorage + '/subscriptions.db';
* Import a subscriptions file that the user provides.
*
* @return {Void}
*/
function importSubscriptions(){
const appDatabaseFile = localDataStorage + '/subscriptions.db';
// Open user's file browser. Only show .db files.
dialog.showOpenDialog({
properties: ['openFile'],
filters: [{
name: 'Database File',
extensions: ['*']
}, ]
}, function (fileLocation) {
if (typeof (fileLocation) === 'undefined') {
ft.log('Import Aborted');
return;
}
ft.log('File Location: ', fileLocation);
let i = fileLocation[0].lastIndexOf('.');
let fileType = (i < 0) ? '' : fileLocation[0].substr(i);
ft.log('File Type: ', fileType);
// Open user's file browser. Only show .db files.
dialog.showOpenDialog({
properties: ['openFile'],
filters: [
{name: 'Database File', extensions: ['*']},
]
}, function(fileLocation){
if(typeof(fileLocation) === 'undefined'){
console.log('Import Aborted');
return;
}
console.log(fileLocation);
let i = fileLocation[0].lastIndexOf('.');
let fileType = (i < 0) ? '' : fileLocation[0].substr(i);
console.log(fileType);
fs.readFile(fileLocation[0], function(readErr, data){
if(readErr){
@ -313,30 +286,31 @@ function importSubscriptions() {
throw readErr;
}
if (data.includes("<opml")) {
getOpml(data, function (error, json) {
if (!error) {
clearFile('subscriptions', false);
importOpmlSubs(json['children'][0]['children']);
}
});
return;
} else if (fileType !== '.db') {
showToast('Incorrect file type. Import unsuccessful.');
return;
}
if (data.includes("<opml")){
getOpml(data, function (error, json){
if (!error){
clearFile('subscriptions', false);
importOpmlSubs(json['children'][0]['children']);
}
});
return;
}
else if (fileType !== '.db'){
showToast('Incorrect file type. Import unsuccessful.');
return;
}
fs.writeFile(appDatabaseFile, data, function (writeErr) {
if (writeErr) {
showToast('Unable to create file. Please check your permissions and try again.');
throw writeErr;
}
showToast('Susbcriptions have been successfully imported. Please restart FreeTube for the changes to take effect.');
});
})
});
clearFile('subscriptions', false);
fs.writeFile(appDatabaseFile, data, function(writeErr){
if(writeErr){
showToast('Unable to create file. Please check your permissions and try again.');
throw writeErr;
}
showToast('Susbcriptions have been successfully imported. Please restart FreeTube for the changes to take effect.');
});
})
});
}
/**
@ -345,79 +319,85 @@ function importSubscriptions() {
* @return {Void}
*/
function exportSubscriptions() {
const appDatabaseFile = localDataStorage + '/subscriptions.db';
const appDatabaseFile = localDataStorage + '/subscriptions.db';
const date = new Date();
let dateMonth = date.getMonth() + 1;
const date = new Date();
let dateMonth = date.getMonth() + 1;
if (dateMonth < 10) {
dateMonth = '0' + dateMonth;
if (dateMonth < 10){
dateMonth = '0' + dateMonth;
}
let dateDay = date.getDate();
if (dateDay < 10){
dateDay = '0' + dateDay;
}
const dateYear = date.getFullYear();
const dateString = 'freetube-subscriptions-' + dateYear + '-' + dateMonth + '-' + dateDay;
// Open user file browser. User gives location of file to be created.
dialog.showSaveDialog({
defaultPath: dateString,
filters: [{
name: 'Database File',
extensions: ['db']
}, ]
}, function(fileLocation) {
console.log(fileLocation);
if (typeof(fileLocation) === 'undefined') {
console.log('Export Aborted');
return;
}
let dateDay = date.getDate();
if (dateDay < 10) {
dateDay = '0' + dateDay;
}
const dateYear = date.getFullYear();
const dateString = 'freetube-subscriptions-' + dateYear + '-' + dateMonth + '-' + dateDay;
// Open user file browser. User gives location of file to be created.
dialog.showSaveDialog({
defaultPath: dateString,
filters: [{
name: 'Database File',
extensions: ['db']
}, ]
}, function (fileLocation) {
ft.log('File Location: ', fileLocation);
if (typeof (fileLocation) === 'undefined') {
ft.log('Export Aborted');
return;
fs.readFile(appDatabaseFile, function(readErr, data) {
if (readErr) {
throw readErr;
}
fs.writeFile(fileLocation, data, function(writeErr) {
if (writeErr) {
throw writeErr;
}
fs.readFile(appDatabaseFile, function (readErr, data) {
if (readErr) {
throw readErr;
}
fs.writeFile(fileLocation, data, function (writeErr) {
if (writeErr) {
throw writeErr;
}
showToast('Susbcriptions have been successfully exported');
});
})
});
showToast('Susbcriptions have been successfully exported');
});
})
});
}
/**
* Clear out the data in a file.
*
* @param {string} type - The type of file to be cleared.
*/
function clearFile(type, showMessage = true) {
ft.log('File Type: ', type);
let dataBaseFile;
* Clear out the data in a file.
*
* @param {string} type - The type of file to be cleared.
*/
function clearFile(type, showMessage = true){
console.log(type);
let dataBaseFile;
switch (type) {
switch (type) {
case 'subscriptions':
dataBaseFile = localDataStorage + '/subscriptions.db';
break;
dataBaseFile = localDataStorage + '/subscriptions.db';
break;
case 'history':
dataBaseFile = localDataStorage + '/videohistory.db';
break;
dataBaseFile = localDataStorage + '/videohistory.db';
break;
case 'saved':
dataBaseFile = localDataStorage + '/savedvideos.db';
break;
dataBaseFile = localDataStorage + '/savedvideos.db';
break;
default:
showToast('Unknown file: ' + type)
return
showToast('Unknown file: ' + type)
return
}
// Replace data with an empty string.
fs.writeFile(dataBaseFile, '', function(err) {
if (err) {
throw err;
}
// Replace data with an empty string.
fs.writeFile(dataBaseFile, '', function (err) {
if (err) {
throw err;
}
if (showMessage){
showToast('File has been cleared. Restart FreeTube to see the changes');
}
})
}
checkDefaultSettings();

View File

@ -80,113 +80,103 @@ function removeSubscription(channelId) {
*
* @return {Void}
*/
function loadSubscriptions() {
if (checkSubscriptions === false && subscriptionView.videoList.length > 0){
console.log('Will not load subscriptions. Timer still on.');
loadingView.seen = false;
return;
}
else{
showToast('Refreshing Subscription List. Please wait...');
checkSubscriptions = false;
}
function loadSubscriptions() {
if (checkSubscriptions === false && subscriptionView.videoList.length > 0){
console.log('Will not load subscriptions. Timer still on.');
loadingView.seen = false;
return;
}
else{
showToast('Refreshing Subscription List. Please wait...');
checkSubscriptions = false;
}
let videoList = [];
let videoList = [];
const subscriptions = returnSubscriptions();
const subscriptions = returnSubscriptions();
subscriptions.then((results) => {
let channelId = '';
let videoList = [];
subscriptions.then((results) => {
let channelId = '';
let videoList = [];
if (results.length > 0) {
let counter = 0;
for (let i = 0; i < results.length; i++) {
channelId = results[i]['channelId'];
if (results.length > 0) {
let counter = 0;
youtubeAPI('search', {
part: 'snippet',
channelId: channelId,
type: 'video',
maxResults: 15,
order: 'date',
}, (data) => {
for (let i = 0; i < results.length; i++) {
channelId = results[i]['channelId'];
youtubeAPI('search', {
part: 'snippet',
channelId: channelId,
type: 'video',
maxResults: 15,
order: 'date',
}, (data) => {
console.log(data);
videoList = videoList.concat(data.items);
counter++;
progressView.progressWidth = (counter / results.length) * 100;
if (counter === results.length) {
videoList.sort((a, b) => {
const date1 = Date.parse(a.snippet.publishedAt);
const date2 = Date.parse(b.snippet.publishedAt);
youtubeAPI('search', {
part: 'snippet',
channelId: channelId,
type: 'video',
maxResults: 15,
order: 'date',
}, (data) => {
console.log(data);
videoList = videoList.concat(data.items);
counter++;
progressView.progressWidth = (counter / results.length) * 100;
if (counter === results.length) {
videoList.sort((a, b) => {
const date1 = Date.parse(a.snippet.publishedAt);
const date2 = Date.parse(b.snippet.publishedAt);
return date2.valueOf() - date1.valueOf();
});
return date2.valueOf() - date1.valueOf();
});
// The YouTube website limits the subscriptions to 100 before grabbing more so we only show 100
// to keep the app running at a good speed.
if (videoList.length < 50) {
let grabDuration = getDuration(videoList.slice(0, 49));
// The YouTube website limits the subscriptions to 100 before grabbing more so we only show 100
// to keep the app running at a good speed.
if (videoList.length < 50) {
let grabDuration = getDuration(videoList.slice(0, 49));
grabDuration.then((list) => {
subscriptionView.videoList = [];
list.items.forEach((video) => {
displayVideo(video, 'subscriptions');
});
loadingView.seen = false;
progressView.seen = false;
progressView.progressWidth = 0;
});
} else {
console.log(videoList);
let finishedList = [];
let firstBatchDuration = getDuration(videoList.slice(0, 49));
grabDuration.then((list) => {
subscriptionView.videoList = [];
list.items.forEach((video) => {
displayVideo(video, 'subscriptions');
});
loadingView.seen = false;
progressView.seen = false;
progressView.progressWidth = 0;
});
} else {
console.log(videoList);
let finishedList = [];
let firstBatchDuration = getDuration(videoList.slice(0, 49));
grabDuration.then((list) => {
list.items.forEach((video) => {
displayVideo(video);
});
stopLoadingAnimation();
});
} else {
firstBatchDuration.then((list1) => {
finishedList = finishedList.concat(list1.items);
let secondBatchDuration = getDuration(videoList.slice(50, 99));
secondBatchDuration.then((list2) => {
finishedList = finishedList.concat(list2.items);
console.log(finishedList);
subscriptionView.videoList = [];
finishedList.forEach((video) => {
displayVideo(video, 'subscriptions');
});
loadingView.seen = false;
progressView.seen = false;
progressView.progressWidth = 0;
subscriptionTimer = window.setTimeout(() => {
checkSubscriptions = true;
}, 60000);
});
});
}
}
}
secondBatchDuration.then((list2) => {
finishedList = finishedList.concat(list2.items);
console.log(finishedList);
subscriptionView.videoList = [];
finishedList.forEach((video) => {
displayVideo(video, 'subscriptions');
});
loadingView.seen = false;
progressView.seen = false;
progressView.progressWidth = 0;
subscriptionTimer = window.setTimeout(() => {
checkSubscriptions = true;
}, 60000);
});
});
}
}
}
);
}
} else {
// User has no subscriptions. Display message.
loadingView.seen = false;
headerView.seen = false;
noSubscriptions.seen = true;
}
});
}
} else {
// User has no subscriptions. Display message.
loadingView.seen = false;
headerView.seen = false;
noSubscriptions.seen = true;
}
});
}
/**
* Get the list of subscriptions from the user's subscription database.
@ -281,4 +271,4 @@ function isSubscribed(channelId) {
}
});
});
}
}

View File

@ -180,6 +180,11 @@ let popularView = new Vue({
},
toggleSave: (videoId) => {
addSavedVideo(videoId);
},
copy: (site, videoId) => {
const url = 'https://' + site + '/watch?v=' + videoId;
clipboard.writeText(url);
showToast('URL has been copied to the clipboard');
}
},
template: videoListTemplate

View File

@ -220,7 +220,6 @@ function displayChannels(channels) {
}, function (data) {
ft.log('Channel Data: ', data);
let items = data['items'].reverse();
const videoListTemplate = require('./templates/channelList.html');
ft.log('Channel Items: ', items);
@ -240,6 +239,7 @@ function displayChannels(channels) {
searchView.videoList = searchView.videoList.concat(channelData);
});
});
}
function displayPlaylists(playlists) {
@ -343,6 +343,7 @@ function showVideoRecommendations(videoId) {
playerView.recommendedVideoList = playerView.recommendedVideoList.concat(data);
});
});
});
}
/**
@ -404,7 +405,7 @@ function parseSearchText(url = '') {
* @return {string} - The formated string. Ex: 12:34:56
*/
function parseVideoDuration(durationString) {
let match = durationString.match(/PT(\d+H)?(\d+M)?(\d+S)?/);
let match = durationString.match(/P.*T(\d+H)?(\d+M)?(\d+S)?/);
let duration = '';
match = match.slice(1).map(function (x) {
@ -602,4 +603,4 @@ function checkVideoUrls(video480p, video720p) {
}
});
}
}
}