diff --git a/package-lock.json b/package-lock.json index 6213a06..e9b32ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "news-feed-eradicator", - "version": "2.2.7", + "version": "2.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "news-feed-eradicator", - "version": "2.2.7", + "version": "2.3.0", "license": "MIT", "dependencies": { "@types/node": "^8.10.36" diff --git a/src/lib/is-enabled.ts b/src/lib/is-enabled.ts index de42d48..6a46629 100644 --- a/src/lib/is-enabled.ts +++ b/src/lib/is-enabled.ts @@ -1,40 +1,46 @@ import { Sites, Site } from '../sites'; import { SettingsState } from '../background/store/reducer'; import { - getSiteStatus, - SiteStatusTag, - SiteStatus, + getSiteStatus, + SiteStatusTag, + SiteStatus, } from '../background/store/sites/selectors'; +function pathMatches(path: string, patterns: string[]): boolean { + return patterns.some(pattern => { + // Convert wildcard patterns to regex to accommodate for wildcards in YouTube Shorts + const regexPattern = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`); + return regexPattern.test(path); + }); +} + export type EnabledStatus = - | { type: 'enabled' } - | { type: 'disabled' } - | { type: 'disabled-temporarily'; until: number }; + | { type: 'enabled' } + | { type: 'disabled' } + | { type: 'disabled-temporarily'; until: number }; export function isEnabled(state: SettingsState): boolean { - return enabledStatus(state).type === 'enabled'; + return enabledStatus(state).type === 'enabled'; } export function enabledStatus(state: SettingsState): EnabledStatus { - const siteStatuses = getSiteStatus(state); - for (let siteId of Object.keys(Sites)) { - let site: Site = Sites[siteId]; - const siteStatus: SiteStatus = siteStatuses[siteId]; - if (site.domain.find(domain => window.location.host.includes(domain)) != null) { - // Always disabled if the path doesn't match - if (site.paths.indexOf(window.location.pathname) === -1) { - return { type: 'disabled' }; - } - - if (siteStatus.type === SiteStatusTag.DISABLED) { - return { type: 'disabled' }; - } else if (siteStatus.type === SiteStatusTag.DISABLED_TEMPORARILY) { - return { type: 'disabled-temporarily', until: siteStatus.until }; - } - - return { type: 'enabled' }; - } - } - - return { type: 'disabled' }; + const siteStatuses = getSiteStatus(state); + for (let siteId of Object.keys(Sites)) { + let site: Site = Sites[siteId]; + const siteStatus: SiteStatus = siteStatuses[siteId]; + // Check if the current host matches any domain in the site's domain array + if (site.domain.some(domain => window.location.host.includes(domain))) { + // Check if the current path is in the list of paths for this site + if (!pathMatches(window.location.pathname, site.paths)) { + return { type: 'disabled' }; + } + if (siteStatus.type === SiteStatusTag.DISABLED) { + return { type: 'disabled' }; + } else if (siteStatus.type === SiteStatusTag.DISABLED_TEMPORARILY) { + return { type: 'disabled-temporarily', until: siteStatus.until }; + } + return { type: 'enabled' }; + } + } + return { type: 'disabled' }; } diff --git a/src/sites/index.ts b/src/sites/index.ts index 872e5b2..d3e7057 100644 --- a/src/sites/index.ts +++ b/src/sites/index.ts @@ -12,6 +12,7 @@ export type SiteId = | 'instagram' | 'github'; + export const Sites: Record = { facebook: { label: 'Facebook', @@ -53,7 +54,7 @@ export const Sites: Record = { youtube: { label: 'YouTube', domain: ['youtube.com'], - paths: ['/', '/feed/trending'], + paths: ['/', '/feed/trending', '/shorts', '/shorts/*'], origins: ['https://www.youtube.com/*'], }, linkedin: { diff --git a/src/sites/youtube.ts b/src/sites/youtube.ts index fb7c05d..fc70cc3 100644 --- a/src/sites/youtube.ts +++ b/src/sites/youtube.ts @@ -1,4 +1,6 @@ -import injectUI, { isAlreadyInjected } from '../lib/inject-ui'; +import injectUI, { + isAlreadyInjected, +} from '../lib/inject-ui'; import { isEnabled } from '../lib/is-enabled'; import { Store } from '../store'; @@ -8,26 +10,34 @@ export function checkSite(): boolean { export function eradicate(store: Store) { function eradicateRetry() { - const settings = store.getState().settings; + const state = store.getState(); + const settings = state.settings; if (settings == null || !isEnabled(settings)) { return; } - // Don't do anything if the UI hasn't loaded yet const feed = document.querySelector('#primary'); + const shorts = document.querySelector('#shorts-container'); - if (feed == null) { + // Don't do anything if the UI hasn't loaded yet + if (feed == null && shorts == null) { return; } - const container = feed; - - // Add News Feed Eradicator quote/info panel - if (container && !isAlreadyInjected()) { + if (feed || shorts) { // Hack so that injectUI can handle dark theme document.body.style.background = 'var(--yt-spec-general-background-a)'; - injectUI(container, store); + // Redirect the user to the main page and quote if they are on the shorts page + if (shorts) { + history.pushState({}, '', '/'); + window.dispatchEvent(new Event('popstate')); + } + + // Add News Feed Eradicator quote/info panel + if (feed && !isAlreadyInjected()) { + injectUI(feed, store); + } } } diff --git a/src/store/index.ts b/src/store/index.ts index 8177890..04b2be6 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -17,6 +17,5 @@ export function createStore(): Store { undefined, applyMiddleware(effectsMiddleware(rootEffect)) ); - return store; }