mirror of https://github.com/FreeTubeApp/FreeTube
Fix issues from Vue.js Merge
This commit is contained in:
parent
860d384fbd
commit
6ccb6de22e
132
package.json
132
package.json
|
@ -1,61 +1,79 @@
|
||||||
{
|
{
|
||||||
"name": "FreeTube",
|
"name": "FreeTube",
|
||||||
"productName": "FreeTube",
|
"productName": "FreeTube",
|
||||||
"version": "0.3.2",
|
"version": "0.3.2",
|
||||||
"description": "An Open Source YouTube app for privacy.",
|
"description": "An Open Source YouTube app for privacy.",
|
||||||
"main": "src/js/init.js",
|
"main": "src/js/init.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron-forge start",
|
"start": "electron-forge start",
|
||||||
"package": "electron-forge package",
|
"package": "electron-forge package",
|
||||||
"make": "electron-forge make",
|
"make": "electron-forge make",
|
||||||
"publish": "electron-forge publish",
|
"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: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:mac": "electron-forge make --platform=darwin",
|
||||||
"make:win": "electron-forge make --platform=win32",
|
"make:win": "electron-forge make --platform=win32",
|
||||||
"make:win:zip": "electron-forge make --platform=win32 --targets=zip",
|
"make:win:zip": "electron-forge make --platform=win32 --targets=zip",
|
||||||
"make:linux:x86": "electron-forge make --platform=linux --arch x64",
|
"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: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: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: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: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: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: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": "electron-forge make --platform=linux --arch arm64",
|
||||||
"make:linux:arm:zip": "electron-forge make --platform=linux --targets=zip --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: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: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"
|
"make:linux:arm:appimage": "electron-forge make --platform=linux --targets=electron-forge-maker-appimage --arch arm64"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": {
|
"author": {
|
||||||
"name": "PrestonN",
|
"name": "PrestonN",
|
||||||
"email": "FreeTubeApp@protonmail.com",
|
"email": "FreeTubeApp@protonmail.com",
|
||||||
"url": "https://github.com/FreeTubeApp/FreeTube"
|
"url": "https://github.com/FreeTubeApp/FreeTube"
|
||||||
},
|
},
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"config": {
|
"config": {
|
||||||
"forge": {
|
"forge": {
|
||||||
"make_targets": {
|
"make_targets": {
|
||||||
"win32": [
|
"win32": [
|
||||||
"squirrel"
|
"squirrel"
|
||||||
],
|
],
|
||||||
"darwin": [
|
"darwin": [
|
||||||
"zip"
|
"zip"
|
||||||
],
|
],
|
||||||
"linux": [
|
"linux": [
|
||||||
"deb",
|
"deb",
|
||||||
"rpm",
|
"rpm",
|
||||||
"electron-forge-maker-appimage",
|
"electron-forge-maker-appimage",
|
||||||
"zip"
|
"zip"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"protocols": [
|
"protocols": [
|
||||||
{
|
{
|
||||||
"name": "freetube",
|
"name": "freetube",
|
||||||
"role": "Viewer",
|
"role": "Viewer",
|
||||||
"schemes": [
|
"schemes": [
|
||||||
"freetube"
|
"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": {
|
"devDependencies": {
|
||||||
|
|
|
@ -20,10 +20,21 @@
|
||||||
<div class="double-bounce1"></div>
|
<div class="double-bounce1"></div>
|
||||||
<div class="double-bounce2"></div>
|
<div class="double-bounce2"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id='confirmFunction'>
|
</div>
|
||||||
<span id='confirmMessage'>Would you like to perform the function?</span>
|
<div id='confirmFunction'>
|
||||||
<div class='confirmButton' id='confirmYes'>Yes</div>
|
<span id='confirmMessage'>Would you like to perform the function?</span>
|
||||||
<div class='confirmButton' id='confirmNo'>No</div>
|
<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>
|
</div>
|
||||||
<img src='icons/iconBlack.png' id='menuIcon' />
|
<img src='icons/iconBlack.png' id='menuIcon' />
|
||||||
<img src='icons/textBlack.png' id='menuText' />
|
<img src='icons/textBlack.png' id='menuText' />
|
||||||
|
@ -70,6 +81,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id='progressView'></div>
|
<div id='progressView'></div>
|
||||||
</body>
|
</body>
|
||||||
|
<script src="js/general.js"></script>
|
||||||
<script src="js/youtubeApi.js"></script>
|
<script src="js/youtubeApi.js"></script>
|
||||||
<script src="js/updates.js"></script>
|
<script src="js/updates.js"></script>
|
||||||
<script src="js/db.js"></script>
|
<script src="js/db.js"></script>
|
||||||
|
|
|
@ -62,7 +62,7 @@ function goToChannel(channelId) {
|
||||||
maxResults: 50,
|
maxResults: 50,
|
||||||
order: 'date',
|
order: 'date',
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
const channelData = data.items[0];
|
let grabDuration = getDuration(data.items);
|
||||||
|
|
||||||
grabDuration.then((videoList) => {
|
grabDuration.then((videoList) => {
|
||||||
channelView.seen = true;
|
channelView.seen = true;
|
||||||
|
@ -72,8 +72,6 @@ function goToChannel(channelId) {
|
||||||
videoList.items.forEach((video) => {
|
videoList.items.forEach((video) => {
|
||||||
displayVideo(video, 'channel');
|
displayVideo(video, 'channel');
|
||||||
});
|
});
|
||||||
$('#main').html(rendered);
|
|
||||||
stopLoadingAnimation();
|
|
||||||
|
|
||||||
// Grab the channel's latest uploads. API forces a max of 50.
|
// Grab the channel's latest uploads. API forces a max of 50.
|
||||||
youtubeAPI('search', {
|
youtubeAPI('search', {
|
||||||
|
@ -92,5 +90,7 @@ function goToChannel(channelId) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,53 +1,48 @@
|
||||||
/*
|
/*
|
||||||
This file is part of FreeTube.
|
This file is part of FreeTube.
|
||||||
|
FreeTube is free software: you can redistribute it and/or modify
|
||||||
FreeTube is free software: you can redistribute it and/or modify
|
it under the terms of the GNU General Public License as published by
|
||||||
it under the terms of the GNU General Public License as published by
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
(at your option) any later version.
|
||||||
(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
|
||||||
FreeTube is distributed in the hope that it will be useful,
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
GNU General Public License for more details.
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
You should have received a copy of the GNU General Public License
|
||||||
GNU General Public License for more details.
|
along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
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
|
* Add a video to the history database file
|
||||||
*
|
*
|
||||||
* @param {string} videoId - The video ID of the video to be saved.
|
* @param {string} videoId - The video ID of the video to be saved.
|
||||||
*
|
*
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function addToHistory(videoId) {
|
function addToHistory(videoId){
|
||||||
const data = {
|
const data = {
|
||||||
videoId: videoId,
|
videoId: videoId,
|
||||||
timeWatched: new Date().getTime(),
|
timeWatched: new Date().getTime(),
|
||||||
};
|
};
|
||||||
historyDb.insert(data, (err, newDoc) => {});
|
historyDb.insert(data, (err, newDoc) => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a video from the history database file
|
* Remove a video from the history database file
|
||||||
*
|
*
|
||||||
* @param {string} videoId - The video ID of the video to be removed.
|
* @param {string} videoId - The video ID of the video to be removed.
|
||||||
*
|
*
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function removeFromHistory(videoId) {
|
function removeFromHistory(videoId){
|
||||||
const data = {
|
const data = {videoId: videoId};
|
||||||
videoId: videoId
|
historyDb.remove(data, {}, (err, numRemoved) => {});
|
||||||
};
|
|
||||||
historyDb.remove(data, {}, (err, numRemoved) => {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,21 +55,22 @@ function showHistory(){
|
||||||
//startLoadingAnimation();
|
//startLoadingAnimation();
|
||||||
console.log('checking history');
|
console.log('checking history');
|
||||||
|
|
||||||
let videoList = '';
|
let videoList = '';
|
||||||
|
|
||||||
historyDb.find({}).sort({
|
historyDb.find({}).sort({
|
||||||
timeWatched: -1
|
timeWatched: -1
|
||||||
}).exec((err, docs) => {
|
}).exec((err, docs) => {
|
||||||
if (docs.length > 49) {
|
if(docs.length > 49){
|
||||||
// The YouTube API limits the search to 50 videos, so grab 50 most recent.
|
// The YouTube API limits the search to 50 videos, so grab 50 most recent.
|
||||||
for (let i = 0; i < 49; i++) {
|
for (let i = 0; i < 49; i++) {
|
||||||
videoList = videoList + ',' + docs[i]['videoId'];
|
videoList = videoList + ',' + docs[i]['videoId'];
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
docs.forEach((video) => {
|
else{
|
||||||
videoList = videoList + ',' + video['videoId'];
|
docs.forEach((video) => {
|
||||||
});
|
videoList = videoList + ',' + video['videoId'];
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
youtubeAPI('videos', {
|
youtubeAPI('videos', {
|
||||||
part: 'snippet',
|
part: 'snippet',
|
||||||
|
@ -91,4 +87,5 @@ function showHistory(){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -17,19 +17,17 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import {
|
import {comment} from "./comment.model";
|
||||||
comment
|
|
||||||
} from "./comment.model";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entire Comment Threads for a Video
|
* Entire Comment Threads for a Video
|
||||||
*/
|
*/
|
||||||
export class commentThread {
|
export class commentThread {
|
||||||
videoId;
|
videoId: ?string;
|
||||||
nextPageToken;
|
nextPageToken: ?string;
|
||||||
pageInfo = {
|
pageInfo: {
|
||||||
totalResults,
|
totalResults: number,
|
||||||
resultsPerPage
|
resultsPerPage: number
|
||||||
};
|
};
|
||||||
items;
|
items: comment[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,27 +127,25 @@ function playVideo(videoId) {
|
||||||
if (typeof(info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks) === 'object') {
|
if (typeof(info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks) === 'object') {
|
||||||
const videoSubtitles = info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks;
|
const videoSubtitles = info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks;
|
||||||
|
|
||||||
if (subtitle.kind == 'asr') {
|
videoSubtitles.forEach((subtitle) => {
|
||||||
//subtitleUrl = subtitle.baseUrl;
|
let subtitleUrl = 'https://www.youtube.com/api/timedtext?lang=' + subtitle.languageCode + '&fmt=vtt&name=&v=' + videoId;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
playerView.subtitleHtml = videoHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const checkSubscription = isSubscribed(playerView.channelId);
|
const checkSubscription = isSubscribed(playerView.channelId);
|
||||||
|
|
||||||
checkSubscription.then((results) => {
|
|
||||||
const subscribeButton = document.getElementById('subscribeButton');
|
|
||||||
|
|
||||||
checkSubscription.then((results) => {
|
checkSubscription.then((results) => {
|
||||||
if (results === false) {
|
if (results === false) {
|
||||||
if (subscribeButton != null) {
|
if (subscribeButton != null) {
|
||||||
|
@ -181,10 +179,7 @@ function playVideo(videoId) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.setTimeout(checkVideoUrls, 5000, video480p, video720p);
|
|
||||||
|
|
||||||
window.setTimeout(checkVideoUrls, 5000, playerView.video480p, playerView.video720p);
|
window.setTimeout(checkVideoUrls, 5000, playerView.video480p, playerView.video720p);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +220,7 @@ function openMiniPlayer() {
|
||||||
videoThumbnail: playerView.thumbnail,
|
videoThumbnail: playerView.thumbnail,
|
||||||
startTime: lastTime,
|
startTime: lastTime,
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -340,4 +336,4 @@ function changeDurationBySeconds(seconds) {
|
||||||
function changeDurationByPercentage(percentage) {
|
function changeDurationByPercentage(percentage) {
|
||||||
const videoPlayer = $('.videoPlayer').get(0);
|
const videoPlayer = $('.videoPlayer').get(0);
|
||||||
videoPlayer.currentTime = videoPlayer.duration * percentage;
|
videoPlayer.currentTime = videoPlayer.duration * percentage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,4 +152,5 @@ function showSavedVideos(){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
/*
|
/*
|
||||||
This file is part of FreeTube.
|
This file is part of FreeTube.
|
||||||
|
FreeTube is free software: you can redistribute it and/or modify
|
||||||
FreeTube is free software: you can redistribute it and/or modify
|
it under the terms of the GNU General Public License as published by
|
||||||
it under the terms of the GNU General Public License as published by
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
(at your option) any later version.
|
||||||
(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
|
||||||
FreeTube is distributed in the hope that it will be useful,
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
GNU General Public License for more details.
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
You should have received a copy of the GNU General Public License
|
||||||
GNU General Public License for more details.
|
along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
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
|
'useTor': false
|
||||||
};
|
};
|
||||||
|
|
||||||
ft.log('Default Settings: ', settingDefaults);
|
console.log(settingDefaults);
|
||||||
|
|
||||||
for (let key in settingDefaults) {
|
for (let key in settingDefaults){
|
||||||
settingsDb.find({
|
settingsDb.find({_id: key}, (err, docs) => {
|
||||||
_id: key
|
if (jQuery.isEmptyObject(docs)) {
|
||||||
}, (err, docs) => {
|
newSetting = {
|
||||||
if (jQuery.isEmptyObject(docs)) {
|
_id: key,
|
||||||
newSetting = {
|
value: settingDefaults[key]
|
||||||
_id: key,
|
};
|
||||||
value: settingDefaults[key]
|
|
||||||
};
|
|
||||||
|
|
||||||
settingsDb.insert(newSetting);
|
settingsDb.insert(newSetting);
|
||||||
|
|
||||||
if (key == 'theme'){
|
if (key == 'theme'){
|
||||||
setTheme('light');
|
setTheme('light');
|
||||||
|
@ -129,20 +124,25 @@ function checkDefaultSettings() {
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function updateSettings() {
|
function updateSettings() {
|
||||||
let themeSwitch = document.getElementById('themeSwitch').checked;
|
let themeSwitch = document.getElementById('themeSwitch').checked;
|
||||||
let torSwitch = document.getElementById('torSwitch').checked;
|
let torSwitch = document.getElementById('torSwitch').checked;
|
||||||
let key = document.getElementById('api-key').value;
|
let key = document.getElementById('api-key').value;
|
||||||
let theme = 'light';
|
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) {
|
if (themeSwitch === true) {
|
||||||
theme = 'dark';
|
theme = 'dark';
|
||||||
}
|
}
|
||||||
|
|
||||||
ft.log('Theme: ', theme);
|
console.log(theme);
|
||||||
|
|
||||||
// Update default theme
|
// Update default theme
|
||||||
settingsDb.update({
|
settingsDb.update({
|
||||||
|
@ -165,40 +165,14 @@ function updateSettings() {
|
||||||
useTor = torSwitch;
|
useTor = torSwitch;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (key !== '') {
|
// To any third party devs that fork the project, please be ethical and change the API key.
|
||||||
settingsDb.update({
|
settingsDb.update({
|
||||||
_id: 'theme'
|
_id: 'apiKey'
|
||||||
}, {
|
}, {
|
||||||
value: theme
|
value: settingsView.apiKey
|
||||||
}, {}, function (err, numReplaced) {
|
}, {});
|
||||||
ft.log('Error while updating theme: ', err);
|
|
||||||
ft.log('Number replaced: ', numReplaced);
|
showToast('Settings have been saved.');
|
||||||
});
|
|
||||||
|
|
||||||
// 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.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,13 +183,13 @@ function updateSettings() {
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function toggleTheme(themeValue) {
|
function toggleTheme(themeValue) {
|
||||||
if (themeValue.checked === true) {
|
if (themeValue.checked === true) {
|
||||||
setTheme('dark');
|
setTheme('dark');
|
||||||
currentTheme = 'dark';
|
currentTheme = 'dark';
|
||||||
} else {
|
} else {
|
||||||
setTheme('light');
|
setTheme('light');
|
||||||
currentTheme = 'light';
|
currentTheme = 'light';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,86 +200,85 @@ function toggleTheme(themeValue) {
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function setTheme(option) {
|
function setTheme(option) {
|
||||||
let cssFile;
|
let cssFile;
|
||||||
const currentTheme = document.getElementsByTagName("link").item(1);
|
const currentTheme = document.getElementsByTagName("link").item(1);
|
||||||
|
|
||||||
// Create a link element
|
// Create a link element
|
||||||
const newTheme = document.createElement("link");
|
const newTheme = document.createElement("link");
|
||||||
newTheme.setAttribute("rel", "stylesheet");
|
newTheme.setAttribute("rel", "stylesheet");
|
||||||
newTheme.setAttribute("type", "text/css");
|
newTheme.setAttribute("type", "text/css");
|
||||||
|
|
||||||
// Grab the css file to be used.
|
// Grab the css file to be used.
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'light':
|
case 'light':
|
||||||
cssFile = './style/lightTheme.css';
|
cssFile = './style/lightTheme.css';
|
||||||
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';
|
||||||
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';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Default to the light theme
|
// Default to the light theme
|
||||||
cssFile = './style/lightTheme.css';
|
cssFile = './style/lightTheme.css';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
newTheme.setAttribute("href", cssFile);
|
newTheme.setAttribute("href", cssFile);
|
||||||
|
|
||||||
// Replace the current theme with the new theme
|
// Replace the current theme with the new theme
|
||||||
document.getElementsByTagName("head").item(0).replaceChild(newTheme, currentTheme);
|
document.getElementsByTagName("head").item(0).replaceChild(newTheme, currentTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import Subscriptions from an OPML file.
|
* Import Subscriptions from an OPML file.
|
||||||
*
|
*
|
||||||
* @param {string} subFile - The file location of the OPML file.
|
* @param {string} subFile - The file location of the OPML file.
|
||||||
*
|
*
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function importOpmlSubs(json) {
|
function importOpmlSubs(json){
|
||||||
if (!json[0]['folder'].includes('YouTube')) {
|
if(!json[0]['folder'].includes('YouTube')){
|
||||||
showToast('Invalid OPML File. Import is unsuccessful.');
|
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;
|
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.
|
* Import a subscriptions file that the user provides.
|
||||||
*
|
*
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function importSubscriptions() {
|
function importSubscriptions(){
|
||||||
const appDatabaseFile = localDataStorage + '/subscriptions.db';
|
const appDatabaseFile = localDataStorage + '/subscriptions.db';
|
||||||
|
|
||||||
// Open user's file browser. Only show .db files.
|
// Open user's file browser. Only show .db files.
|
||||||
dialog.showOpenDialog({
|
dialog.showOpenDialog({
|
||||||
properties: ['openFile'],
|
properties: ['openFile'],
|
||||||
filters: [{
|
filters: [
|
||||||
name: 'Database File',
|
{name: 'Database File', extensions: ['*']},
|
||||||
extensions: ['*']
|
]
|
||||||
}, ]
|
}, function(fileLocation){
|
||||||
}, function (fileLocation) {
|
if(typeof(fileLocation) === 'undefined'){
|
||||||
if (typeof (fileLocation) === 'undefined') {
|
console.log('Import Aborted');
|
||||||
ft.log('Import Aborted');
|
return;
|
||||||
return;
|
}
|
||||||
}
|
console.log(fileLocation);
|
||||||
ft.log('File Location: ', fileLocation);
|
let i = fileLocation[0].lastIndexOf('.');
|
||||||
let i = fileLocation[0].lastIndexOf('.');
|
let fileType = (i < 0) ? '' : fileLocation[0].substr(i);
|
||||||
let fileType = (i < 0) ? '' : fileLocation[0].substr(i);
|
console.log(fileType);
|
||||||
ft.log('File Type: ', fileType);
|
|
||||||
|
|
||||||
fs.readFile(fileLocation[0], function(readErr, data){
|
fs.readFile(fileLocation[0], function(readErr, data){
|
||||||
if(readErr){
|
if(readErr){
|
||||||
|
@ -313,30 +286,31 @@ function importSubscriptions() {
|
||||||
throw readErr;
|
throw readErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.includes("<opml")) {
|
if (data.includes("<opml")){
|
||||||
getOpml(data, function (error, json) {
|
getOpml(data, function (error, json){
|
||||||
if (!error) {
|
if (!error){
|
||||||
clearFile('subscriptions', false);
|
|
||||||
importOpmlSubs(json['children'][0]['children']);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
} else if (fileType !== '.db') {
|
|
||||||
showToast('Incorrect file type. Import unsuccessful.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearFile('subscriptions', false);
|
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) {
|
clearFile('subscriptions', false);
|
||||||
if (writeErr) {
|
|
||||||
showToast('Unable to create file. Please check your permissions and try again.');
|
fs.writeFile(appDatabaseFile, data, function(writeErr){
|
||||||
throw writeErr;
|
if(writeErr){
|
||||||
}
|
showToast('Unable to create file. Please check your permissions and try again.');
|
||||||
showToast('Susbcriptions have been successfully imported. Please restart FreeTube for the changes to take effect.');
|
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}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function exportSubscriptions() {
|
function exportSubscriptions() {
|
||||||
const appDatabaseFile = localDataStorage + '/subscriptions.db';
|
const appDatabaseFile = localDataStorage + '/subscriptions.db';
|
||||||
|
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
let dateMonth = date.getMonth() + 1;
|
let dateMonth = date.getMonth() + 1;
|
||||||
|
|
||||||
if (dateMonth < 10) {
|
if (dateMonth < 10){
|
||||||
dateMonth = '0' + dateMonth;
|
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;
|
||||||
}
|
}
|
||||||
|
fs.readFile(appDatabaseFile, function(readErr, data) {
|
||||||
let dateDay = date.getDate();
|
if (readErr) {
|
||||||
|
throw readErr;
|
||||||
if (dateDay < 10) {
|
}
|
||||||
dateDay = '0' + dateDay;
|
fs.writeFile(fileLocation, data, function(writeErr) {
|
||||||
}
|
if (writeErr) {
|
||||||
|
throw writeErr;
|
||||||
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) {
|
showToast('Susbcriptions have been successfully exported');
|
||||||
if (readErr) {
|
});
|
||||||
throw readErr;
|
})
|
||||||
}
|
});
|
||||||
fs.writeFile(fileLocation, data, function (writeErr) {
|
|
||||||
if (writeErr) {
|
|
||||||
throw writeErr;
|
|
||||||
}
|
|
||||||
showToast('Susbcriptions have been successfully exported');
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear out the data in a file.
|
* Clear out the data in a file.
|
||||||
*
|
*
|
||||||
* @param {string} type - The type of file to be cleared.
|
* @param {string} type - The type of file to be cleared.
|
||||||
*/
|
*/
|
||||||
function clearFile(type, showMessage = true) {
|
function clearFile(type, showMessage = true){
|
||||||
ft.log('File Type: ', type);
|
console.log(type);
|
||||||
let dataBaseFile;
|
let dataBaseFile;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'subscriptions':
|
case 'subscriptions':
|
||||||
dataBaseFile = localDataStorage + '/subscriptions.db';
|
dataBaseFile = localDataStorage + '/subscriptions.db';
|
||||||
break;
|
break;
|
||||||
case 'history':
|
case 'history':
|
||||||
dataBaseFile = localDataStorage + '/videohistory.db';
|
dataBaseFile = localDataStorage + '/videohistory.db';
|
||||||
break;
|
break;
|
||||||
case 'saved':
|
case 'saved':
|
||||||
dataBaseFile = localDataStorage + '/savedvideos.db';
|
dataBaseFile = localDataStorage + '/savedvideos.db';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
showToast('Unknown file: ' + type)
|
showToast('Unknown file: ' + type)
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace data with an empty string.
|
||||||
|
fs.writeFile(dataBaseFile, '', function(err) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace data with an empty string.
|
if (showMessage){
|
||||||
fs.writeFile(dataBaseFile, '', function (err) {
|
showToast('File has been cleared. Restart FreeTube to see the changes');
|
||||||
if (err) {
|
}
|
||||||
throw err;
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDefaultSettings();
|
checkDefaultSettings();
|
||||||
|
|
|
@ -80,113 +80,103 @@ function removeSubscription(channelId) {
|
||||||
*
|
*
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function loadSubscriptions() {
|
function loadSubscriptions() {
|
||||||
if (checkSubscriptions === false && subscriptionView.videoList.length > 0){
|
if (checkSubscriptions === false && subscriptionView.videoList.length > 0){
|
||||||
console.log('Will not load subscriptions. Timer still on.');
|
console.log('Will not load subscriptions. Timer still on.');
|
||||||
loadingView.seen = false;
|
loadingView.seen = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
showToast('Refreshing Subscription List. Please wait...');
|
showToast('Refreshing Subscription List. Please wait...');
|
||||||
checkSubscriptions = false;
|
checkSubscriptions = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let videoList = [];
|
let videoList = [];
|
||||||
|
|
||||||
const subscriptions = returnSubscriptions();
|
const subscriptions = returnSubscriptions();
|
||||||
|
|
||||||
subscriptions.then((results) => {
|
subscriptions.then((results) => {
|
||||||
let channelId = '';
|
let channelId = '';
|
||||||
let videoList = [];
|
let videoList = [];
|
||||||
|
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
for (let i = 0; i < results.length; i++) {
|
|
||||||
channelId = results[i]['channelId'];
|
|
||||||
|
|
||||||
youtubeAPI('search', {
|
for (let i = 0; i < results.length; i++) {
|
||||||
part: 'snippet',
|
channelId = results[i]['channelId'];
|
||||||
channelId: channelId,
|
|
||||||
type: 'video',
|
|
||||||
maxResults: 15,
|
|
||||||
order: 'date',
|
|
||||||
}, (data) => {
|
|
||||||
|
|
||||||
youtubeAPI('search', {
|
youtubeAPI('search', {
|
||||||
part: 'snippet',
|
part: 'snippet',
|
||||||
channelId: channelId,
|
channelId: channelId,
|
||||||
type: 'video',
|
type: 'video',
|
||||||
maxResults: 15,
|
maxResults: 15,
|
||||||
order: 'date',
|
order: 'date',
|
||||||
}, (data) => {
|
}, (data) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
videoList = videoList.concat(data.items);
|
videoList = videoList.concat(data.items);
|
||||||
counter++;
|
counter++;
|
||||||
progressView.progressWidth = (counter / results.length) * 100;
|
progressView.progressWidth = (counter / results.length) * 100;
|
||||||
if (counter === results.length) {
|
if (counter === results.length) {
|
||||||
videoList.sort((a, b) => {
|
videoList.sort((a, b) => {
|
||||||
const date1 = Date.parse(a.snippet.publishedAt);
|
const date1 = Date.parse(a.snippet.publishedAt);
|
||||||
const date2 = Date.parse(b.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
|
// 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.
|
// to keep the app running at a good speed.
|
||||||
if (videoList.length < 50) {
|
if (videoList.length < 50) {
|
||||||
let grabDuration = getDuration(videoList.slice(0, 49));
|
let grabDuration = getDuration(videoList.slice(0, 49));
|
||||||
|
|
||||||
grabDuration.then((list) => {
|
grabDuration.then((list) => {
|
||||||
subscriptionView.videoList = [];
|
subscriptionView.videoList = [];
|
||||||
list.items.forEach((video) => {
|
list.items.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;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log(videoList);
|
console.log(videoList);
|
||||||
let finishedList = [];
|
let finishedList = [];
|
||||||
let firstBatchDuration = getDuration(videoList.slice(0, 49));
|
let firstBatchDuration = getDuration(videoList.slice(0, 49));
|
||||||
|
|
||||||
grabDuration.then((list) => {
|
firstBatchDuration.then((list1) => {
|
||||||
list.items.forEach((video) => {
|
finishedList = finishedList.concat(list1.items);
|
||||||
displayVideo(video);
|
let secondBatchDuration = getDuration(videoList.slice(50, 99));
|
||||||
});
|
|
||||||
stopLoadingAnimation();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
|
|
||||||
secondBatchDuration.then((list2) => {
|
secondBatchDuration.then((list2) => {
|
||||||
finishedList = finishedList.concat(list2.items);
|
finishedList = finishedList.concat(list2.items);
|
||||||
console.log(finishedList);
|
console.log(finishedList);
|
||||||
subscriptionView.videoList = [];
|
subscriptionView.videoList = [];
|
||||||
finishedList.forEach((video) => {
|
finishedList.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);
|
}, 60000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// User has no subscriptions. Display message.
|
// User has no subscriptions. Display message.
|
||||||
loadingView.seen = false;
|
loadingView.seen = false;
|
||||||
headerView.seen = false;
|
headerView.seen = false;
|
||||||
noSubscriptions.seen = true;
|
noSubscriptions.seen = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of subscriptions from the user's subscription database.
|
* Get the list of subscriptions from the user's subscription database.
|
||||||
|
@ -281,4 +271,4 @@ function isSubscribed(channelId) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,11 @@ let popularView = new Vue({
|
||||||
},
|
},
|
||||||
toggleSave: (videoId) => {
|
toggleSave: (videoId) => {
|
||||||
addSavedVideo(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
|
template: videoListTemplate
|
||||||
|
|
|
@ -220,7 +220,6 @@ function displayChannels(channels) {
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
ft.log('Channel Data: ', data);
|
ft.log('Channel Data: ', data);
|
||||||
let items = data['items'].reverse();
|
let items = data['items'].reverse();
|
||||||
const videoListTemplate = require('./templates/channelList.html');
|
|
||||||
|
|
||||||
ft.log('Channel Items: ', items);
|
ft.log('Channel Items: ', items);
|
||||||
|
|
||||||
|
@ -240,6 +239,7 @@ function displayChannels(channels) {
|
||||||
|
|
||||||
searchView.videoList = searchView.videoList.concat(channelData);
|
searchView.videoList = searchView.videoList.concat(channelData);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayPlaylists(playlists) {
|
function displayPlaylists(playlists) {
|
||||||
|
@ -343,6 +343,7 @@ function showVideoRecommendations(videoId) {
|
||||||
playerView.recommendedVideoList = playerView.recommendedVideoList.concat(data);
|
playerView.recommendedVideoList = playerView.recommendedVideoList.concat(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -404,7 +405,7 @@ function parseSearchText(url = '') {
|
||||||
* @return {string} - The formated string. Ex: 12:34:56
|
* @return {string} - The formated string. Ex: 12:34:56
|
||||||
*/
|
*/
|
||||||
function parseVideoDuration(durationString) {
|
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 = '';
|
let duration = '';
|
||||||
|
|
||||||
match = match.slice(1).map(function (x) {
|
match = match.slice(1).map(function (x) {
|
||||||
|
@ -602,4 +603,4 @@ function checkVideoUrls(video480p, video720p) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue