[WIP] Translation Template and Browser Redirect

This commit is contained in:
Preston 2018-05-03 12:09:53 -04:00
commit dd8035921a
12 changed files with 180 additions and 42 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "FreeTube",
"version": "0.2.0",
"version": "0.2.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -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"

View File

@ -43,9 +43,8 @@
<div class="topNav">
<span class="logo"><i onclick='toggleSideNavigation()' class="menuButton fas fa-bars"></i>&nbsp;&nbsp;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>

View File

@ -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'){

View File

@ -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'}

View File

@ -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;
}
/**

View File

@ -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.

View File

@ -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()

95
src/js/translations/en.js Normal file
View File

@ -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."
};

View File

@ -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();
}
}

View File

@ -64,17 +64,13 @@ a {
}
.searchBar input {
width: 40%;
width: 90%;
}
.searchButton {
text-decoration: none;
}
.jumpToInput {
width: 80%;
}
#sideNav {
height: 100vh;
width: 250px;

View File

@ -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>