diff --git a/src/Const.ts b/src/Const.ts index f38614a0..757aa0e4 100644 --- a/src/Const.ts +++ b/src/Const.ts @@ -20,6 +20,11 @@ export const VoidCatHost = "https://void.cat"; */ export const KieranPubKey = "npub1v0lxxxxutpvrelsksy8cdhgfux9l6a42hsj2qzquu2zk7vc9qnkszrqj49"; +/** + * Official snort account + */ +export const SnortPubKey = "npub1sn0rtcjcf543gj4wsg7fa59s700d5ztys5ctj0g69g2x6802npjqhjjtws"; + /** * Websocket re-connect timeout */ diff --git a/src/Pages/DonatePage.tsx b/src/Pages/DonatePage.tsx index 41ed33cf..3ce1751d 100644 --- a/src/Pages/DonatePage.tsx +++ b/src/Pages/DonatePage.tsx @@ -1,4 +1,4 @@ -import { ApiHost, KieranPubKey } from "Const"; +import { ApiHost, KieranPubKey, SnortPubKey } from "Const"; import ProfilePreview from "Element/ProfilePreview"; import ZapButton from "Element/ZapButton"; import { HexKey } from "Nostr"; @@ -72,7 +72,7 @@ const DonatePage = () => {
Lightning Donation:
diff --git a/src/Pages/Layout.tsx b/src/Pages/Layout.tsx index a4bd1c24..dfb40316 100644 --- a/src/Pages/Layout.tsx +++ b/src/Pages/Layout.tsx @@ -7,32 +7,25 @@ import Bell from "Icons/Bell"; import Search from "Icons/Search"; import { RootState } from "State/Store"; -import { init, UserPreferences } from "State/Login"; -import { HexKey, RawEvent, TaggedRawEvent } from "Nostr"; -import { RelaySettings } from "Nostr/Connection"; +import { init, setRelays } from "State/Login"; import { System } from "Nostr/System" import ProfileImage from "Element/ProfileImage"; import useLoginFeed from "Feed/LoginFeed"; import { totalUnread } from "Pages/MessagesPage"; -import { SearchRelays } from 'Const'; +import { SearchRelays, SnortPubKey } from 'Const'; import useEventPublisher from "Feed/EventPublisher"; import useModeration from "Hooks/useModeration"; import { IndexedUDB, useDb } from "State/Users/Db"; import { db } from "Db"; +import { bech32ToHex } from "Util"; export default function Layout() { const dispatch = useDispatch(); const navigate = useNavigate(); - const isInit = useSelector(s => s.login.loggedOut); - const key = useSelector(s => s.login.publicKey); - const relays = useSelector>(s => s.login.relays); - const notifications = useSelector(s => s.login.notifications); - const readNotifications = useSelector(s => s.login.readNotifications); - const dms = useSelector(s => s.login.dms); + const { loggedOut, publicKey, relays, notifications, readNotifications, dms, preferences, newUserKey } = useSelector((s: RootState) => s.login); const { isMuted } = useModeration(); const filteredDms = dms.filter(a => !isMuted(a.pubkey)) - const prefs = useSelector(s => s.login.preferences); const usingDb = useDb(); const pub = useEventPublisher(); useLoginFeed(); @@ -69,15 +62,15 @@ export default function Layout() { useEffect(() => { let osTheme = window.matchMedia("(prefers-color-scheme: light)"); - setTheme(prefs.theme === "system" && osTheme.matches ? "light" : prefs.theme === "light" ? "light" : "dark"); + setTheme(preferences.theme === "system" && osTheme.matches ? "light" : preferences.theme === "light" ? "light" : "dark"); osTheme.onchange = (e) => { - if (prefs.theme === "system") { + if (preferences.theme === "system") { setTheme(e.matches ? "light" : "dark"); } } return () => { osTheme.onchange = null; } - }, [prefs.theme]); + }, [preferences.theme]); useEffect(() => { // check DB support then init @@ -104,6 +97,33 @@ export default function Layout() { }, []); + async function handleNewUser() { + try { + let rsp = await fetch("https://api.nostr.watch/v1/online"); + if (rsp.ok) { + let online: string[] = await rsp.json(); + let pickRandom = online.sort((a, b) => Math.random() >= 0.5 ? 1 : -1).slice(0, 4); // pick 4 random relays + + let relayObjects = pickRandom.map(a => [a, { read: true, write: true }]); + dispatch(setRelays({ + relays: Object.fromEntries(relayObjects), + createdAt: 1 + })); + } + } catch (e) { + console.warn(e); + } + + const ev = await pub.addFollow(bech32ToHex(SnortPubKey)); + pub.broadcast(ev); + } + + useEffect(() => { + if (newUserKey === true) { + handleNewUser().catch(console.warn); + } + }, [newUserKey]); + async function goToNotifications(e: any) { e.stopPropagation(); // request permissions to send notifications @@ -122,7 +142,7 @@ export default function Layout() { function accountHeader() { const unreadNotifications = notifications?.filter(a => (a.created_at * 1000) > readNotifications).length; - const unreadDms = key ? totalUnread(filteredDms, key) : 0; + const unreadDms = publicKey ? totalUnread(filteredDms, publicKey) : 0; return (
navigate("/search")}> @@ -136,12 +156,12 @@ export default function Layout() { {unreadNotifications > 0 && ()}
- +
) } - if (typeof isInit !== "boolean") { + if (typeof loggedOut !== "boolean") { return null; } return ( @@ -149,7 +169,7 @@ export default function Layout() {
navigate("/")}>Snort
- {key ? accountHeader() : + {publicKey ? accountHeader() : }
diff --git a/src/Pages/Login.tsx b/src/Pages/Login.tsx index 643fb85d..e51a3c67 100644 --- a/src/Pages/Login.tsx +++ b/src/Pages/Login.tsx @@ -4,7 +4,7 @@ import { useNavigate } from "react-router-dom"; import * as secp from '@noble/secp256k1'; import { RootState } from "State/Store"; -import { setPrivateKey, setPublicKey, setRelays } from "State/Login"; +import { setPrivateKey, setPublicKey, setRelays, setGeneratedPrivateKey } from "State/Login"; import { DefaultRelays, EmailRegex } from "Const"; import { bech32ToHex } from "Util"; import { HexKey } from "Nostr"; @@ -66,23 +66,7 @@ export default function LoginPage() { async function makeRandomKey() { let newKey = secp.utils.bytesToHex(secp.utils.randomPrivateKey()); - dispatch(setPrivateKey(newKey)); - - try { - let rsp = await fetch("https://api.nostr.watch/v1/online"); - if (rsp.ok) { - let online: string[] = await rsp.json(); - let pickRandom = online.sort((a, b) => Math.random() >= 0.5 ? 1 : -1).slice(0, 4); // pick 4 random relays - - let relayObjects = pickRandom.map(a => [a, { read: true, write: true }]); - dispatch(setRelays({ - relays: Object.fromEntries(relayObjects), - createdAt: 1 - })); - } - } catch (e) { - console.warn(e); - } + dispatch(setGeneratedPrivateKey(newKey)); navigate("/new"); } diff --git a/src/State/Login.ts b/src/State/Login.ts index ef083ed4..13c1535a 100644 --- a/src/State/Login.ts +++ b/src/State/Login.ts @@ -85,6 +85,11 @@ export interface LoginStore { */ publicKey?: HexKey, + /** + * If user generated key on snort + */ + newUserKey: boolean, + /** * All the logged in users relays */ @@ -157,6 +162,7 @@ export const InitState = { loggedOut: undefined, publicKey: undefined, privateKey: undefined, + newUserKey: false, relays: {}, latestRelays: 0, follows: [], @@ -242,6 +248,13 @@ const LoginSlice = createSlice({ window.localStorage.setItem(PrivateKeyItem, action.payload); state.publicKey = secp.utils.bytesToHex(secp.schnorr.getPublicKey(action.payload)); }, + setGeneratedPrivateKey: (state, action: PayloadAction) => { + state.loggedOut = false; + state.newUserKey = true; + state.privateKey = action.payload; + window.localStorage.setItem(PrivateKeyItem, action.payload); + state.publicKey = secp.utils.bytesToHex(secp.schnorr.getPublicKey(action.payload)); + }, setPublicKey: (state, action: PayloadAction) => { window.localStorage.setItem(PublicKeyItem, action.payload); state.loggedOut = false; @@ -362,6 +375,7 @@ const LoginSlice = createSlice({ export const { init, setPrivateKey, + setGeneratedPrivateKey, setPublicKey, setRelays, removeRelay,