chore: format and lint
This commit is contained in:
@@ -1,42 +1,65 @@
|
||||
import browser from 'webextension-polyfill'
|
||||
import React, {useState, useCallback, useEffect} from 'react'
|
||||
import {render} from 'react-dom'
|
||||
import {generatePrivateKey, nip19} from 'nostr-tools'
|
||||
import { useState, useCallback, useEffect } from 'react'
|
||||
import { render } from 'react-dom'
|
||||
import { generateSecretKey, nip19, utils } from 'nostr-tools'
|
||||
import QRCode from 'react-qr-code'
|
||||
import * as Tabs from '@radix-ui/react-tabs'
|
||||
import {LogoIcon} from './icons'
|
||||
import {removePermissions} from './common'
|
||||
import { LogoIcon } from './icons'
|
||||
import { removePermissions } from './common'
|
||||
import * as Checkbox from '@radix-ui/react-checkbox'
|
||||
|
||||
function Options() {
|
||||
let [privKey, setPrivKey] = useState('')
|
||||
let [relays, setRelays] = useState([])
|
||||
let [newRelayURL, setNewRelayURL] = useState('')
|
||||
let [policies, setPermissions] = useState([])
|
||||
let [protocolHandler, setProtocolHandler] = useState('https://njump.me/{raw}')
|
||||
let [hidingPrivateKey, hidePrivateKey] = useState(true)
|
||||
let [showNotifications, setNotifications] = useState(false)
|
||||
let [messages, setMessages] = useState([])
|
||||
let [handleNostrLinks, setHandleNostrLinks] = useState(false)
|
||||
let [showProtocolHandlerHelp, setShowProtocolHandlerHelp] = useState(false)
|
||||
let [unsavedChanges, setUnsavedChanges] = useState([])
|
||||
const [privKey, setPrivKey] = useState('')
|
||||
const [relays, setRelays] = useState([])
|
||||
const [newRelayURL, setNewRelayURL] = useState('')
|
||||
const [policies, setPermissions] = useState([])
|
||||
const [protocolHandler, setProtocolHandler] = useState(
|
||||
'https://njump.me/{raw}'
|
||||
)
|
||||
const [hidingPrivateKey, hidePrivateKey] = useState(true)
|
||||
const [showNotifications, setNotifications] = useState(false)
|
||||
const [messages, setMessages] = useState([])
|
||||
const [handleNostrLinks, setHandleNostrLinks] = useState(false)
|
||||
const [showProtocolHandlerHelp, setShowProtocolHandlerHelp] = useState(false)
|
||||
const [unsavedChanges, setUnsavedChanges] = useState([])
|
||||
|
||||
const showMessage = useCallback(msg => {
|
||||
const showMessage = useCallback((msg) => {
|
||||
messages.push(msg)
|
||||
setMessages(messages)
|
||||
setTimeout(() => setMessages([]), 3000)
|
||||
})
|
||||
|
||||
const loadPermissions = useCallback(async () => {
|
||||
const { policies = {} } = await browser.storage.local.get('policies')
|
||||
const list = []
|
||||
|
||||
Object.entries(policies).forEach(([host, accepts]) => {
|
||||
Object.entries(accepts).forEach(([accept, types]) => {
|
||||
Object.entries(types).forEach(([type, { conditions, created_at }]) => {
|
||||
list.push({
|
||||
host,
|
||||
type,
|
||||
accept,
|
||||
conditions,
|
||||
created_at
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
setPermissions(list)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
browser.storage.local
|
||||
.get(['private_key', 'relays', 'protocol_handler', 'notifications'])
|
||||
.then(results => {
|
||||
.then((results) => {
|
||||
if (results.private_key) {
|
||||
setPrivKey(nip19.nsecEncode(results.private_key))
|
||||
}
|
||||
if (results.relays) {
|
||||
let relaysList = []
|
||||
for (let url in results.relays) {
|
||||
const relaysList = []
|
||||
for (const url in results.relays) {
|
||||
relaysList.push({
|
||||
url,
|
||||
policy: results.relays[url]
|
||||
@@ -57,28 +80,7 @@ function Options() {
|
||||
|
||||
useEffect(() => {
|
||||
loadPermissions()
|
||||
}, [])
|
||||
|
||||
async function loadPermissions() {
|
||||
let {policies = {}} = await browser.storage.local.get('policies')
|
||||
let list = []
|
||||
|
||||
Object.entries(policies).forEach(([host, accepts]) => {
|
||||
Object.entries(accepts).forEach(([accept, types]) => {
|
||||
Object.entries(types).forEach(([type, {conditions, created_at}]) => {
|
||||
list.push({
|
||||
host,
|
||||
type,
|
||||
accept,
|
||||
conditions,
|
||||
created_at
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
setPermissions(list)
|
||||
}
|
||||
}, [loadPermissions])
|
||||
|
||||
return (
|
||||
<div className="w-screen h-screen flex flex-col items-center justify-center">
|
||||
@@ -178,8 +180,8 @@ function Options() {
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="font-semibold text-base">Preferred Relays:</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
{relays.map(({url, policy}, i) => (
|
||||
<div key={i} className="flex items-center gap-4">
|
||||
{relays.map(({ url, policy }, i) => (
|
||||
<div key={url} className="flex items-center gap-4">
|
||||
<input
|
||||
value={url}
|
||||
onChange={changeRelayURL.bind(null, i)}
|
||||
@@ -205,6 +207,7 @@ function Options() {
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
@@ -240,6 +243,7 @@ function Options() {
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
@@ -258,6 +262,7 @@ function Options() {
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={removeRelay.bind(null, i)}
|
||||
className="shrink-0 px-3 w-24 h-9 font-semibold border border-primary shadow-sm rounded-lg inline-flex items-center justify-center disabled:text-muted"
|
||||
>
|
||||
@@ -268,14 +273,15 @@ function Options() {
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
value={newRelayURL}
|
||||
onChange={e => setNewRelayURL(e.target.value)}
|
||||
onKeyDown={e => {
|
||||
onChange={(e) => setNewRelayURL(e.target.value)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') addNewRelay()
|
||||
}}
|
||||
placeholder="wss://"
|
||||
className="flex-1 h-9 bg-transparent border px-3 py-1 border-primary rounded-lg placeholder:text-muted"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
disabled={!newRelayURL}
|
||||
onClick={addNewRelay}
|
||||
className="shrink-0 px-3 w-24 h-9 font-semibold border border-primary shadow-sm rounded-lg inline-flex items-center justify-center disabled:text-muted"
|
||||
@@ -317,7 +323,7 @@ function Options() {
|
||||
</thead>
|
||||
<tbody>
|
||||
{policies.map(
|
||||
({host, type, accept, conditions, created_at}) => (
|
||||
({ host, type, accept, conditions, created_at }) => (
|
||||
<tr
|
||||
key={
|
||||
host + type + accept + JSON.stringify(conditions)
|
||||
@@ -344,6 +350,7 @@ function Options() {
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleRevoke}
|
||||
data-host={host}
|
||||
data-accept={accept}
|
||||
@@ -358,11 +365,11 @@ function Options() {
|
||||
)}
|
||||
{!policies.length && (
|
||||
<tr>
|
||||
{Array(5)
|
||||
.fill('N/A')
|
||||
.map((v, i) => (
|
||||
<td key={i}>{v}</td>
|
||||
))}
|
||||
<td>N/A</td>
|
||||
<td>N/A</td>
|
||||
<td>N/A</td>
|
||||
<td>N/A</td>
|
||||
<td>N/A</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
@@ -387,6 +394,7 @@ function Options() {
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
@@ -413,6 +421,7 @@ function Options() {
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-5 h-5"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
@@ -438,6 +447,7 @@ function Options() {
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-4 h-4"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
@@ -458,7 +468,10 @@ function Options() {
|
||||
onChange={handleChangeProtocolHandler}
|
||||
/>
|
||||
{!showProtocolHandlerHelp && (
|
||||
<button onClick={changeShowProtocolHandlerHelp}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={changeShowProtocolHandlerHelp}
|
||||
>
|
||||
?
|
||||
</button>
|
||||
)}
|
||||
@@ -487,6 +500,7 @@ examples:
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
disabled={!unsavedChanges.length}
|
||||
onClick={saveChanges}
|
||||
className="w-full h-10 bg-primary rounded-xl font-bold inline-flex items-center justify-center text-white disabled:cursor-not-allowed disabled:opacity-70 transform active:translate-y-1 transition-transform ease-in-out duration-75"
|
||||
@@ -498,13 +512,14 @@ examples:
|
||||
)
|
||||
|
||||
async function handleKeyChange(e) {
|
||||
let key = e.target.value.toLowerCase().trim()
|
||||
const key = e.target.value.toLowerCase().trim()
|
||||
setPrivKey(key)
|
||||
addUnsavedChanges('private_key')
|
||||
}
|
||||
|
||||
async function generate() {
|
||||
setPrivKey(nip19.nsecEncode(generatePrivateKey()))
|
||||
const sk = generateSecretKey()
|
||||
setPrivKey(nip19.nsecEncode(utils.bytesToHex(sk)))
|
||||
addUnsavedChanges('private_key')
|
||||
}
|
||||
|
||||
@@ -517,7 +532,7 @@ examples:
|
||||
let hexOrEmptyKey = privKey
|
||||
|
||||
try {
|
||||
let {type, data} = nip19.decode(privKey)
|
||||
const { type, data } = nip19.decode(privKey)
|
||||
if (type === 'nsec') hexOrEmptyKey = data
|
||||
} catch (_) {}
|
||||
|
||||
@@ -544,7 +559,7 @@ examples:
|
||||
function changeRelayURL(i, ev) {
|
||||
setRelays([
|
||||
...relays.slice(0, i),
|
||||
{url: ev.target.value, policy: relays[i].policy},
|
||||
{ url: ev.target.value, policy: relays[i].policy },
|
||||
...relays.slice(i + 1)
|
||||
])
|
||||
addUnsavedChanges('relays')
|
||||
@@ -555,7 +570,7 @@ examples:
|
||||
...relays.slice(0, i),
|
||||
{
|
||||
url: relays[i].url,
|
||||
policy: {...relays[i].policy, [cat]: !relays[i].policy[cat]}
|
||||
policy: { ...relays[i].policy, [cat]: !relays[i].policy[cat] }
|
||||
},
|
||||
...relays.slice(i + 1)
|
||||
])
|
||||
@@ -572,7 +587,7 @@ examples:
|
||||
if (!newRelayURL.startsWith('wss://')) return
|
||||
relays.push({
|
||||
url: newRelayURL,
|
||||
policy: {read: true, write: true}
|
||||
policy: { read: true, write: true }
|
||||
})
|
||||
setRelays(relays)
|
||||
addUnsavedChanges('relays')
|
||||
@@ -580,7 +595,7 @@ examples:
|
||||
}
|
||||
|
||||
async function handleRevoke(e) {
|
||||
let {host, accept, type} = e.target.dataset
|
||||
const { host, accept, type } = e.target.dataset
|
||||
if (
|
||||
window.confirm(
|
||||
`revoke all ${
|
||||
@@ -601,14 +616,14 @@ examples:
|
||||
}
|
||||
|
||||
async function requestBrowserNotificationPermissions() {
|
||||
let granted = await browser.permissions.request({
|
||||
const granted = await browser.permissions.request({
|
||||
permissions: ['notifications']
|
||||
})
|
||||
if (!granted) setNotifications(false)
|
||||
}
|
||||
|
||||
async function saveNotifications() {
|
||||
await browser.storage.local.set({notifications: showNotifications})
|
||||
await browser.storage.local.set({ notifications: showNotifications })
|
||||
showMessage('saved notifications!')
|
||||
}
|
||||
|
||||
@@ -616,8 +631,8 @@ examples:
|
||||
await browser.storage.local.set({
|
||||
relays: Object.fromEntries(
|
||||
relays
|
||||
.filter(({url}) => url.trim() !== '')
|
||||
.map(({url, policy}) => [url.trim(), policy])
|
||||
.filter(({ url }) => url.trim() !== '')
|
||||
.map(({ url, policy }) => [url.trim(), policy])
|
||||
)
|
||||
})
|
||||
showMessage('saved relays!')
|
||||
@@ -641,19 +656,19 @@ examples:
|
||||
}
|
||||
|
||||
async function saveNostrProtocolHandlerSettings() {
|
||||
await browser.storage.local.set({protocol_handler: protocolHandler})
|
||||
await browser.storage.local.set({ protocol_handler: protocolHandler })
|
||||
showMessage('saved protocol handler!')
|
||||
}
|
||||
|
||||
function addUnsavedChanges(section) {
|
||||
if (!unsavedChanges.find(s => s === section)) {
|
||||
if (!unsavedChanges.find((s) => s === section)) {
|
||||
unsavedChanges.push(section)
|
||||
setUnsavedChanges(unsavedChanges)
|
||||
}
|
||||
}
|
||||
|
||||
async function saveChanges() {
|
||||
for (let section of unsavedChanges) {
|
||||
for (const section of unsavedChanges) {
|
||||
switch (section) {
|
||||
case 'private_key':
|
||||
await saveKey()
|
||||
|
||||
Reference in New Issue
Block a user