Implement #1: allow to redirect automatically
This commit is contained in:
parent
02005a0ef8
commit
9c9707705f
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,9 @@ export enum MessageKind {
|
||||||
SearchByName,
|
SearchByName,
|
||||||
SearchByID,
|
SearchByID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum RedirectType {
|
||||||
|
None = 'None',
|
||||||
|
Show = 'Show',
|
||||||
|
Auto = 'Auto'
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue