Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Sum Xu committed Jan 18, 2021
0 parents commit 34b837a
Show file tree
Hide file tree
Showing 20 changed files with 1,978 additions and 0 deletions.
34 changes: 34 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module.exports = {
extends: 'eslint:recommended',
env: {
browser: true,
es2020: true,
},
globals: {
chrome: 'readonly', // for Chrome plugin
},
reportUnusedDisableDirectives: true,
ignorePatterns: ['build/', 'node_modules/'],
root: true,
rules: {
'indent': ['error', 2],
'keyword-spacing': 2,
'no-unused-vars': 'warn',
'quote-props': ['error', 'consistent-as-needed'],
'semi': 'warn',
'no-undef': 'error',
'no-global-assign': 'error',
'quotes': ['warn', 'single', { avoidEscape: true }],
'comma-dangle': ['error', 'only-multiline'],
'eqeqeq': ['error', 'always'],
'no-unused-expressions': [
'warn',
{
allowTaggedTemplates: true,
allowTernary: true,
allowShortCircuit: true,
},
],
'no-console': 0,
},
};
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"singleQuote": true,
"quoteProps": "consistent",
"bracketSpacing": true,
"printWidth": 108
}
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Dopamine Detox (Chrome Extension)

### TODO

- (style) alternative page should look better
- (feat) only disable for 12 hour
- (feat) let user add a message at tab page
- (feat) custom limit for each site

### Done

- (feat) add more hurdle if user want to deactivate

### Closed

- (feat) https://developer.chrome.com/extensions/external_extensions
100 changes: 100 additions & 0 deletions background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// const urls = ['netflix.com', 'youtube.com'];
// const goodUrls = ['brilliant.org', 'frontendmasters.com', 'hackerrank.com'];
const urls = [];
const goodUrls = [];

const INITIAL_STATE = {
urls,
userMsg: '',
timeOption: { isAllDay: true, startTime: 32400000, endTime: 79200000 },
goodUrls,
disabledTime: null,
};

chrome.runtime.onInstalled.addListener(function () {
chrome.storage.sync.set(INITIAL_STATE, function () {
console.log('the urls has been initialized as', urls);
});
});

chrome.tabs.onUpdated.addListener(async function (tabId, changeInfo, tab) {
console.log('-----');
console.log('tabs.onUpdated changeInfo', changeInfo);
// console.log('tabs.onUpdated tabId', tabId);
// console.log('tabs.onUpdated tab', tab);
console.log('tabs.onUpdated tab.url', tab.url);

const curUrl = tab.url;
if (!curUrl || curUrl === 'chrome://newtab/' || changeInfo.status !== 'loading') return;

if (await checkIsExtensionDisabled()) return;

if (!(await checkTimeInRange())) return;

chrome.storage.sync.get('urls', (data) => {
const { urls } = data;

console.log('urls to check match', urls);

console.log('curUrl', curUrl);

if (urls && urls.find((u) => new RegExp(u).test(curUrl))) {
console.log('matched', curUrl);

chrome.permissions.contains(
{
permissions: ['tabs'],
origins: [curUrl],
},
function (result) {
if (result) {
chrome.tabs.create({ url: chrome.runtime.getURL('./alternativePage/index.html') });
chrome.tabs.remove(tabId);
// chrome.tabs.executeScript({
// file: 'contents/index.js',
// });
} else {
// The extension doesn't have the permissions.
alert(`Permission not granded for ${new URL(curUrl).host}. Please add it in Options page.`);
}
}
);
}
});
});

function checkTimeInRange() {
return new Promise((resolve) => {
chrome.storage.sync.get('timeOption', (data) => {
const { timeOption } = data;
const { isAllDay, startTime, endTime } = timeOption;
if (isAllDay) resolve(true);

const rightNow = getCurrentTimeInMs();
console.log({ rightNow, startTime, endTime });
resolve(rightNow >= startTime && rightNow <= endTime);
});
});
}

function checkIsExtensionDisabled() {
return new Promise((resolve) => {
chrome.storage.sync.get('disabledTime', (data) => {
const { disabledTime } = data;

const twelveHourInMilli = 1000 * 60 * 60 * 12;
const now = new Date().getTime();
const withinDisabledPeriod = disabledTime + twelveHourInMilli > now;

console.log('withinDisabledPeriod', withinDisabledPeriod);
resolve(withinDisabledPeriod);
});
});
}

function getCurrentTimeInMs() {
const hourInMs = new Date().getHours() * 60 * 60 * 1000;
const minuteInMs = new Date().getMinutes() * 60 * 1000;

return hourInMs + minuteInMs;
}
55 changes: 55 additions & 0 deletions contents/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
(async function () {
const DEFAULT_MSG = 'If you can be your best version today, why wait for tomorrow.';
function checkUserTempDisable() {
return new Promise((resolve) => {
chrome.storage.sync.get('isTempDisable', (data) => {
const { isTempDisable } = data;
resolve(isTempDisable);
});
});
}
function createInspirationWrap() {
const inspirationWrap = document.createElement('div');
inspirationWrap.style.cssText = `
position: fixed;
display: flex;
flex-direction: column;
justify-content: center;
width: 400px;
height: 300px;
font-family: BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,sans-serif;
background: yellowgreen;
top: 10px;
right: 30px;
border-radius: 5px;
z-index: 100000;
box-shadow: 2px 2px 10px 5px rgba(0, 0, 0, 0.2);
border: 1px solid white;
padding: 1em;
`;
inspirationWrap.classList.add('delayed-gratification-wrap');

const textEl = document.createElement('h1');
textEl.classList.add('delayed-gratification-msg-text');
textEl.style.cssText = `
color: #fff;
font-size: 24px;
text-align: center;
`;
chrome.storage.sync.get('userMsg', (data) => {
const { userMsg } = data;
if (!userMsg) textEl.innerText = DEFAULT_MSG;
else textEl.innerText = userMsg;
});
inspirationWrap.appendChild(textEl);
bodyEl.appendChild(inspirationWrap);
}

const bodyEl = document.querySelector('body');
const inspirationWrap = document.querySelector('.delayed-gratification-wrap');

if (!inspirationWrap && !(await checkUserTempDisable())) {
createInspirationWrap();
return;
}
})();
63 changes: 63 additions & 0 deletions global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
body {
font-family: Verdana, Geneva, Tahoma, sans-serif;
margin: 0;
}
* {
color: #4d4b4b;
}

p {
font-size: 1.4rem;
color: #4d4b4b;
}

label {
color: #4d4b4b;
font-size: 1.2rem;
}

input[type='radio'] {
opacity: 0;
position: fixed;
width: 0;
}

input[type='radio'] + label {
font-size: 1.2rem;
color: #fff;
border-radius: 10px;
width: max-content;
padding: 0.5em 0.8em;
border: 2px #fff solid;
}

input[type='radio']:checked + label {
color: #4d4b4b;
border: 2px #4d4b4b solid;
}

input[type='radio'] + label:hover {
cursor: pointer;
}

button {
font-size: 1.2rem;
color: #4d4b4b;
border-radius: 10px;
width: max-content;
padding: 0.5em 0.8em;
background: #f5f0f0;
border: 2px #fff solid;
}
button:hover {
cursor: pointer;
color: #8b8b8b;
}

input,
textarea {
font-size: 1.2rem;
border-radius: 10px;
border: 2px #fff solid;
margin-bottom: 1.4em;
}
Binary file added images/icon128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/icon16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/icon256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/icon32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/icon48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "Dopamine Detox",
"version": "1.1.0",
"description": "Want to spend less time on some sites? Try this extension.",
"permissions": ["tabs", "storage"],
"optional_permissions": ["http://*/", "https://*/"],
"options_page": "options/index.html",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_popup": "popup/index.html",
"default_icon": {
"256": "images/icon256.png",
"128": "images/icon128.png",
"48": "images/icon48.png",
"32": "images/icon32.png",
"16": "images/icon16.png"
}
},
"icons": {
"256": "images/icon256.png",
"128": "images/icon128.png",
"48": "images/icon48.png",
"32": "images/icon32.png",
"16": "images/icon16.png"
},
"manifest_version": 2
}
69 changes: 69 additions & 0 deletions options/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="../global.css" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main>
<h1>Settings</h1>
<section id="bad-sites">
<h2>Enter the dopamine heavy websites you try to avoid.</h2>
<label for="urlInput">URL:</label>
<input type="text" class="urlInput" />
<div class="urlDisplay"></div>
</section>
<section id="good-sites">
<h2>Enter the websites you think is good for you.</h2>
<label for="urlInput">URL:</label>
<input type="text" class="urlInput" />
<div class="urlDisplay"></div>
</section>
<!-- <section class="message-section">
<h2>Customize your message.</h2>
<textarea
id="userMsg"
name="user-message"
id="userMessage"
cols="30"
rows="10"
placeholder="If you can be your best version today, why wait for tomorrow."
></textarea>
<button id="msgSaveBtn">Save</button>
</section> -->
<section>
<h2>Customize when to take effect in a day.</h2>
<div class="section-body" id="whenToShow">
<div class="radio-group">
<input type="radio" id="allDay" value="allDay" name="whenToShow" />
<label for="allDay">All day</label>
<input type="radio" id="selectedTimeRange" value="selectedTimeRange" name="whenToShow" />
<label for="selectedTimeRange">Time range</label>
</div>
<div class="time-range-setting">
<div class="item">
<label for="startTime">Start time:</label>
<input type="time" id="startTime" name="startTime" />
</div>
<div class="item">
<label for="endTime">End time:</label>
<input type="time" id="endTime" name="endTime" />
</div>
</div>
</div>
</section>
<section>
<h2>Extension activated:</h2>
<div class="section-body" id="togglePlugin">
<div class="radio-group" id="toggleActivationRadioGroup">
<input type="radio" id="activated" name="activated" value="yes" />
<label for="yes">Yes</label>
<input type="radio" id="inactivated" name="inactivated" value="no" />
<label for="no">No</label>
</div>
</div>
</section>
</main>
</body>
<script src="options.js"></script>
</html>
Loading

0 comments on commit 34b837a

Please sign in to comment.