Skip to content

Commit b3f0a34

Browse files
authored
Merge pull request #9 from jqphu/8-create-a-simple-way-to-disable-the-extension
Add a settings button to disable the extension
2 parents 7d7a30f + 0d498a9 commit b3f0a34

File tree

10 files changed

+197
-51
lines changed

10 files changed

+197
-51
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"format": "prettier --write '**/*.{js,jsx,ts,tsx,json,css,scss,md}'"
1010
},
1111
"dependencies": {
12+
"@headlessui/react": "^1.6.6",
1213
"@hot-loader/react-dom": "^17.0.2",
1314
"@metamask/detect-provider": "1.2.0",
1415
"@reduxjs/toolkit": "^1.8.3",
@@ -17,7 +18,7 @@
1718
"ethers": "^5.6.9",
1819
"mixpanel-browser": "^2.45.0",
1920
"pino": "8.1.0",
20-
"pocket-universe-js": "^0.0.1",
21+
"pocket-universe-js": "^0.0.3",
2122
"react": "^17.0.2",
2223
"react-dom": "^17.0.2",
2324
"react-hot-loader": "^4.13.0",

src/assets/img/icon-32-gray.png

1.82 KB
Loading

src/containers/Settings/Settings.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { MdClose } from 'react-icons/md';
2+
import { Switch } from '@headlessui/react';
3+
import { useState, useEffect } from 'react';
4+
import { setSettings, getSettings } from '../../lib/storage';
5+
import React from 'react';
6+
7+
const Settings = ({ closeSettings }: { closeSettings: () => void }) => {
8+
const [enabled, setEnabled] = useState<boolean>(true);
9+
10+
useEffect(() => {
11+
getSettings().then((settings) => setEnabled(!settings.disable));
12+
}, []);
13+
14+
const switchedCallback = async (enabled: boolean) => {
15+
await setSettings({ disable: !enabled });
16+
setEnabled(enabled);
17+
};
18+
19+
return (
20+
<div className="flex flex-col">
21+
<div className="flex flex-col grow">
22+
<div className="flex flex-row border-t border-gray-600 py-4">
23+
<div className="text-xl font-bold text-gray-100 px-4">Settings</div>
24+
<button
25+
onClick={closeSettings}
26+
className="text-2xl font-bold text-gray-400 ml-auto my-auto text-right mr-3 p-1 hover:bg-gray-600 hover:rounded-full"
27+
>
28+
<MdClose />
29+
</button>
30+
</div>
31+
<div className="flex flex-col gap-4 px-4 pt-4 w-full">
32+
<div className="flex flex-row w-full">
33+
<div className="text-lg text-gray-100 my-auto">Run Simulations</div>
34+
<Switch
35+
checked={enabled}
36+
onChange={switchedCallback}
37+
className={`${enabled ? 'bg-blue-400' : 'bg-teal-700'}
38+
my-auto ml-auto relative inline-flex h-6 w-12 shrink-0 cursor-pointer rounded-full items-center border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75`}
39+
>
40+
<span className="sr-only">Use setting</span>
41+
<span
42+
aria-hidden="true"
43+
className={`${enabled ? 'translate-x-6' : 'translate-x-0'}
44+
pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out`}
45+
/>
46+
</Switch>
47+
</div>
48+
</div>
49+
</div>
50+
<div>
51+
<img className="mt-auto w-screen" src="waves_bottom.png" alt="" />
52+
</div>
53+
</div>
54+
);
55+
};
56+
57+
export default Settings;

src/lib/settings.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export let settings = {
2+
disable: false,
3+
};
4+
5+
const DISPATCH_SETTINGS = 'POCKET_UNIVERSE_DISPATCH_SETTINGS';
6+
7+
/**
8+
* Dispatch from ContentScript to InjectedScript the new settings.
9+
*/
10+
export const dispatchSettings = (settings: any) => {
11+
document.dispatchEvent(
12+
new CustomEvent(DISPATCH_SETTINGS, {
13+
detail: settings,
14+
})
15+
);
16+
};
17+
18+
/**
19+
* Listen to updates in settings.
20+
*/
21+
export const listenForSettingsUpdates = () => {
22+
document.addEventListener(DISPATCH_SETTINGS, (event: any) => {
23+
settings = event.detail;
24+
});
25+
};

src/lib/storage.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,57 @@ export const clearOldSimulations = async () => {
176176
return chrome.storage.sync.set({ simulations });
177177
};
178178

179+
export const SETTINGS_KEY = 'settings';
180+
181+
export interface Settings {
182+
/**
183+
* Whether or not we should disable the extension.
184+
*/
185+
disable: boolean;
186+
}
187+
188+
const updateIcon = (settings: Settings) => {
189+
if (settings.disable) {
190+
chrome.action.setIcon({ path: 'icon-32-gray.png' });
191+
} else {
192+
chrome.action.setIcon({ path: 'icon-32.png' });
193+
}
194+
};
195+
196+
/**
197+
* Set the settings to the given args.
198+
*/
199+
export const setSettings = async (args: Settings) => {
200+
// Default is enabled.
201+
let { settings = { disable: false } } = await chrome.storage.sync.get(
202+
SETTINGS_KEY
203+
);
204+
log.info({ settings: settings, msg: 'Updating settings' });
205+
206+
settings.disable = args.disable;
207+
208+
updateIcon(settings);
209+
210+
return chrome.storage.sync.set({ settings });
211+
};
212+
213+
/**
214+
* Get the settings.
215+
*/
216+
export const getSettings = async (): Promise<Settings> => {
217+
const { settings = { disable: false } } = await chrome.storage.sync.get(
218+
SETTINGS_KEY
219+
);
220+
log.info({ settings: settings, msg: 'Getting settings.' });
221+
222+
return settings as Settings;
223+
};
224+
225+
/**
226+
* Get the initial set of settings for the icon.
227+
*/
228+
getSettings().then(updateIcon);
229+
179230
export const simulationNeedsAction = (
180231
state: StoredSimulationState
181232
): boolean => {

src/pages/Content/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import {
66
SIMULATE_REQUEST_COMMAND,
77
SimulateResponse,
88
} from '../../lib/simulate_request_reply';
9+
import { dispatchSettings } from '../../lib/settings';
910
import type { StoredSimulation } from '../../lib/storage';
1011
import { removeSimulation, StoredSimulationState } from '../../lib/storage';
1112

1213
const log = logger.child({ component: 'Content-Script' });
13-
console.log('Content Script Loaded');
14+
15+
log.debug({ msg: 'Content Script Loaded' });
1416

1517
// There is a bit of a memory leak here. If the user navigates away from this page before the request is sent in, the request will never be removed from storage.
1618
// There shouldn't be too many requests though so this is okay.
@@ -27,6 +29,12 @@ const maybeRemoveId = (id: string) => {
2729
}
2830
};
2931

32+
chrome.storage.onChanged.addListener((changes, area) => {
33+
if (area === 'sync' && changes.settings?.newValue) {
34+
dispatchSettings(changes.settings.newValue);
35+
}
36+
});
37+
3038
listenToSimulateRequest((simulateRequest: SimulateRequestArgs) => {
3139
log.info({ simulateRequest }, 'SimulateRequest');
3240
ids.push(simulateRequest.id);

src/pages/Injected/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
RequestManager,
44
SimulateResponse,
55
} from '../../lib/simulate_request_reply';
6+
import { settings, listenForSettingsUpdates } from '../../lib/settings';
67

78
declare global {
89
interface Window {
@@ -11,9 +12,11 @@ declare global {
1112
}
1213

1314
const log = logger.child({ component: 'Injected' });
15+
log.debug({ msg: 'Injected script loaded.' });
1416

1517
/// Handling all the request communication.
1618
const REQUEST_MANAGER = new RequestManager();
19+
listenForSettingsUpdates();
1720

1821
let cachedProxy: any;
1922

@@ -26,6 +29,12 @@ let providerChanged = true;
2629
const pocketUniverseProxyHandler = {
2730
get(target: any, prop: any, receiver: any) {
2831
log.debug({ prop, msg: 'Props' });
32+
/*
33+
* User has disabled PU, just reflect.
34+
*/
35+
if (settings.disable) {
36+
return Reflect.get(target, prop, receiver);
37+
}
2938

3039
if (prop === 'providers') {
3140
return null;

src/pages/Popup/Popup.tsx

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import mixpanel from 'mixpanel-browser';
2-
import React, { useEffect } from 'react';
2+
import { AiFillSetting } from 'react-icons/ai';
3+
import React, { useEffect, useState } from 'react';
34

45
import Transaction from '../../containers/Transaction/Transaction';
6+
import Settings from '../../containers/Settings/Settings';
57

68
mixpanel.init('00d3b8bc7c620587ecb1439557401a87');
79

810
const Popup = () => {
11+
const [settingsOpen, setSettingsOpen] = useState(false);
12+
913
useEffect(() => {
1014
document.title = 'Pocket Universe';
1115
chrome.storage.sync.get('first_open', (result) => {
@@ -17,15 +21,28 @@ const Popup = () => {
1721
}, []);
1822

1923
return (
20-
<div className="flex flex-col text-white bg-gray-900 overflow-hidden min-w-[360px] min-h-screen items-center">
21-
<div className="flex flex-row p-5 text-center">
22-
<h3 className="flex flex-row gap-4 text-xl leading-6 font-medium text-purple-300">
24+
<div className="flex flex-col text-white bg-gray-900 overflow-hidden min-w-[360px] min-h-screen items-center ">
25+
<div className="flex flex-row p-4 text-center w-full">
26+
<button
27+
onClick={() => setSettingsOpen(false)}
28+
className="flex flex-row gap-4 text-xl leading-6 font-medium text-purple-300 hover:bg-gray-600 rounded-lg"
29+
>
2330
<img src="icon-128.png" className="h-10 my-auto" alt="logo" />
2431
<div className="font-light text-xl my-auto">Pocket Universe</div>
25-
</h3>
32+
</button>
33+
<button
34+
className="flex ml-auto my-auto hover:bg-gray-600 hover:rounded-full text-gray-200 text-xl w-7 h-7 justify-center items-center"
35+
onClick={() => setSettingsOpen(true)}
36+
>
37+
<AiFillSetting />
38+
</button>
2639
</div>
2740
<div className="flex grow">
28-
<Transaction />
41+
{settingsOpen ? (
42+
<Settings closeSettings={() => setSettingsOpen(false)} />
43+
) : (
44+
<Transaction />
45+
)}
2946
</div>
3047
</div>
3148
);

webpack.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,16 @@ var options = {
223223
},
224224
],
225225
}),
226+
new CopyWebpackPlugin({
227+
patterns: [
228+
{
229+
from: 'src/assets/img/icon-32-gray.png',
230+
to: path.join(__dirname, 'build'),
231+
force: true,
232+
},
233+
],
234+
}),
235+
226236
new HtmlWebpackPlugin({
227237
template: path.join(__dirname, 'src', 'pages', 'Popup', 'index.html'),
228238
filename: 'popup.html',

yarn.lock

Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,11 @@
13961396
"@ethersproject/properties" "^5.6.0"
13971397
"@ethersproject/strings" "^5.6.1"
13981398

1399+
"@headlessui/react@^1.6.6":
1400+
version "1.6.6"
1401+
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.6.6.tgz#3073c066b85535c9d28783da0a4d9288b5354d0c"
1402+
integrity sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q==
1403+
13991404
"@hot-loader/react-dom@^17.0.2":
14001405
version "17.0.2"
14011406
resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-17.0.2.tgz#0b24e484093e8f97eb5c72bebdda44fc20bc8400"
@@ -1716,14 +1721,6 @@
17161721
resolved "https://registry.yarnpkg.com/@types/mixpanel-browser/-/mixpanel-browser-2.38.0.tgz#b3e28e1ba06c10a9f88510b88f1ac9d1b2adfc42"
17171722
integrity sha512-TR8rvsILnqXA7oiiGOxuMGXwvDeCoQDonXJB5UR+TYvEAFpiK8ReFj5LhZT+Xhm3NpI9aPoju30jB2ssorSUww==
17181723

1719-
"@types/node-fetch@^2.6.2":
1720-
version "2.6.2"
1721-
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da"
1722-
integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==
1723-
dependencies:
1724-
"@types/node" "*"
1725-
form-data "^3.0.0"
1726-
17271724
"@types/node@*":
17281725
version "18.6.1"
17291726
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.1.tgz#828e4785ccca13f44e2fb6852ae0ef11e3e20ba5"
@@ -2364,14 +2361,6 @@ axe-core@^4.4.3:
23642361
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f"
23652362
integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==
23662363

2367-
axios@^0.27.2:
2368-
version "0.27.2"
2369-
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
2370-
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
2371-
dependencies:
2372-
follow-redirects "^1.14.9"
2373-
form-data "^4.0.0"
2374-
23752364
axobject-query@^2.2.0:
23762365
version "2.2.0"
23772366
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
@@ -2755,7 +2744,7 @@ colorette@^2.0.10, colorette@^2.0.14:
27552744
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
27562745
integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
27572746

2758-
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
2747+
combined-stream@^1.0.6, combined-stream@~1.0.6:
27592748
version "1.0.8"
27602749
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
27612750
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
@@ -3815,7 +3804,7 @@ flatted@^3.1.0:
38153804
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2"
38163805
integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
38173806

3818-
follow-redirects@^1.0.0, follow-redirects@^1.14.9:
3807+
follow-redirects@^1.0.0:
38193808
version "1.15.1"
38203809
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
38213810
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
@@ -3825,24 +3814,6 @@ forever-agent@~0.6.1:
38253814
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
38263815
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
38273816

3828-
form-data@^3.0.0:
3829-
version "3.0.1"
3830-
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
3831-
integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
3832-
dependencies:
3833-
asynckit "^0.4.0"
3834-
combined-stream "^1.0.8"
3835-
mime-types "^2.1.12"
3836-
3837-
form-data@^4.0.0:
3838-
version "4.0.0"
3839-
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
3840-
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
3841-
dependencies:
3842-
asynckit "^0.4.0"
3843-
combined-stream "^1.0.8"
3844-
mime-types "^2.1.12"
3845-
38463817
form-data@~2.3.2:
38473818
version "2.3.3"
38483819
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
@@ -5579,13 +5550,10 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0:
55795550
dependencies:
55805551
find-up "^4.0.0"
55815552

5582-
pocket-universe-js@^0.0.1:
5583-
version "0.0.1"
5584-
resolved "https://registry.yarnpkg.com/pocket-universe-js/-/pocket-universe-js-0.0.1.tgz#0a7fed5d1a8c48c450815f3432e20384ed4b7430"
5585-
integrity sha512-8wc2wk4mPBYE3xfQST0n35hQrbB448TDR52m06O6w/vew7BexKuTvOZafeQG5WAHHCnxQs2vhUpuh5SPMazu1g==
5586-
dependencies:
5587-
"@types/node-fetch" "^2.6.2"
5588-
axios "^0.27.2"
5553+
pocket-universe-js@^0.0.3:
5554+
version "0.0.3"
5555+
resolved "https://registry.yarnpkg.com/pocket-universe-js/-/pocket-universe-js-0.0.3.tgz#1c104d62a650662ba6be9271328659fca847fba0"
5556+
integrity sha512-+0RiMGvyq3LDxqWyF+QYbonw/StgS6yCMaWsa18XfJik0qyBw8icLqQ7ANeBuctY2g5/Gah+AaBZMjRKaemEew==
55895557

55905558
postcss-import@^14.1.0:
55915559
version "14.1.0"

0 commit comments

Comments
 (0)