diff --git a/README.md b/README.md index eb77f2b1..ce7c1a23 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Snort +## Snort Snort is a nostr UI built with React, Snort intends to be fast and effecient @@ -13,7 +13,7 @@ Snort supports the following NIP's - [x] NIP-08: Handling Mentions - [x] NIP-09: Event Deletion - [x] NIP-10: Conventions for clients' use of `e` and `p` tags in text events -- [x] NIP-11: Relay Information Document +- [ ] NIP-11: Relay Information Document - [x] NIP-12: Generic Tag Queries - [ ] NIP-13: Proof of Work - [ ] NIP-14: Subject tag in text events diff --git a/src/Const.ts b/src/Const.ts index 3a1d20d3..bcea7a8b 100644 --- a/src/Const.ts +++ b/src/Const.ts @@ -1,10 +1,5 @@ import { RelaySettings } from "Nostr/Connection"; -/** - * Add-on api for snort features - */ -export const ApiHost = "https://api.snort.social"; - /** * Websocket re-connect timeout */ @@ -98,4 +93,5 @@ export const TidalRegex = /tidal\.com\/(?:browse\/)?(\w+)\/([a-z0-9-]+)/i; /** * SoundCloud regex */ + export const SoundCloudRegex = /soundcloud\.com\/(?!live)([a-zA-Z0-9]+)\/([a-zA-Z0-9-]+)/ diff --git a/src/Element/Nip05.tsx b/src/Element/Nip05.tsx index d68332e2..eef8941d 100644 --- a/src/Element/Nip05.tsx +++ b/src/Element/Nip05.tsx @@ -57,7 +57,7 @@ const Nip05 = (props: Nip05Params) => { const { isVerified, couldNotVerify } = useIsVerified(props.pubkey, props.nip05) return ( -
+
ev.stopPropagation()}> {!isDefaultUser && (
{name} diff --git a/src/Element/Nip5Service.tsx b/src/Element/Nip5Service.tsx index d1b32a1f..82765c92 100644 --- a/src/Element/Nip5Service.tsx +++ b/src/Element/Nip5Service.tsx @@ -15,7 +15,7 @@ import LNURLTip from "Element/LNURLTip"; import Copy from "Element/Copy"; import useProfile from "Feed/ProfileFeed"; import useEventPublisher from "Feed/EventPublisher"; -import { debounce, hexToBech32 } from "Util"; +import { hexToBech32 } from "Util"; import { UserMetadata } from "Nostr"; type Nip05ServiceProps = { @@ -33,7 +33,7 @@ export default function Nip5Service(props: Nip05ServiceProps) { const pubkey = useSelector(s => s.login.publicKey); const user = useProfile(pubkey); const publisher = useEventPublisher(); - const svc = useMemo(() => new ServiceProvider(props.service), [props.service]); + const svc = new ServiceProvider(props.service); const [serviceConfig, setServiceConfig] = useState(); const [error, setError] = useState(); const [handle, setHandle] = useState(""); @@ -43,7 +43,7 @@ export default function Nip5Service(props: Nip05ServiceProps) { const [showInvoice, setShowInvoice] = useState(false); const [registerStatus, setRegisterStatus] = useState(); - const domainConfig = useMemo(() => serviceConfig?.domains.find(a => a.name === domain), [domain, serviceConfig]); + const domainConfig = useMemo(() => serviceConfig?.domains.find(a => a.name === domain), [domain]); useEffect(() => { svc.GetConfig() @@ -58,7 +58,7 @@ export default function Nip5Service(props: Nip05ServiceProps) { } }) .catch(console.error) - }, [props, svc]); + }, [props]); useEffect(() => { setError(undefined); @@ -77,7 +77,7 @@ export default function Nip5Service(props: Nip05ServiceProps) { setAvailabilityResponse({ available: false, why: "REGEX" }); return; } - return debounce(500, () => { + let t = setTimeout(() => { svc.CheckAvailable(handle, domain) .then(a => { if ('error' in a) { @@ -87,9 +87,10 @@ export default function Nip5Service(props: Nip05ServiceProps) { } }) .catch(console.error); - }); + }, 500); + return () => clearTimeout(t); } - }, [handle, domain, domainConfig, svc]); + }, [handle, domain]); useEffect(() => { if (registerResponse && showInvoice) { @@ -111,7 +112,7 @@ export default function Nip5Service(props: Nip05ServiceProps) { }, 2_000); return () => clearInterval(t); } - }, [registerResponse, showInvoice, svc]) + }, [registerResponse, showInvoice]) function mapError(e: ServiceErrorCode, t: string | null): string | undefined { let whyMap = new Map([ @@ -159,7 +160,7 @@ export default function Nip5Service(props: Nip05ServiceProps) {

Find out more info about {props.name} at {props.link}

{error && {error.error}} {!registerStatus &&
- setHandle(e.target.value.toLowerCase())} /> + setHandle(e.target.value)} />  @  dispatch(setPreferences({ ...perf, theme: e.target.value} as UserPreferences))}> - + @@ -34,8 +34,8 @@ const PreferencesPage = () => {
-
Enable reactions
- Reactions will be shown on every page, if disabled no reactions will be shown +
Message reaction options
+ When the box is checked, you can like and repost, but when it's unchecked, you can't
dispatch(setPreferences({ ...perf, enableReactions: e.target.checked }))} /> diff --git a/src/Pages/settings/Profile.tsx b/src/Pages/settings/Profile.tsx index 482340da..1fb60b2d 100644 --- a/src/Pages/settings/Profile.tsx +++ b/src/Pages/settings/Profile.tsx @@ -31,6 +31,7 @@ export default function ProfileSettings() { const [about, setAbout] = useState(); const [website, setWebsite] = useState(); const [nip05, setNip05] = useState(); + const [lud06, setLud06] = useState(); const [lud16, setLud16] = useState(); const avatarPicture = (picture?.length ?? 0) === 0 ? Nostrich : picture @@ -44,6 +45,7 @@ export default function ProfileSettings() { setAbout(user.about); setWebsite(user.website); setNip05(user.nip05); + setLud06(user.lud06); setLud16(user.lud16); } }, [user]); @@ -101,7 +103,7 @@ export default function ProfileSettings() { return (
-
Name:
+
Username:
setName(e.target.value)} />
@@ -131,7 +133,7 @@ export default function ProfileSettings() {
navigate("/verification")}>   - Buy + Buy NIP-05
diff --git a/src/Pages/settings/RelayInfo.tsx b/src/Pages/settings/RelayInfo.tsx deleted file mode 100644 index 2dd6aa7b..00000000 --- a/src/Pages/settings/RelayInfo.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import ProfilePreview from "Element/ProfilePreview"; -import useRelayState from "Feed/RelayState"; -import { System } from "Nostr/System"; -import { useDispatch } from "react-redux"; -import { useNavigate, useParams } from "react-router-dom"; -import { removeRelay } from "State/Login"; -import { parseId } from "Util"; - -const RelayInfo = () => { - const params = useParams(); - const navigate = useNavigate(); - const dispatch = useDispatch(); - const addr: string = `wss://${params.addr}`; - - const con = System.Sockets.get(addr) ?? System.Sockets.get(`${addr}/`); - const stats = useRelayState(con?.Address ?? addr); - - return ( - <> -

navigate("/settings/relays")}>Relays

-
-

{stats?.info?.name ?? addr}

-

{stats?.info?.description}

- - {stats?.info?.pubkey && (<> -

Owner

- - )} - {stats?.info?.software && (
-

Software

-
- {stats.info.software.startsWith("http") ? {stats.info.software} : <>{stats.info.software}} - {!stats.info.version?.startsWith("v") && "v"}{stats.info.version} -
-
)} - {stats?.info?.contact && (
-

Contact

- {stats.info.contact} -
)} - {stats?.info?.supported_nips && (<> -

Supports

-
- {stats.info.supported_nips.map(a => navigate(`https://github.com/nostr-protocol/nips/blob/master/${a.toString().padStart(2, "0")}.md`)}>NIP-{a.toString().padStart(2, "0")})} -
- )} -
-
{ - dispatch(removeRelay(con!.Address)); - navigate("/settings/relays") - }}>Remove
-
-
- - ) -} - -export default RelayInfo; \ No newline at end of file diff --git a/src/Pages/settings/Relays.tsx b/src/Pages/settings/Relays.tsx index b5e2d241..3ca0fca4 100644 --- a/src/Pages/settings/Relays.tsx +++ b/src/Pages/settings/Relays.tsx @@ -52,7 +52,7 @@ const RelaySettingsPage = () => {
{Object.keys(relays || {}).map(a => )}
-
+
saveRelays()}>Save
diff --git a/src/State/Login.ts b/src/State/Login.ts index ca009db4..23c0a4b6 100644 --- a/src/State/Login.ts +++ b/src/State/Login.ts @@ -1,8 +1,9 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit' import * as secp from '@noble/secp256k1'; import { DefaultRelays } from 'Const'; -import { HexKey, TaggedRawEvent } from 'Nostr'; +import { HexKey, RawEvent, TaggedRawEvent } from 'Nostr'; import { RelaySettings } from 'Nostr/Connection'; +import { useDispatch } from 'react-redux'; const PrivateKeyItem = "secret"; const PublicKeyItem = "pubkey"; @@ -181,7 +182,7 @@ const LoginSlice = createSlice({ let filtered = new Map(); for (let [k, v] of Object.entries(relays)) { if (k.startsWith("wss://") || k.startsWith("ws://")) { - filtered.set(k, v as RelaySettings); + filtered.set(k, v); } } diff --git a/src/Util.ts b/src/Util.ts index abd73dde..68cc7e49 100644 --- a/src/Util.ts +++ b/src/Util.ts @@ -1,6 +1,6 @@ import * as secp from "@noble/secp256k1"; import { bech32 } from "bech32"; -import { HexKey, TaggedRawEvent, u256 } from "Nostr"; +import { HexKey, RawEvent, TaggedRawEvent, u256 } from "Nostr"; import EventKind from "Nostr/EventKind"; export async function openFile(): Promise { @@ -65,7 +65,7 @@ export function eventLink(hex: u256) { * @param {string} hex */ export function hexToBech32(hrp: string, hex: string) { - if (typeof hex !== "string" || hex.length === 0 || hex.length % 2 !== 0) { + if (typeof hex !== "string" || hex.length === 0 || hex.length % 2 != 0) { return ""; } @@ -145,15 +145,4 @@ export function extractLnAddress(lnurl: string) { export function unixNow() { return Math.floor(new Date().getTime() / 1000); -} - -/** - * Simple debounce - * @param timeout Time until falling edge - * @param fn Callack to run on falling edge - * @returns Cancel timeout function - */ -export function debounce(timeout: number, fn: () => void) { - let t = setTimeout(fn, timeout); - return () => clearTimeout(t); -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index 8556f0db..05296df4 100644 --- a/src/index.css +++ b/src/index.css @@ -222,18 +222,18 @@ textarea:placeholder { align-items: flex-start !important; } -.f-end { - justify-content: flex-end; -} - .w-max { width: 100%; - width: stretch; + width: -moz-available; + width: -webkit-fill-available; + width: fill-available; } .w-max-w { max-width: 100%; - max-width: stretch; + max-width: -moz-available; + max-width: -webkit-fill-available; + max-width: fill-available; } a { @@ -263,7 +263,7 @@ div.form-group>div:nth-child(1) { div.form-group>div:nth-child(2) { display: flex; flex-grow: 1; - justify-content: flex-end; + justify-content: end; } div.form-group>div:nth-child(2) input { @@ -296,10 +296,6 @@ body.scroll-lock { height: 100vh; } -.pointer { - cursor: pointer; -} - .m5 { margin: 5px; }