From 9c9707705f991680861ed41faf028e5d5566b759 Mon Sep 17 00:00:00 2001 From: Ealhad Date: Fri, 9 Nov 2018 14:30:35 +0100 Subject: [PATCH] Implement #1: allow to redirect automatically --- src/options.html | 63 +++++++++++++++++++++++++++++++++++++--------- src/options.ts | 23 ++++++++++------- src/peertube.ts | 48 +++++++++++++++++++++++++---------- src/preferences.ts | 12 ++++++--- src/types.ts | 6 +++++ src/youtube.ts | 53 +++++++++++++++++++++++++++----------- 6 files changed, 153 insertions(+), 52 deletions(-) diff --git a/src/options.html b/src/options.html index 8f8b78d..f024d87 100644 --- a/src/options.html +++ b/src/options.html @@ -15,19 +15,58 @@ - +
+

+ YouTube +

- +
+ + + + + +
+ + +
+ +
+

+ PeerTube +

+ +
+ + + + + +
+
diff --git a/src/options.ts b/src/options.ts index 8577379..0aef2a5 100644 --- a/src/options.ts +++ b/src/options.ts @@ -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); diff --git a/src/peertube.ts b/src/peertube.ts index 53d8f24..1ec5a49 100644 --- a/src/peertube.ts +++ b/src/peertube.ts @@ -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; + } } } diff --git a/src/preferences.ts b/src/preferences.ts index c7a3644..fd41297 100644 --- a/src/preferences.ts +++ b/src/preferences.ts @@ -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() } diff --git a/src/types.ts b/src/types.ts index 2b30ec7..331b7cb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,3 +2,9 @@ export enum MessageKind { SearchByName, SearchByID, } + +export enum RedirectType { + None = 'None', + Show = 'Show', + Auto = 'Auto' +} diff --git a/src/youtube.ts b/src/youtube.ts index 83c88c1..3b86918 100644 --- a/src/youtube.ts +++ b/src/youtube.ts @@ -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); } } }