From 02005a0ef87b46415390a74004bbb4fe2047149f Mon Sep 17 00:00:00 2001 From: Ealhad Date: Fri, 9 Nov 2018 12:44:07 +0100 Subject: [PATCH] Add Preferences class to handle localStorage --- src/background.ts | 50 ++++++++++++++++++++--------------------- src/constants.ts | 2 +- src/options.ts | 35 ++++++++++++----------------- src/peertube.ts | 47 +++++++++++++++++++-------------------- src/preferences.ts | 55 ++++++++++++++++++++++++++++++++++++++++++++++ src/youtube.ts | 46 +++++++++++++++++++------------------- tsconfig.json | 22 +++++++++---------- 7 files changed, 151 insertions(+), 106 deletions(-) create mode 100644 src/preferences.ts diff --git a/src/background.ts b/src/background.ts index 698732e..2d4bb98 100644 --- a/src/background.ts +++ b/src/background.ts @@ -18,43 +18,43 @@ import * as _ from 'lodash/fp'; import * as browser from 'webextension-polyfill'; import { MessageKind } from './types'; -import { constants } from './constants'; +import constants from './constants'; const buildSearchByNameURL = (instance: string, query: string): string => `https://${instance}/api/v1/search/videos?search=${encodeURIComponent(query)}`; const searchByName = query => new Promise(async (resolve, reject) => { - const instance = _.getOr(constants.defaultInstance, 'searchInstance', await browser.storage.local.get()).toString(); + const instance = _.getOr(constants.defaultInstance, 'searchInstance', await browser.storage.local.get()).toString(); - fetch(buildSearchByNameURL(instance, query)) - .then(res => res.json()) - .then(function(data) { - if (data.total > 0) { - const video = data.data[0] - if (video.name === query) { - resolve(video); - } - } - reject(new Error('No results.')); - }); + fetch(buildSearchByNameURL(instance, query)) + .then(res => res.json()) + .then(function(data) { + if (data.total > 0) { + const video = data.data[0] + if (video.name === query) { + resolve(video); + } + } + reject(new Error('No results.')); + }); }); const buildSearchByIDURL = (instance: string, id: string): string => `https://${instance}/api/v1/videos/${id}`; const searchByID = id => new Promise(async (resolve, reject) => { - const instance = _.getOr(constants.defaultInstance, 'searchInstance', await browser.storage.local.get()).toString(); + const instance = _.getOr(constants.defaultInstance, 'searchInstance', await browser.storage.local.get()).toString(); - fetch(buildSearchByIDURL(instance, id)) - .then(res => res.json()) - .then(function (video) { - resolve({ url: `https://${instance}/videos/watch/${id}`, video }); - }) + fetch(buildSearchByIDURL(instance, id)) + .then(res => res.json()) + .then(function(video) { + resolve({ url: `https://${instance}/videos/watch/${id}`, video }); + }) }) browser.runtime.onMessage.addListener(function(message, sender) { - switch (message.kind) { - case MessageKind.SearchByName: - return searchByName(message.query); - case MessageKind.SearchByID: - return searchByID(message.id); - } + switch (message.kind) { + case MessageKind.SearchByName: + return searchByName(message.query); + case MessageKind.SearchByID: + return searchByID(message.id); + } }); diff --git a/src/constants.ts b/src/constants.ts index 5eee3b4..2996c9c 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,3 @@ -export const constants = { +export default { defaultInstance: 'peertube.social' }; diff --git a/src/options.ts b/src/options.ts index cab7a23..8577379 100644 --- a/src/options.ts +++ b/src/options.ts @@ -16,8 +16,7 @@ import * as _ from 'lodash/fp'; import * as browser from 'webextension-polyfill'; - -import { constants } from './constants'; +import Preferences from './preferences' function id(id: string): Element { return document.getElementById(id); } @@ -25,24 +24,18 @@ const searchInstance = () => id('search-instance') as HTMLInputElement; const openInOriginalInstance = () => id('open-in-original-instance') as HTMLInputElement; const showOnPeertube = () => id('show-on-peertube') as HTMLInputElement; -function saveOptions(e) { - e.preventDefault(); - browser.storage.local.set({ - searchInstance: _.defaultTo(constants.defaultInstance, stripProtocol(searchInstance().value)), - openInOriginalInstance: _.defaultTo(true, openInOriginalInstance().checked), - showOnPeertube: _.defaultTo(false, showOnPeertube().checked), - }); -} +Preferences.getPreferences().then(preferences => { + searchInstance().value = preferences.searchInstance; + openInOriginalInstance().checked = preferences.openInOriginalInstance; + showOnPeertube().checked = preferences.showOnPeertube; -const stripProtocol = _.replace(/^https?:\/\//, ''); + function saveOptions(e) { + e.preventDefault(); + preferences.searchInstance = searchInstance().value; + preferences.openInOriginalInstance = openInOriginalInstance().checked; + preferences.showOnPeertube = showOnPeertube().checked; + preferences.save(); + } -function restoreOptions() { - browser.storage.local.get().then(result => { - searchInstance().value = _.defaultTo(constants.defaultInstance, result.searchInstance as string); - openInOriginalInstance().checked = _.defaultTo(true, result.openInOriginalInstance as boolean); - showOnPeertube().checked = _.defaultTo(false, result.showOnPeertube as boolean); - }) -} - -document.addEventListener('DOMContentLoaded', restoreOptions); -document.querySelector('form').addEventListener('submit', saveOptions); + document.querySelector('form').addEventListener('submit', saveOptions); +}) diff --git a/src/peertube.ts b/src/peertube.ts index abf194c..53d8f24 100644 --- a/src/peertube.ts +++ b/src/peertube.ts @@ -19,7 +19,7 @@ import * as browser from 'webextension-polyfill'; import { htmlToElement } from './util'; import { MessageKind } from './types'; -import { constants } from './constants'; +import Preferences from './preferences'; const watchURL = (host, uuid) => `https://${host}/videos/watch/${uuid}`; const thumbnailURL = (host, path) => `https://${host}${path}`; @@ -27,37 +27,36 @@ const thumbnailURL = (host, path) => `https://${host}${path}`; const LINK_ID = 'peertube-link'; async function peertubeify() { - const options = await browser.storage.local.get(); - const showOnPeertube = _.getOr(false, 'showOnPeertube', options); - const preferredInstance = _.getOr(constants.defaultInstance, 'searchInstance', options); - const isPreferredInstance = _.equals(preferredInstance, location.hostname) - if (showOnPeertube && !isPreferredInstance) { - const id = _.last(_.split('/', location.href)); + const prefs = await Preferences.getPreferences() - browser.runtime.sendMessage({ - kind: MessageKind.SearchByID, - id - }).then(async ({video, url}) => { - const link = videoLink(url, video); + const isPreferredInstance = _.equals(prefs.searchInstance, location.hostname) + if (prefs.showOnPeertube && !isPreferredInstance) { + const id = _.last(_.split('/', location.href)); - removeVideoLink(); - document.querySelector('body').appendChild(link); - }).catch(removeVideoLink); - } + browser.runtime.sendMessage({ + kind: MessageKind.SearchByID, + id + }).then(async ({ video, url }) => { + const link = videoLink(url, video); + + removeVideoLink(); + document.querySelector('body').appendChild(link); + }).catch(removeVideoLink); + } } const throttledPeertubeify = _.throttle(1000, peertubeify); const observer = new MutationObserver(function(mutationsList) { - for (const mutation of mutationsList) { - if ((mutation.target as Element).id =='video-element-wrapper') { - throttledPeertubeify(); + for (const mutation of mutationsList) { + if ((mutation.target as Element).id == 'video-element-wrapper') { + throttledPeertubeify(); + } } - } }); observer.observe(document.body, { - childList: true, - subtree: true, + childList: true, + subtree: true, }) const videoLink = (url, video) => htmlToElement(` @@ -114,6 +113,6 @@ const videoLink = (url, video) => htmlToElement(` `); function removeVideoLink() { - const existingLink = document.getElementById(LINK_ID); - existingLink && existingLink.remove(); + const existingLink = document.getElementById(LINK_ID); + existingLink && existingLink.remove(); } diff --git a/src/preferences.ts b/src/preferences.ts new file mode 100644 index 0000000..c7a3644 --- /dev/null +++ b/src/preferences.ts @@ -0,0 +1,55 @@ +/* This file is part of PeerTubeify. + * + * PeerTubeify is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * PeerTubeify is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * PeerTubeify. If not, see . + */ + +import * as _ from 'lodash/fp'; +import * as browser from 'webextension-polyfill'; +import constants from './constants' + +const stripProtocol = _.replace(/^https?:\/\//, ''); + +export default class Preferences { + private _searchInstance: string; + openInOriginalInstance: boolean; + showOnPeertube: boolean; + + 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); + } + + static async getPreferences() { + const localStorage = await browser.storage.local.get(); + return new Preferences(localStorage); + } + + async save() { + await browser.storage.local.set({ + searchInstance: this.searchInstance, + openInOriginalInstance: this.openInOriginalInstance, + showOnPeertube: this.showOnPeertube, + }) + const prefs = await browser.storage.local.get() + } + + get searchInstance() { + return this._searchInstance; + } + + set searchInstance(instance) { + this._searchInstance = _.isEmpty(instance) ? constants.defaultInstance : stripProtocol(instance) + } +} diff --git a/src/youtube.ts b/src/youtube.ts index 968a661..83c88c1 100644 --- a/src/youtube.ts +++ b/src/youtube.ts @@ -19,7 +19,7 @@ import * as browser from 'webextension-polyfill'; import { htmlToElement } from './util'; import { MessageKind } from './types'; -import { constants } from './constants'; +import Preferences from './preferences' const watchURL = (host, uuid) => `https://${host}/videos/watch/${uuid}`; const thumbnailURL = (host, path) => `https://${host}${path}`; @@ -27,38 +27,36 @@ const thumbnailURL = (host, path) => `https://${host}${path}`; const LINK_ID = 'peertube-link'; function peertubeify(query: string) { - browser.runtime.sendMessage({ - kind: MessageKind.SearchByName, - query, - }).then(async video => { - const options = await browser.storage.local.get(); - const openInOriginalInstance = _.getOr(true, 'openInOriginalInstance', options); - const searchInstance = _.getOr(constants.defaultInstance, 'searchInstance', options); + browser.runtime.sendMessage({ + kind: MessageKind.SearchByName, + query, + }).then(async video => { + const prefs = await Preferences.getPreferences(); - const url = watchURL(openInOriginalInstance ? video.account.host : searchInstance, video.uuid); - const link = videoLink(url, video); + 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); + removeVideoLink(); + document.querySelector('ytd-app').appendChild(link); + }).catch(removeVideoLink); } const throttledPeertubify = _.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); + 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); + } + } } - } } - } }); observer.observe(document.body, { - childList: true, - subtree: true, + childList: true, + subtree: true, }) const videoLink = (url, video) => htmlToElement(` @@ -119,6 +117,6 @@ const videoLink = (url, video) => htmlToElement(` `); function removeVideoLink() { - const existingLink = document.getElementById(LINK_ID); - existingLink && existingLink.remove(); + const existingLink = document.getElementById(LINK_ID); + existingLink && existingLink.remove(); } diff --git a/tsconfig.json b/tsconfig.json index b8533fd..6d63562 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,14 @@ { - "compilerOptions": { - "outDir": "./built", - "allowJs": true, - "target": "es6", - "typeRoots": [ - "node_modules/@types", - "node_modules/web-ext-types" + "compilerOptions": { + "outDir": "./built", + "allowJs": true, + "target": "es6", + "typeRoots": [ + "node_modules/@types", + "node_modules/web-ext-types" + ] + }, + "include": [ + "./src/**/*" ] - }, - "include": [ - "./src/**/*" - ] }