Skip to content

Commit

Permalink
Merge pull request #35 from jishaal/wip-next
Browse files Browse the repository at this point in the history
Refactor and Reddit support
  • Loading branch information
jishaal authored Oct 15, 2022
2 parents 95d1678 + c7d86af commit 53b1b65
Show file tree
Hide file tree
Showing 19 changed files with 349 additions and 193 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Night Owl (Chrome Extension)

🦉 An extension to save your eyes! Automatically make Twitter's night mode turn on and off at sunset and sunrise.
🦉 An extension to save your eyes! Automatically make your favourite website's night mode turn on and off at sunset and sunrise.

The following sites are currently supported

- twitter.com
- reddit.com

[Get the latest version from the Chrome Store](https://chrome.google.com/webstore/detail/night-owl/iagomahcookmbnimmomjcmiaimmhompf)

---

![TwitterScreenshot](./screenshots/screenshot.JPG)
![TwitterScreenshot](./screenshots/screenshot.png)
31 changes: 31 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
"start": "webpack --watch"
},
"devDependencies": {
"@types/chrome": "0.0.143",
"@babel/core": "^7.14.3",
"@babel/preset-env": "^7.14.4",
"@babel/preset-react": "^7.13.13",
"@hot-loader/react-dom": "^17.0.1",
"@types/chrome": "0.0.143",
"@types/react": "^17.0.8",
"@types/react-dom": "^17.0.5",
"@types/webextension-polyfill": "^0.8.0",
"babel-loader": "^8.1.0",
"copy-webpack-plugin": "^6.2.1",
"css-loader": "^5.2.6",
Expand All @@ -28,6 +29,7 @@
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"element-ready": "^6.0.0",
"prettier": "^2.3.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand Down
7 changes: 4 additions & 3 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"short_name": "Night Owl",
"name": "Night Owl",
"version": "1.0.3",
"version": "1.1",
"manifest_version": 2,
"description": "An extension to save your eyes! Automatically make Twitter's night mode turn on and off at sunset and sunrise.",
"description": "An extension to save your eyes! Automatically make your favourite website's night mode turn on and off at sunset and sunrise.",
"browser_action": {
"default_popup": "index.html",
"default_title": "Night Owl"
Expand All @@ -14,7 +14,8 @@
},
"content_scripts": [
{
"matches": ["*://*/*"],
"run_at": "document_end",
"matches": ["*://*.reddit.com/*"],
"js": ["browser-polyfill.min.js", "content.js"]
}
],
Expand Down
Binary file removed screenshots/screenshot.JPG
Binary file not shown.
Binary file added screenshots/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 16 additions & 13 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
.owl {
width: 250px;
/* background-color: #011627; */
width: 240px;
background-color: #242245;
padding: 15px;
min-height: 200px;
}

/* #091e42 */
.owl-header {
padding: 1px 10px;
color: #82aaff;
color: white;
margin-bottom: 25px;
}

.owl-title {
font-size: 1.5em;
font-weight: 500;
font-size: 18px;
font-weight: 600;
margin: 0;
}

/* Settings items */
.owl-settings {
color: #82aaff;
color: white;
}

.settings-item-title {
font-size: 1.5em;
font-weight: 500;
font-size: 16px;
font-weight: 400;
}

.settings-item {
Expand All @@ -30,8 +33,8 @@
align-content: flex-end;
align-items: center;
justify-content: space-between;
background-color: #011627;
margin: 4px;
padding: 10px 6px;
border-radius: 4px;
background-color: #45426c;
margin-bottom: 10px;
padding: 8px 6px;
border-radius: 10px;
}
29 changes: 24 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,33 @@ import './App.css';

export default function App() {
const [isTwitterEnabled, setIsTwitterEnabled] = useState(false);
const [isRedditEnabled, setIsRedditEnabled] = useState(false);

useEffect(() => {
getTwitterSetting();
getSettings();
}, []);

const getTwitterSetting = async () => {
const getSettings = async () => {
const twitterSetting = await storage.get(settings.TWITTER_ON);
const redditSetting = await storage.get(settings.REDDIT_ON);
setIsTwitterEnabled(twitterSetting[settings.TWITTER_ON]);
setIsRedditEnabled(redditSetting[settings.REDDIT_ON]);
};

const handleTwitterChange = ({ target: { checked } }) => {
storage.set(settings.TWITTER_ON, checked);
setIsTwitterEnabled(checked);
};

const handleRedditChange = ({ target: { checked } }) => {
storage.set(settings.REDDIT_ON, checked);
setIsRedditEnabled(checked);
};

return (
<div className="owl">
<header className="owl-header">
<h1 className="owl-title">
<span role="img">🌙</span> Settings
</h1>
<h1 className="owl-title">Settings</h1>
</header>
<div className="owl-settings">
<div className="settings-item">
Expand All @@ -44,6 +50,19 @@ export default function App() {
/>
</div>
</div>

<div className="settings-item">
<span className="settings-item-title">
<span role="img">👽</span> Reddit
</span>
<div className="settings-toggle">
<ToggleSwitch
name="reddit"
isOn={isRedditEnabled}
onChange={handleRedditChange}
/>
</div>
</div>
</div>
</div>
);
Expand Down
19 changes: 14 additions & 5 deletions src/background.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
// This file is ran as a background script
console.log('Hello from background script! 2');

import browser from 'webextension-polyfill';
import * as storage from './util/localStorage';
import * as settings from './constants/settings';

import handleTwitter from './handlers/twitter';
import { handleTwitter } from './handlers/twitter';
import { handleReddit } from './handlers/reddit';

const URL_TWITTER = 'twitter.com';
const URL_REDDIT = 'reddit.com';

chrome.tabs.onCreated.addListener(async (tab) => {
browser.tabs.onCreated.addListener(async (tab) => {
if (tab.url) {
if (tab.url.includes(URL_TWITTER)) {
await handleTwitter(tab);
}

if (tab.url.includes(URL_REDDIT) && tab.id) {
await handleReddit(tab);
}
}
});

Expand All @@ -21,11 +25,16 @@ browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
if (changeInfo.url.includes(URL_TWITTER)) {
await handleTwitter(tab);
}

if (changeInfo.url.includes(URL_REDDIT) && tabId) {
await handleReddit(tab);
}
}
});

browser.runtime.onInstalled.addListener(async ({ reason }) => {
if (reason === 'install') {
await storage.set(settings.TWITTER_ON, true);
await storage.set(settings.REDDIT_ON, true);
}
});
9 changes: 8 additions & 1 deletion src/components/Toggle/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ import React from 'react';

import './toggle.css';

const ToggleSwitch = (props) => {
type Props = {
name: string;
isOn: boolean;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
className?: string;
};

const ToggleSwitch = (props: Props) => {
return (
<div className={`toggle ${props.className ? props.className : ''}`}>
<input
Expand Down
1 change: 1 addition & 0 deletions src/constants/settings.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const TWITTER_ON = 'userTwitterOn';
export const REDDIT_ON = 'userRedditOn';
65 changes: 52 additions & 13 deletions src/content.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,52 @@
// This file is injected as a content script
console.log('Hello from content script!');
(function () {
const userDropDownNode = document.querySelector('#USER_DROPDOWN_ID');

// https://github.com/sindresorhus/element-ready
// click the button
// assert if on and do night mode logic
// there is a JWT in local storage USER that could also be read from
// if we want more progmattic logic checking rather than clicks

// userDropDownNode.click();
})();
import elementReady from 'element-ready';
import browser from 'webextension-polyfill';
import { NightBrowserMessage } from './types';

console.log('content loaded');

async function toggleReddit(isNight: boolean) {
const dropdown = await elementReady('#USER_DROPDOWN_ID');
if (dropdown) {
dropdown.click();
const menu = await elementReady('[role="menu"]');
const menuItems = menu?.children[0].children ? Array.from(menu?.children[0].children) : [];

if (menuItems.length) {
const viewOptionsHeader = menuItems.filter((e) => e.textContent === 'View Options')[0];
if (viewOptionsHeader) {
const darkModeContainer = viewOptionsHeader.nextElementSibling as HTMLElement;
const darkModeSwitch = darkModeContainer.querySelector(
'[role="switch"]',
) as HTMLElement;

// No switch if the user is not logged in
if (!darkModeSwitch) {
dropdown.click();
}

const isRedditDarkModeEnabled =
darkModeSwitch?.getAttribute('aria-checked') === 'true';

// TODO: This is a hacky way to toggle the switch, but it works for now
if (
(isNight && !isRedditDarkModeEnabled) ||
(!isNight && isRedditDarkModeEnabled)
) {
darkModeSwitch.click();
dropdown.click();
} else {
dropdown.click();
}
} else {
// User isn't logged in, close the dropdown
dropdown.click();
}
}
}
}

browser.runtime.onMessage.addListener((request: NightBrowserMessage) => {
if (request.type === 'redditIsNight' && request.isUserEnabled) {
toggleReddit(request.value);
}
});
2 changes: 0 additions & 2 deletions src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@ declare module '*.svg' {
const content: any;
export default content;
}

declare var browser: any;
Loading

0 comments on commit 53b1b65

Please sign in to comment.