Implement #1: allow to redirect automatically

This commit is contained in:
Ealhad 2018-11-09 14:30:35 +01:00
parent 02005a0ef8
commit 9c9707705f
6 changed files with 153 additions and 52 deletions

View File

@ -15,19 +15,58 @@
<input style="flex-grow: 1" type="text" id="search-instance">
</label>
<label style="margin-bottom: 1rem; display: flex; align-items: center;">
<p style="margin-right: 1rem">
Open videos in original instance?
</p>
<input type="checkbox" id="open-in-original-instance">
</label>
<section>
<h2>
YouTube
</h2>
<label style="margin-bottom: 1rem; display: flex; align-items: center;">
<p style="margin-right: 1rem">
Show a message on other PeerTube instances to redirect to your preferred one?
</p>
<input type="checkbox" id="show-on-peertube">
</label>
<div>
<label style="">
<input type="radio" name="redirectYoutube" value="None">
Do nothing
</label>
<label style="">
<input type="radio" name="redirectYoutube" value="Show">
Show a banner
</label>
<label style="">
<input type="radio" name="redirectYoutube" value="Auto">
Redirect
</label>
</div>
<label style="margin-bottom: 1rem; display: flex; align-items: center;">
<p style="margin-right: 1rem">
Open videos in original instance?
</p>
<input type="checkbox" id="open-in-original-instance">
</label>
</section>
<section>
<h2>
PeerTube
</h2>
<div>
<label style="">
<input type="radio" name="redirectPeertube" value="None">
Do nothing
</label>
<label style="">
<input type="radio" name="redirectPeertube" value="Show">
Show a banner
</label>
<label style="">
<input type="radio" name="redirectPeertube" value="Auto">
Redirect
</label>
</div>
</section>
<button style="display: block; margin-left: auto" type="submit">Save</button>
</form>

View File

@ -17,24 +17,29 @@
import * as _ from 'lodash/fp';
import * as browser from 'webextension-polyfill';
import Preferences from './preferences'
import { RedirectType } from './types';
function id(id: string): Element { return document.getElementById(id); }
const searchInstance = () => id('search-instance') as HTMLInputElement;
const openInOriginalInstance = () => id('open-in-original-instance') as HTMLInputElement;
const showOnPeertube = () => id('show-on-peertube') as HTMLInputElement;
Preferences.getPreferences().then(preferences => {
searchInstance().value = preferences.searchInstance;
openInOriginalInstance().checked = preferences.openInOriginalInstance;
showOnPeertube().checked = preferences.showOnPeertube;
const checked = name => (document.querySelector(`input[name="${name}"]:checked`) as HTMLInputElement).value;
const check = name => value => (document.querySelector(`input[name="${name}"][value="${value}"]`) as HTMLInputElement).checked = true
Preferences.getPreferences().then(prefs => {
searchInstance().value = prefs.searchInstance;
openInOriginalInstance().checked = prefs.openInOriginalInstance;
check('redirectPeertube')(prefs.redirectPeertube)
check('redirectYoutube')(prefs.redirectYoutube)
function saveOptions(e) {
e.preventDefault();
preferences.searchInstance = searchInstance().value;
preferences.openInOriginalInstance = openInOriginalInstance().checked;
preferences.showOnPeertube = showOnPeertube().checked;
preferences.save();
prefs.searchInstance = searchInstance().value;
prefs.openInOriginalInstance = openInOriginalInstance().checked;
prefs.redirectPeertube = checked('redirectPeertube') as RedirectType
prefs.redirectYoutube = checked('redirectYoutube') as RedirectType
prefs.save();
}
document.querySelector('form').addEventListener('submit', saveOptions);

View File

@ -18,7 +18,7 @@ import * as _ from 'lodash/fp';
import * as browser from 'webextension-polyfill';
import { htmlToElement } from './util';
import { MessageKind } from './types';
import { MessageKind, RedirectType } from './types';
import Preferences from './preferences';
const watchURL = (host, uuid) => `https://${host}/videos/watch/${uuid}`;
@ -26,22 +26,44 @@ const thumbnailURL = (host, path) => `https://${host}${path}`;
const LINK_ID = 'peertube-link';
function searchVideo() {
const id = _.last(_.split('/', location.href));
return browser.runtime.sendMessage({
kind: MessageKind.SearchByID,
id
});
}
async function peertubeify() {
const prefs = await Preferences.getPreferences()
const prefs = await Preferences.getPreferences();
const isPreferredInstance = _.equals(prefs.searchInstance, location.hostname)
if (prefs.showOnPeertube && !isPreferredInstance) {
const id = _.last(_.split('/', location.href));
const isPreferredInstance = _.equals(prefs.searchInstance, location.hostname);
browser.runtime.sendMessage({
kind: MessageKind.SearchByID,
id
}).then(async ({ video, url }) => {
const link = videoLink(url, video);
if (isPreferredInstance) {
return;
}
removeVideoLink();
document.querySelector('body').appendChild(link);
}).catch(removeVideoLink);
switch (prefs.redirectPeertube) {
case RedirectType.Show: {
searchVideo()
.then(async ({ video, url }) => {
const link = videoLink(url, video);
removeVideoLink();
document.querySelector('body').appendChild(link);
}).catch(removeVideoLink);
break;
}
case RedirectType.Auto: {
searchVideo()
.then(async ({ video, url }) => {
location.replace(url);
});
break;
}
case RedirectType.None: {
break;
}
}
}

View File

@ -16,19 +16,22 @@
import * as _ from 'lodash/fp';
import * as browser from 'webextension-polyfill';
import constants from './constants'
import constants from './constants';
import { RedirectType } from './types';
const stripProtocol = _.replace(/^https?:\/\//, '');
export default class Preferences {
private _searchInstance: string;
openInOriginalInstance: boolean;
showOnPeertube: boolean;
redirectYoutube: RedirectType;
redirectPeertube: RedirectType;
constructor(localStorage) {
this.searchInstance = _.defaultTo(constants.defaultInstance, localStorage.searchInstance as string);
this.openInOriginalInstance = _.defaultTo(true, localStorage.openInOriginalInstance as boolean);
this.showOnPeertube = _.defaultTo(false, localStorage.showOnPeertube as boolean);
this.redirectYoutube = _.defaultTo(RedirectType.Show, localStorage.redirectYoutube)
this.redirectPeertube = _.defaultTo(RedirectType.None, localStorage.redirectPeertube)
}
static async getPreferences() {
@ -40,7 +43,8 @@ export default class Preferences {
await browser.storage.local.set({
searchInstance: this.searchInstance,
openInOriginalInstance: this.openInOriginalInstance,
showOnPeertube: this.showOnPeertube,
redirectYoutube: this.redirectYoutube,
redirectPeertube: this.redirectPeertube,
})
const prefs = await browser.storage.local.get()
}

View File

@ -2,3 +2,9 @@ export enum MessageKind {
SearchByName,
SearchByID,
}
export enum RedirectType {
None = 'None',
Show = 'Show',
Auto = 'Auto'
}

View File

@ -18,7 +18,7 @@ import * as _ from 'lodash/fp';
import * as browser from 'webextension-polyfill';
import { htmlToElement } from './util';
import { MessageKind } from './types';
import { MessageKind, RedirectType } from './types';
import Preferences from './preferences'
const watchURL = (host, uuid) => `https://${host}/videos/watch/${uuid}`;
@ -26,28 +26,53 @@ const thumbnailURL = (host, path) => `https://${host}${path}`;
const LINK_ID = 'peertube-link';
function peertubeify(query: string) {
browser.runtime.sendMessage({
function searchVideo(query) {
return browser.runtime.sendMessage({
kind: MessageKind.SearchByName,
query,
}).then(async video => {
const prefs = await Preferences.getPreferences();
const url = watchURL(prefs.openInOriginalInstance ? video.account.host : prefs.searchInstance, video.uuid);
const link = videoLink(url, video);
removeVideoLink();
document.querySelector('ytd-app').appendChild(link);
}).catch(removeVideoLink);
});
}
const throttledPeertubify = _.throttle(1000, peertubeify);
function getCorrectURL(video: any, prefs: Preferences) {
return watchURL(prefs.openInOriginalInstance ? video.account.host : prefs.searchInstance, video.uuid)
}
async function peertubeify(query: String) {
const prefs = await Preferences.getPreferences();
switch (prefs.redirectYoutube) {
case RedirectType.Show: {
searchVideo(query)
.then(async video => {
const url = getCorrectURL(video, prefs)
const link = videoLink(url, video);
removeVideoLink();
document.querySelector('ytd-app').appendChild(link);
}).catch(removeVideoLink);
break;
}
case RedirectType.Auto: {
searchVideo(query)
.then(async video => {
const url = getCorrectURL(video, prefs)
location.replace(url);
});
break;
}
case RedirectType.None: {
break;
}
}
}
const throttledPeertubeify = _.throttle(1000, peertubeify);
const observer = new MutationObserver(function(mutationsList) {
for (const mutation of mutationsList) {
if ((mutation.target as Element).classList.contains('ytp-title-link')) {
for (const node of mutation.addedNodes) {
if (node.nodeType == Node.TEXT_NODE) {
throttledPeertubify(node.textContent);
throttledPeertubeify(node.textContent);
}
}
}