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

View File

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

View File

@ -18,7 +18,7 @@ import * as _ from 'lodash/fp';
import * as browser from 'webextension-polyfill'; import * as browser from 'webextension-polyfill';
import { htmlToElement } from './util'; import { htmlToElement } from './util';
import { MessageKind } from './types'; import { MessageKind, RedirectType } from './types';
import Preferences from './preferences'; import Preferences from './preferences';
const watchURL = (host, uuid) => `https://${host}/videos/watch/${uuid}`; 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'; const LINK_ID = 'peertube-link';
async function peertubeify() { function searchVideo() {
const prefs = await Preferences.getPreferences()
const isPreferredInstance = _.equals(prefs.searchInstance, location.hostname)
if (prefs.showOnPeertube && !isPreferredInstance) {
const id = _.last(_.split('/', location.href)); const id = _.last(_.split('/', location.href));
browser.runtime.sendMessage({ return browser.runtime.sendMessage({
kind: MessageKind.SearchByID, kind: MessageKind.SearchByID,
id id
}).then(async ({ video, url }) => { });
const link = videoLink(url, video); }
async function peertubeify() {
const prefs = await Preferences.getPreferences();
const isPreferredInstance = _.equals(prefs.searchInstance, location.hostname);
if (isPreferredInstance) {
return;
}
switch (prefs.redirectPeertube) {
case RedirectType.Show: {
searchVideo()
.then(async ({ video, url }) => {
const link = videoLink(url, video);
removeVideoLink(); removeVideoLink();
document.querySelector('body').appendChild(link); document.querySelector('body').appendChild(link);
}).catch(removeVideoLink); }).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 _ from 'lodash/fp';
import * as browser from 'webextension-polyfill'; import * as browser from 'webextension-polyfill';
import constants from './constants' import constants from './constants';
import { RedirectType } from './types';
const stripProtocol = _.replace(/^https?:\/\//, ''); const stripProtocol = _.replace(/^https?:\/\//, '');
export default class Preferences { export default class Preferences {
private _searchInstance: string; private _searchInstance: string;
openInOriginalInstance: boolean; openInOriginalInstance: boolean;
showOnPeertube: boolean; redirectYoutube: RedirectType;
redirectPeertube: RedirectType;
constructor(localStorage) { constructor(localStorage) {
this.searchInstance = _.defaultTo(constants.defaultInstance, localStorage.searchInstance as string); this.searchInstance = _.defaultTo(constants.defaultInstance, localStorage.searchInstance as string);
this.openInOriginalInstance = _.defaultTo(true, localStorage.openInOriginalInstance as boolean); 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() { static async getPreferences() {
@ -40,7 +43,8 @@ export default class Preferences {
await browser.storage.local.set({ await browser.storage.local.set({
searchInstance: this.searchInstance, searchInstance: this.searchInstance,
openInOriginalInstance: this.openInOriginalInstance, openInOriginalInstance: this.openInOriginalInstance,
showOnPeertube: this.showOnPeertube, redirectYoutube: this.redirectYoutube,
redirectPeertube: this.redirectPeertube,
}) })
const prefs = await browser.storage.local.get() const prefs = await browser.storage.local.get()
} }

View File

@ -2,3 +2,9 @@ export enum MessageKind {
SearchByName, SearchByName,
SearchByID, 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 * as browser from 'webextension-polyfill';
import { htmlToElement } from './util'; import { htmlToElement } from './util';
import { MessageKind } from './types'; import { MessageKind, RedirectType } from './types';
import Preferences from './preferences' import Preferences from './preferences'
const watchURL = (host, uuid) => `https://${host}/videos/watch/${uuid}`; 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'; const LINK_ID = 'peertube-link';
function peertubeify(query: string) { function searchVideo(query) {
browser.runtime.sendMessage({ return browser.runtime.sendMessage({
kind: MessageKind.SearchByName, kind: MessageKind.SearchByName,
query, query,
}).then(async video => { });
}
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(); const prefs = await Preferences.getPreferences();
const url = watchURL(prefs.openInOriginalInstance ? video.account.host : prefs.searchInstance, video.uuid); switch (prefs.redirectYoutube) {
case RedirectType.Show: {
searchVideo(query)
.then(async video => {
const url = getCorrectURL(video, prefs)
const link = videoLink(url, video); const link = videoLink(url, video);
removeVideoLink(); removeVideoLink();
document.querySelector('ytd-app').appendChild(link); document.querySelector('ytd-app').appendChild(link);
}).catch(removeVideoLink); }).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 throttledPeertubify = _.throttle(1000, peertubeify); const throttledPeertubeify = _.throttle(1000, peertubeify);
const observer = new MutationObserver(function(mutationsList) { const observer = new MutationObserver(function(mutationsList) {
for (const mutation of mutationsList) { for (const mutation of mutationsList) {
if ((mutation.target as Element).classList.contains('ytp-title-link')) { if ((mutation.target as Element).classList.contains('ytp-title-link')) {
for (const node of mutation.addedNodes) { for (const node of mutation.addedNodes) {
if (node.nodeType == Node.TEXT_NODE) { if (node.nodeType == Node.TEXT_NODE) {
throttledPeertubify(node.textContent); throttledPeertubeify(node.textContent);
} }
} }
} }