This commit is contained in:
reya
2023-11-20 11:03:30 +07:00
parent 9c9d591b46
commit 8aa1741699
9 changed files with 7609 additions and 1479 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -1,24 +1,15 @@
<!DOCTYPE html> <!DOCTYPE html>
<html>
<meta charset="utf-8" /> <head>
<title>nos2x</title> <meta charset="utf-8" />
<style> <title>nos2x</title>
* { <meta name="viewport" content="width=device-width, initial-scale=1.0" />
font-family: monospace; <link href="output.css" rel="stylesheet" />
} </head>
</style> <body
class="bg-gray-50 dark:bg-gray-950 text-sm font-sans antialiased text-gray-700 dark:text-gray-300"
<div id="main" /> >
<div id="main" />
<script src="options.build.js"></script> <script src="options.build.js"></script>
</body>
<style> </html>
table {
border-collapse: collapse;
}
th,
td {
border: 1px solid;
padding: 1px 2px;
}
</style>

View File

@@ -79,44 +79,48 @@ function Options() {
} }
return ( return (
<> <div className="mt-10 p-8 bg-white dark:bg-black border border-gray-100 dark:border-gray-900 rounded-2xl max-w-xl mx-auto">
<h1 style={{fontSize: '25px', marginBlockEnd: '0px'}}>nos2x</h1> <div className="flex items-center gap-4">
<p style={{marginBlockStart: '0px'}}>nostr signer extension</p> <div className="w-12 h-12 bg-gray-200 dark:bg-gray-800 rounded-xl" />
<h2 style={{marginBlockStart: '20px', marginBlockEnd: '5px'}}>options</h2>
<div
style={{
marginBottom: '10px',
display: 'flex',
flexDirection: 'column',
gap: '10px',
width: 'fit-content'
}}
>
<div> <div>
<div>private key:&nbsp;</div> <h1 className="text-lg font-bold">Nostr Connect</h1>
<div <p className="text-base text-gray-500 font-medium">Nostr signer</p>
style={{ </div>
marginLeft: '10px', </div>
display: 'flex', <div className="mt-4 flex flex-col">
flexDirection: 'column', <div className="mb-6 flex flex-col gap-2">
gap: '10px' <div className="font-semibold text-base">Private key:</div>
}} <div>
> <div className="flex gap-2">
<div style={{display: 'flex', gap: '10px'}}>
<input <input
type={hidingPrivateKey ? 'password' : 'text'} type={hidingPrivateKey ? 'password' : 'text'}
style={{width: '600px'}}
value={privKey} value={privKey}
onChange={handleKeyChange} onChange={handleKeyChange}
className="flex-1 h-9 bg-transparent border px-3 py-1 border-gray-200 dark:border-gray-800 rounded-lg"
/> />
{privKey === '' && <button onClick={generate}>generate</button>} <div className="shrink-0">
{privKey && hidingPrivateKey && ( {!privKey && (
<button onClick={() => hidePrivateKey(false)}>show key</button> <button
)} onClick={generate}
{privKey && !hidingPrivateKey && ( className="px-3 h-9 font-bold border border-gray-200 shadow-sm dark:border-gray-800 rounded-lg inline-flex items-center justify-center"
<button onClick={() => hidePrivateKey(true)}>hide key</button> >
)} Generate
</button>
)}
{privKey && hidingPrivateKey && (
<button onClick={() => hidePrivateKey(false)}>
Show key
</button>
)}
{privKey && !hidingPrivateKey && (
<button onClick={() => hidePrivateKey(true)}>Hide key</button>
)}
</div>
</div> </div>
<p className="text-gray-500 text-sm mt-1">
Your key is stored locally. The developer has no way of seeing
your keys.
</p>
{privKey && !isKeyValid() && ( {privKey && !isKeyValid() && (
<div style={{color: 'red'}}>private key is invalid!</div> <div style={{color: 'red'}}>private key is invalid!</div>
)} )}
@@ -139,63 +143,107 @@ function Options() {
)} )}
</div> </div>
</div> </div>
<div> <div className="mb-4 flex flex-col">
<div>preferred relays:</div> <div className="mb-4 w-full border-b border-gray-100 h-11 flex items-center gap-6">
<div <div className="text-indigo-600 font-medium flex gap-2 items-center h-11 border-b border-indigo-600">
style={{ Relays
marginLeft: '10px', <span className="px-3 h-6 inline-flex items-center justify-center bg-indigo-100 text-indigo-600 rounded-full">
display: 'flex', 10
flexDirection: 'column', </span>
gap: '1px' </div>
}} <div className="text-gray-300 font-medium flex items-center gap-2 h-11">
> Permissions
{relays.map(({url, policy}, i) => ( <span className="px-3 h-6 inline-flex items-center justify-center bg-gray-100 rounded-full">
<div 0
key={i} </span>
style={{display: 'flex', alignItems: 'center', gap: '15px'}} </div>
> </div>
<div className="flex flex-col gap-2">
<div className="font-semibold text-base">Preferred Relays:</div>
<div>
{relays.map(({url, policy}, i) => (
<div
key={i}
style={{display: 'flex', alignItems: 'center', gap: '15px'}}
>
<input
style={{width: '400px'}}
value={url}
onChange={changeRelayURL.bind(null, i)}
/>
<div style={{display: 'flex', gap: '5px'}}>
<label style={{display: 'flex', alignItems: 'center'}}>
read
<input
type="checkbox"
checked={policy.read}
onChange={toggleRelayPolicy.bind(null, i, 'read')}
/>
</label>
<label style={{display: 'flex', alignItems: 'center'}}>
write
<input
type="checkbox"
checked={policy.write}
onChange={toggleRelayPolicy.bind(null, i, 'write')}
/>
</label>
</div>
<button onClick={removeRelay.bind(null, i)}>remove</button>
</div>
))}
<div className="flex gap-2">
<input <input
style={{width: '400px'}} style={{width: '400px'}}
value={url} value={newRelayURL}
onChange={changeRelayURL.bind(null, i)} onChange={e => setNewRelayURL(e.target.value)}
onKeyDown={e => {
if (e.key === 'Enter') addNewRelay()
}}
className="flex-1 h-9 bg-transparent border px-3 py-1 border-gray-200 dark:border-gray-800 rounded-lg"
/> />
<div style={{display: 'flex', gap: '5px'}}> <button
<label style={{display: 'flex', alignItems: 'center'}}> disabled={!newRelayURL}
read onClick={addNewRelay}
<input className="shrink-0 px-3 h-9 font-bold border border-gray-200 shadow-sm dark:border-gray-800 rounded-lg inline-flex items-center justify-center disabled:text-gray-300"
type="checkbox" >
checked={policy.read} Add Relay
onChange={toggleRelayPolicy.bind(null, i, 'read')} </button>
/>
</label>
<label style={{display: 'flex', alignItems: 'center'}}>
write
<input
type="checkbox"
checked={policy.write}
onChange={toggleRelayPolicy.bind(null, i, 'write')}
/>
</label>
</div>
<button onClick={removeRelay.bind(null, i)}>remove</button>
</div> </div>
))}
<div style={{display: 'flex', gap: '10px', marginTop: '5px'}}>
<input
style={{width: '400px'}}
value={newRelayURL}
onChange={e => setNewRelayURL(e.target.value)}
onKeyDown={e => {
if (e.key === 'Enter') addNewRelay()
}}
/>
<button disabled={!newRelayURL} onClick={addNewRelay}>
add relay
</button>
</div> </div>
</div> </div>
</div> </div>
<div> <div className="mb-6">
<label className="flex gap-2 items-center">
<input
type="checkbox"
checked={showNotifications}
onChange={handleNotifications}
className="w-6 h-6 rounded-md border border-gray-200 dark:border-gray-800 appearance-none"
/>
Show desktop notifications when a permissions has been used
</label>
</div>
<div className="mb-4 flex items-center justify-between">
<div className="font-semibold text-base">Advanced</div>
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-5 h-5"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M19.5 8.25l-7.5 7.5-7.5-7.5"
/>
</svg>
</div>
</div>
{/*<div>
<label style={{display: 'flex', alignItems: 'center'}}> <label style={{display: 'flex', alignItems: 'center'}}>
<div> <div>
handle{' '} handle{' '}
@@ -242,29 +290,14 @@ function Options() {
</div> </div>
)} )}
</div> </div>
</div> </div>*/}
<label style={{display: 'flex', alignItems: 'center'}}> {/*<div style={{fontSize: '120%'}}>
show notifications when permissions are used:
<input
type="checkbox"
checked={showNotifications}
onChange={handleNotifications}
/>
</label>
<button
disabled={!unsavedChanges.length}
onClick={saveChanges}
style={{padding: '5px 20px'}}
>
save
</button>
<div style={{fontSize: '120%'}}>
{messages.map((message, i) => ( {messages.map((message, i) => (
<div key={i}>{message}</div> <div key={i}>{message}</div>
))} ))}
</div> </div>*/}
</div> </div>
<div> {/*<div>
<h2>permissions</h2> <h2>permissions</h2>
<table> <table>
<thead> <thead>
@@ -323,8 +356,15 @@ function Options() {
no permissions have been granted yet no permissions have been granted yet
</div> </div>
)} )}
</div> </div>*/}
</> <button
disabled={!unsavedChanges.length}
onClick={saveChanges}
className="w-full h-10 bg-indigo-600 rounded-xl font-bold inline-flex items-center justify-center text-white"
>
Save
</button>
</div>
) )
async function handleKeyChange(e) { async function handleKeyChange(e) {

1001
extension/output.css Normal file

File diff suppressed because it is too large Load Diff

3
extension/style.css Normal file
View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -2,24 +2,27 @@
"license": "WTFPL", "license": "WTFPL",
"dependencies": { "dependencies": {
"async-mutex": "^0.3.2", "async-mutex": "^0.3.2",
"esbuild": "^0.14.11", "esbuild": "^0.14.54",
"eslint": "^8.6.0", "eslint": "^8.54.0",
"eslint-plugin-babel": "^5.3.1", "eslint-plugin-babel": "^5.3.1",
"eslint-plugin-react": "^7.28.0", "eslint-plugin-react": "^7.33.2",
"events": "^3.3.0", "events": "^3.3.0",
"nostr-tools": "^1.12.0", "nostr-tools": "^1.17.0",
"prettier": "^2.5.1", "prettier": "^2.8.8",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-native-svg": "^13.8.0", "react-native-svg": "^13.14.0",
"react-qr-code": "^2.0.11", "react-qr-code": "^2.0.12",
"use-boolean-state": "^1.0.2", "use-boolean-state": "^1.0.2",
"use-debounce": "^7.0.1", "use-debounce": "^7.0.1",
"webextension-polyfill": "^0.8.0" "webextension-polyfill": "^0.8.0"
}, },
"scripts": { "scripts": {
"build": "./build.js prod", "build": "./build.js prod",
"watch": "ag -l --js | entr ./build.js", "watch": "ag -l --js | entr ./build.js; pnpm exec tailwindcss -i ./extension/style.css -o ./extension/output.css --watch",
"package": "./build.js prod; cd extension; zip -r archive *; cd ..; mv extension/archive.zip ./nos2x.zip" "package": "./build.js prod; cd extension; zip -r archive *; cd ..; mv extension/archive.zip ./nos2x.zip"
},
"devDependencies": {
"tailwindcss": "^3.3.5"
} }
} }

6429
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

9
tailwind.config.js Normal file
View File

@@ -0,0 +1,9 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./extension/**/*.{html,js,jsx}'],
theme: {
extend: {},
},
plugins: [],
}

1346
yarn.lock

File diff suppressed because it is too large Load Diff