mirror of https://github.com/FreeTubeApp/FreeTube
[WIP] Translation Template and Browser Redirect
This commit is contained in:
commit
dd8035921a
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "FreeTube",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "FreeTube",
|
||||
"productName": "FreeTube",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"description": "An Open Source YouTube app for privacy.",
|
||||
"main": "src/js/init.js",
|
||||
"scripts": {
|
||||
|
@ -34,6 +34,11 @@
|
|||
"rpm"
|
||||
]
|
||||
},
|
||||
"protocols": [{
|
||||
"name": "freetube",
|
||||
"role": "Viewer",
|
||||
"schemes": ["freetube"]
|
||||
}],
|
||||
"electronPackagerConfig": {
|
||||
"packageManager": "yarn",
|
||||
"icon": "./src/icons/icon.icns"
|
||||
|
|
|
@ -43,9 +43,8 @@
|
|||
<div class="topNav">
|
||||
<span class="logo"><i onclick='toggleSideNavigation()' class="menuButton fas fa-bars"></i> FreeTube <i class="far fa-play-circle"></i></span>
|
||||
<div class="searchBar">
|
||||
<input id='jumpToInput' class='jumpToInput' type='text' placeholder="Jump to Video Link / Id" /><i onclick='parseVideoLink()' class="fas fa-search searchButton" style='margin-right: 50px; cursor: pointer;'></i>
|
||||
<input id='search' class="search" type="text" placeholder="Search">
|
||||
<i onclick='search()' class="fas fa-search searchButton" style='margin-right: -10px; cursor: pointer'></i>
|
||||
<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>
|
||||
<div id='sideNavDisabled'></div>
|
||||
|
|
|
@ -115,7 +115,7 @@ let videoShortcutHandler = function(event) {
|
|||
}
|
||||
break;
|
||||
case 67:
|
||||
// F Key
|
||||
// C Key
|
||||
event.preventDefault();
|
||||
let subtitleMode = $('.videoPlayer').get(0).textTracks[0].mode;
|
||||
if (subtitleMode === 'hidden'){
|
||||
|
|
|
@ -20,11 +20,29 @@ along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
|
|||
/*
|
||||
* File used to initializing the application
|
||||
*/
|
||||
const {app, BrowserWindow, dialog} = require('electron');
|
||||
const {app, BrowserWindow, dialog, protocol} = require('electron');
|
||||
const path = require('path');
|
||||
const url = require('url');
|
||||
let win;
|
||||
|
||||
protocol.registerStandardSchemes(['freetube'])
|
||||
|
||||
app.setAsDefaultProtocolClient('freetube');
|
||||
|
||||
const isSecondInstance = app.makeSingleInstance((commandLine, workingDirectory) => {
|
||||
// Someone tried to run a second instance, we should focus our window.
|
||||
if (win) {
|
||||
if (win.isMinimized()) win.restore()
|
||||
win.focus()
|
||||
|
||||
win.webContents.send( 'ping', commandLine)
|
||||
}
|
||||
})
|
||||
|
||||
if (isSecondInstance) {
|
||||
app.quit()
|
||||
}
|
||||
|
||||
if(require('electron-squirrel-startup')) app.quit();
|
||||
|
||||
/**
|
||||
|
@ -34,6 +52,7 @@ if(require('electron-squirrel-startup')) app.quit();
|
|||
*/
|
||||
let init = function() {
|
||||
const Menu = require('electron').Menu;
|
||||
|
||||
win = new BrowserWindow({width: 1200, height: 800, autoHideMenuBar: true});
|
||||
|
||||
win.loadURL(url.format({
|
||||
|
@ -43,7 +62,7 @@ let init = function() {
|
|||
}));
|
||||
|
||||
if (process.env = 'development') {
|
||||
//win.webContents.openDevTools();
|
||||
//win.webContents.openDevTools();ff
|
||||
}
|
||||
|
||||
win.on('closed', () => {
|
||||
|
@ -51,15 +70,18 @@ let init = function() {
|
|||
});
|
||||
|
||||
const template = [
|
||||
{
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{role: 'quit'}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{role: 'undo'},
|
||||
{role: 'redo'},
|
||||
{type: 'separator'},
|
||||
{role: 'cut'},
|
||||
{role: 'copy'},
|
||||
{role: 'paste'},
|
||||
{role: 'copy', accelerator: "CmdOrCtrl+C", selector: "copy:" },
|
||||
{role: 'paste', accelerator: "CmdOrCtrl+V", selector: "paste:" },
|
||||
{role: 'pasteandmatchstyle'},
|
||||
{role: 'delete'},
|
||||
{role: 'selectall'}
|
||||
|
|
|
@ -28,11 +28,12 @@ window.$ = window.jQuery = require('jquery');
|
|||
const mustache = require('mustache'); // templating
|
||||
const dateFormat = require('dateformat'); // formatting dates
|
||||
|
||||
const RxPlayer = require('rx-player'); // formatting dates
|
||||
//const RxPlayer = require('rx-player'); // formatting dates
|
||||
|
||||
// Used for finding links within text and making them clickable. Used mostly for video descriptions.
|
||||
const autolinker = require('autolinker');
|
||||
const electron = require('electron');
|
||||
const protocol = electron.remote.protocol;
|
||||
|
||||
// Used for getting the user's subscriptions. Can probably remove this when that function
|
||||
// is rewritten.
|
||||
|
@ -47,7 +48,7 @@ const fs = require('fs'); // Used to read files. Specifically in the settings pa
|
|||
|
||||
let currentTheme = '';
|
||||
let apiKey;
|
||||
let dialog = require('electron').remote.dialog; // Used for opening file browser to export / import subscriptions.
|
||||
let dialog = electron.remote.dialog; // Used for opening file browser to export / import subscriptions.
|
||||
let toastTimeout; // Timeout for toast notifications.
|
||||
let mouseTimeout; // Timeout for hiding the mouse cursor on video playback
|
||||
|
||||
|
@ -79,7 +80,13 @@ const settingsDb = new Datastore({
|
|||
// none are found.
|
||||
checkDefaultSettings();
|
||||
|
||||
// Ppen links externally by default
|
||||
require('electron').ipcRenderer.on('ping', function(event, message) {
|
||||
let url = message[1].replace('freetube://', '');
|
||||
parseSearchText(url);
|
||||
console.log(message); // Prints "whoooooooh!"
|
||||
});
|
||||
|
||||
// Open links externally by default
|
||||
$(document).on('click', 'a[href^="http"]', (event) => {
|
||||
let el = event.currentTarget;
|
||||
event.preventDefault();
|
||||
|
@ -104,14 +111,7 @@ $(document).ready(() => {
|
|||
// Allow user to use the 'enter' key to search for a video.
|
||||
searchBar.onkeypress = (e) => {
|
||||
if (e.keyCode === 13) {
|
||||
search();
|
||||
}
|
||||
};
|
||||
|
||||
// Allow user to use the 'enter' key to open a video link.
|
||||
jumpToInput.onkeypress = (e) => {
|
||||
if (e.keyCode === 13) {
|
||||
parseVideoLink();
|
||||
parseSearchText();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -153,24 +153,20 @@ function startLoadingAnimation() {
|
|||
const loading = document.getElementById('loading');
|
||||
const sideNavDisabled = document.getElementById('sideNavDisabled');
|
||||
const searchBar = document.getElementById('search');
|
||||
const goToVideoInput = document.getElementById('jumpToInput');
|
||||
|
||||
loading.style.display = 'inherit';
|
||||
sideNavDisabled.style.display = 'inherit';
|
||||
searchBar.disabled = true;
|
||||
goToVideoInput.disabled = true;
|
||||
}
|
||||
|
||||
function stopLoadingAnimation() {
|
||||
const loading = document.getElementById('loading');
|
||||
const sideNavDisabled = document.getElementById('sideNavDisabled');
|
||||
const searchBar = document.getElementById('search');
|
||||
const goToVideoInput = document.getElementById('jumpToInput');
|
||||
|
||||
loading.style.display = 'none';
|
||||
sideNavDisabled.style.display = 'none';
|
||||
searchBar.disabled = false;
|
||||
goToVideoInput.disabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -146,14 +146,14 @@ function playVideo(videoId, videoThumbnail = '') {
|
|||
videoHtml = '<video class="videoPlayer" type="application/x-mpegURL" onmousemove="hideMouseTimeout()" onmouseleave="removeMouseTimeout()" controls="" src="' + defaultUrl + '" poster="' + videoThumbnail + '" autoplay>';
|
||||
|
||||
|
||||
if(typeof(info.player_response.captions) === 'object'){
|
||||
if(typeof(info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks) === 'object'){
|
||||
if (typeof(info.player_response.captions) === 'object') {
|
||||
if (typeof(info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks) === 'object') {
|
||||
const videoSubtitles = info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks;
|
||||
|
||||
videoSubtitles.forEach((subtitle) => {
|
||||
let subtitleUrl = 'https://www.youtube.com/api/timedtext?lang=' + subtitle.languageCode + '&fmt=vtt&name=&v=' + videoId;
|
||||
|
||||
if(subtitle.kind == 'asr'){
|
||||
if (subtitle.kind == 'asr') {
|
||||
//subtitleUrl = subtitle.baseUrl;
|
||||
return;
|
||||
}
|
||||
|
@ -217,7 +217,13 @@ function playVideo(videoId, videoThumbnail = '') {
|
|||
}*/
|
||||
|
||||
showVideoRecommendations(videoId);
|
||||
console.log('done');
|
||||
|
||||
if (Object.keys(info['subtitles']).length > 0) {
|
||||
let textTracks = $('.videoPlayer').get(0).textTracks;
|
||||
Object.keys(textTracks).forEach((track) => {
|
||||
textTracks[track].mode = 'hidden';
|
||||
});
|
||||
}
|
||||
|
||||
// Sometimes a video URL is found, but the video will not play. I believe the issue is
|
||||
// that the video has yet to render for that quality, as the video will be available at a later time.
|
||||
|
|
|
@ -79,7 +79,7 @@ function removeSubscription(channelId) {
|
|||
*/
|
||||
function loadSubscriptions() {
|
||||
clearMainContainer();
|
||||
showToast('Getting Subscriptions. This may take a while...');
|
||||
showToast('Getting Subscriptions. Please wait...');
|
||||
const loading = document.getElementById('loading');
|
||||
|
||||
startLoadingAnimation()
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
{
|
||||
"File": "File",
|
||||
"Quit": "Quit",
|
||||
"Edit": "Edit",
|
||||
"Undo": "Undo",
|
||||
"Redo": "Redo",
|
||||
"Cut": "Cut",
|
||||
"Copy": "Copy",
|
||||
"Paste": "Paste",
|
||||
"Delete": "Delete",
|
||||
"Select all": "Select all",
|
||||
"View": "View",
|
||||
"Reload": "Reload",
|
||||
"Force Reload": "Force Reload",
|
||||
"Toggle Developer Tools": "Toggle Developer Tools",
|
||||
"Actual size": "Actual size",
|
||||
"Zoom in": "Zoom in",
|
||||
"Zoom out": "Zoom out",
|
||||
"Toggle fullscreen": "Toggle fullscreen",
|
||||
"Window": "Window",
|
||||
"Minimize": "Minimize",
|
||||
"Close": "Close",
|
||||
"FreeTube": "FreeTube",
|
||||
"Subscriptions": "Subscriptions",
|
||||
"Featured": "Featured",
|
||||
"Most Popular": "Most Popular",
|
||||
"Saved": "Saved",
|
||||
"Playlists": "History",
|
||||
"History": "History",
|
||||
"Settings": "Settings",
|
||||
"About": "About",
|
||||
"Search / Go to URL": "Search / Go to URL",
|
||||
"Search Results": "Search Results",
|
||||
"Subscriber": "Subscriber",
|
||||
"Subscriber": "Subscribers",
|
||||
"Video": "Video",
|
||||
"Videos": "Videos",
|
||||
"View Full Playlist": "View Full Playlist",
|
||||
"Live Now": "Live Now",
|
||||
"Fetch more results": "Fetch more results",
|
||||
"Fetching results. Please wait": "Fetching results. Please wait",
|
||||
"Latest Subscriptions": "Latest Subscriptions",
|
||||
"Save Video": "Save Video",
|
||||
"Remove Saved Video": "Remove Saved Video",
|
||||
"Open in YouTube": "Open in YouTube",
|
||||
"Copy YouTube Link": "Copy YouTube Link",
|
||||
"Open in HookTube": "Open in HookTube",
|
||||
"Copy HookTube Link": "Copy HookTube Link",
|
||||
"URL has been copied to the clipboard": "URL has been copied to the clipboard",
|
||||
"Found valid URL for 480p, but returned a 404. Video type might be available in the future.": "Found valid URL for 480p, but returned a 404. Video type might be available in the future.",
|
||||
"Save": "Save",
|
||||
"Mini Player": "Mini Player",
|
||||
"View": "View",
|
||||
"Views": "Views",
|
||||
"Subscribe": "Subscribe",
|
||||
"Unsubscribe": "Unsubscribe",
|
||||
"Published on": "Published on",
|
||||
"Jan": "Jan",
|
||||
"Feb": "Feb",
|
||||
"Mar": "Mar",
|
||||
"Apr": "Apr",
|
||||
"May": "May",
|
||||
"Jun": "Jun",
|
||||
"Jul": "Jul",
|
||||
"Aug": "Aug",
|
||||
"Sep": "Sep",
|
||||
"Oct": "Oct",
|
||||
"Nov": "Nov",
|
||||
"Dec": "Dec",
|
||||
"Show Comments": "Show Comments",
|
||||
"Max of 100": "Max of 100",
|
||||
"Recommendations": "Recommendations",
|
||||
"Latest Subscriptions": "Latest Subscriptions",
|
||||
"Getting Subscriptions. Please wait...": "Getting Subscriptions. Please wait...",
|
||||
"Your Subscription list is currently empty. Start adding subscriptions to see them here.": "Your Subscription list is currently empty. Start adding subscriptions to see them here.",
|
||||
"Saved Videos": "Saved Videos",
|
||||
"Watch History": "Watch History",
|
||||
"API Key": "API Key",
|
||||
"Set API Key: Leave blank to use default": "Set API Key: Leave blank to use default",
|
||||
"Use Dark Theme": "Use Dark Theme",
|
||||
"Import Subscriptions": "Import Subscriptions",
|
||||
"Export Subscriptions": "Export Subscriptions",
|
||||
"Clear History": "Clear History",
|
||||
"Are you sure you want to delete your history?": "Are you sure you want to delete your history?",
|
||||
"Clear Saved Videos": "Clear Saved Videos",
|
||||
"Are you sure you want to remove all saved videos?": "Are you sure you want to remove all saved videos?",
|
||||
"Clear Subscriptions": "Clear Subscriptions",
|
||||
"Are you sure you want to remove all subscriptions?": "Are you sure you want to remove all subscriptions?",
|
||||
"Save Settings": "Save Settings",
|
||||
"Yes": "Yes",
|
||||
"No": "No",
|
||||
"Beta": "Beta",
|
||||
"This software is FOSS and released under the GNU Public License v3+.": "This software is FOSS and released under the GNU Public License v3+.",
|
||||
"Found a bug? Want to suggest a feature? Want to help out? Check out our GitHub page. Pull requests are welcome.": "Found a bug? Want to suggest a feature? Want to help out? Check out our GitHub page. Pull requests are welcome."
|
||||
};
|
|
@ -338,8 +338,15 @@ function showVideoRecommendations(videoId) {
|
|||
*
|
||||
* @return {Void}
|
||||
*/
|
||||
function parseVideoLink() {
|
||||
let input = document.getElementById('jumpToInput').value;
|
||||
function parseSearchText(url = '') {
|
||||
let input;
|
||||
|
||||
if (url === ''){
|
||||
input = document.getElementById('search').value;
|
||||
}
|
||||
else{
|
||||
input = url;
|
||||
}
|
||||
|
||||
if (input === '') {
|
||||
return;
|
||||
|
@ -354,9 +361,11 @@ function parseVideoLink() {
|
|||
|
||||
// Play video if a match is found.
|
||||
try {
|
||||
console.log('Match Found');
|
||||
playVideo(match[2]);
|
||||
} catch (err) {
|
||||
showToast('Video Not Found');
|
||||
console.log('Video not found');
|
||||
search();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,17 +64,13 @@ a {
|
|||
}
|
||||
|
||||
.searchBar input {
|
||||
width: 40%;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.searchButton {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.jumpToInput {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
#sideNav {
|
||||
height: 100vh;
|
||||
width: 250px;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{{videoHtml}}}
|
||||
<div class='statistics'>
|
||||
<div class='smallButton' onclick="openMiniPlayer('{{videoThumbnail}}')">
|
||||
MINI PLAYER <i class="fas fa-external-link-alt"></i>
|
||||
MINI PLAYER <i class="fas fa-external-link-alt"></i>
|
||||
</div>
|
||||
<div class='smallButton videoQuality'>
|
||||
<span id='currentQuality'>{{videoQuality}}</span> <i class="fas fa-angle-down"></i>
|
||||
|
@ -34,9 +34,19 @@
|
|||
<div class='smallButton' onclick='copyLink("youtube", "{{videoId}}")'>
|
||||
COPY YOUTUBE LINK
|
||||
</div>
|
||||
<a href='https://youtube.com/watch?v={{videoId}}'>
|
||||
<div class='smallButton'>
|
||||
OPEN IN YOUTUBE
|
||||
</div>
|
||||
</a>
|
||||
<div class='smallButton' onclick='copyLink("hooktube", "{{videoId}}")'>
|
||||
COPY HOOKTUBE LINK
|
||||
</div>
|
||||
<a href='https://hooktube.com/watch?v={{videoId}}'>
|
||||
<div class='smallButton' onclick='copyLink("hooktube", "{{videoId}}")'>
|
||||
OPEN IN HOOKTUBE
|
||||
</div>
|
||||
</a>
|
||||
<br />
|
||||
<p class='title'>{{videoTitle}}</p>
|
||||
<p class='views'>{{videoViews}} views</p>
|
||||
|
|
Loading…
Reference in New Issue