mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-10-03 16:09:52 +02:00
added login with nip05
This commit is contained in:
@@ -6,7 +6,7 @@ import { Page } from "./components/page";
|
||||
import { SettingsView } from "./views/settings";
|
||||
import { LoginView } from "./views/login";
|
||||
import { ProfileView } from "./views/profile";
|
||||
import identityService from "./services/identity";
|
||||
import accountService from "./services/account";
|
||||
import { FollowingTab } from "./views/home/following-tab";
|
||||
import { DiscoverTab } from "./views/home/discover-tab";
|
||||
import { GlobalTab } from "./views/home/global-tab";
|
||||
@@ -23,10 +23,11 @@ import { LoginNpubView } from "./views/login/npub";
|
||||
import NotificationsView from "./views/notifications";
|
||||
import { RelaysView } from "./views/relays";
|
||||
import useSubject from "./hooks/use-subject";
|
||||
import { LoginNip05View } from "./views/login/nip05";
|
||||
|
||||
const RequireSetup = ({ children }: { children: JSX.Element }) => {
|
||||
let location = useLocation();
|
||||
const setup = useSubject(identityService.setup);
|
||||
const setup = useSubject(accountService.setup);
|
||||
|
||||
if (!setup) return <Navigate to="/login" state={{ from: location.pathname }} replace />;
|
||||
|
||||
@@ -48,6 +49,7 @@ const router = createBrowserRouter([
|
||||
children: [
|
||||
{ path: "", element: <LoginStartView /> },
|
||||
{ path: "npub", element: <LoginNpubView /> },
|
||||
{ path: "nip05", element: <LoginNip05View /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@@ -8,7 +8,7 @@ import { Bech32Prefix, normalizeToBech32 } from "../../helpers/nip-19";
|
||||
|
||||
import { NoteContents } from "./note-contents";
|
||||
import { NoteMenu } from "./note-menu";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
import { useUserContacts } from "../../hooks/use-user-contacts";
|
||||
import { UserTipButton } from "../user-tip-button";
|
||||
import { NoteRelays } from "./note-relays";
|
||||
@@ -31,7 +31,7 @@ export const Note = React.memo(({ event, maxHeight }: NoteProps) => {
|
||||
const readonly = useReadonlyMode();
|
||||
const { openModal } = useContext(PostModalContext);
|
||||
|
||||
const pubkey = useSubject(identityService.pubkey) ?? "";
|
||||
const pubkey = useSubject(accountService.pubkey) ?? "";
|
||||
const contacts = useUserContacts(pubkey);
|
||||
const following = contacts?.contacts || [];
|
||||
|
||||
|
@@ -6,7 +6,7 @@ import { ErrorBoundary } from "./error-boundary";
|
||||
import { ConnectedRelays } from "./connected-relays";
|
||||
|
||||
import { useIsMobile } from "../hooks/use-is-mobile";
|
||||
import identityService from "../services/identity";
|
||||
import accountService from "../services/account";
|
||||
import { FollowingList } from "./following-list";
|
||||
import { ReloadPrompt } from "./reload-prompt";
|
||||
import { PostModalProvider } from "../providers/post-modal-provider";
|
||||
@@ -16,7 +16,7 @@ import { UserAvatarLink } from "./user-avatar-link";
|
||||
import useSubject from "../hooks/use-subject";
|
||||
|
||||
const MobileProfileHeader = () => {
|
||||
const pubkey = useSubject(identityService.pubkey) ?? "";
|
||||
const pubkey = useSubject(accountService.pubkey) ?? "";
|
||||
const readonly = useReadonlyMode();
|
||||
|
||||
return (
|
||||
@@ -27,7 +27,7 @@ const MobileProfileHeader = () => {
|
||||
colorScheme="red"
|
||||
textAlign="center"
|
||||
variant="link"
|
||||
onClick={() => confirm("Exit readonly mode?") && identityService.logout()}
|
||||
onClick={() => confirm("Exit readonly mode?") && accountService.logout()}
|
||||
>
|
||||
Readonly Mode
|
||||
</Button>
|
||||
@@ -96,7 +96,7 @@ const DesktopSideNav = () => {
|
||||
<Button onClick={() => navigate("/settings")} leftIcon={<SettingsIcon />}>
|
||||
Settings
|
||||
</Button>
|
||||
<Button onClick={() => identityService.logout()} leftIcon={<LogoutIcon />}>
|
||||
<Button onClick={() => accountService.logout()} leftIcon={<LogoutIcon />}>
|
||||
Logout
|
||||
</Button>
|
||||
{readonly && (
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Box, LinkBox, Text } from "@chakra-ui/react";
|
||||
import { Link } from "react-router-dom";
|
||||
import identityService from "../services/identity";
|
||||
import accountService from "../services/account";
|
||||
import { UserAvatar } from "./user-avatar";
|
||||
import { useUserMetadata } from "../hooks/use-user-metadata";
|
||||
import { normalizeToBech32 } from "../helpers/nip-19";
|
||||
@@ -8,7 +8,7 @@ import { truncatedId } from "../helpers/nostr-event";
|
||||
import useSubject from "../hooks/use-subject";
|
||||
|
||||
export const ProfileButton = () => {
|
||||
const pubkey = useSubject(identityService.pubkey) ?? "";
|
||||
const pubkey = useSubject(accountService.pubkey) ?? "";
|
||||
const metadata = useUserMetadata(pubkey);
|
||||
|
||||
return (
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import identityService from "../services/identity";
|
||||
import accountService from "../services/account";
|
||||
import useSubject from "./use-subject";
|
||||
|
||||
export function useReadonlyMode() {
|
||||
return useSubject(identityService.readonly);
|
||||
return useSubject(accountService.readonly);
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ export type SavedIdentity = {
|
||||
useExtension: boolean;
|
||||
};
|
||||
|
||||
class IdentityService {
|
||||
class AccountService {
|
||||
loading = new PersistentSubject(false);
|
||||
setup = new PersistentSubject(false);
|
||||
pubkey = new Subject<string>();
|
||||
@@ -81,11 +81,11 @@ class IdentityService {
|
||||
}
|
||||
}
|
||||
|
||||
const identityService = new IdentityService();
|
||||
const accountService = new AccountService();
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
// @ts-ignore
|
||||
window.identity = identityService;
|
||||
window.identity = accountService;
|
||||
}
|
||||
|
||||
export default identityService;
|
||||
export default accountService;
|
@@ -3,7 +3,7 @@ import { nostrPostAction } from "../classes/nostr-post-action";
|
||||
import { PersistentSubject, Subject } from "../classes/subject";
|
||||
import { DraftNostrEvent, PTag } from "../types/nostr-event";
|
||||
import clientRelaysService from "./client-relays";
|
||||
import identityService from "./identity";
|
||||
import accountService from "./account";
|
||||
import userContactsService, { UserContacts } from "./user-contacts";
|
||||
|
||||
export type RelayDirectory = Record<string, { read: boolean; write: boolean }>;
|
||||
@@ -34,14 +34,14 @@ function updateSub() {
|
||||
sub = undefined;
|
||||
}
|
||||
|
||||
if (identityService.pubkey.value) {
|
||||
sub = userContactsService.requestContacts(identityService.pubkey.value, clientRelaysService.getReadUrls(), true);
|
||||
if (accountService.pubkey.value) {
|
||||
sub = userContactsService.requestContacts(accountService.pubkey.value, clientRelaysService.getReadUrls(), true);
|
||||
|
||||
sub.subscribe(handleNewContacts);
|
||||
}
|
||||
}
|
||||
|
||||
identityService.pubkey.subscribe(() => {
|
||||
accountService.pubkey.subscribe(() => {
|
||||
// clear the following list until a new one can be fetched
|
||||
following.next([]);
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import moment from "moment";
|
||||
import { nostrPostAction } from "../classes/nostr-post-action";
|
||||
import { unique } from "../helpers/array";
|
||||
import { DraftNostrEvent, RTag } from "../types/nostr-event";
|
||||
import identityService from "./identity";
|
||||
import accountService from "./account";
|
||||
import { RelayConfig, RelayMode } from "../classes/relay";
|
||||
import userRelaysService, { UserRelays } from "./user-relays";
|
||||
import { PersistentSubject, Subject } from "../classes/subject";
|
||||
@@ -23,7 +23,7 @@ class ClientRelayService {
|
||||
|
||||
constructor() {
|
||||
let lastSubject: Subject<UserRelays> | undefined;
|
||||
identityService.pubkey.subscribe((pubkey) => {
|
||||
accountService.pubkey.subscribe((pubkey) => {
|
||||
// clear the relay list until a new one can be fetched
|
||||
// this.relays.next([]);
|
||||
|
||||
@@ -38,7 +38,7 @@ class ClientRelayService {
|
||||
});
|
||||
|
||||
// add preset relays fromm nip07 extension to bootstrap list
|
||||
identityService.relays.subscribe((presetRelays) => {
|
||||
accountService.relays.subscribe((presetRelays) => {
|
||||
for (const [url, opts] of Object.entries(presetRelays)) {
|
||||
if (opts.read) {
|
||||
clientRelaysService.bootstrapRelays.add(url);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import moment from "moment";
|
||||
import db from "./db";
|
||||
|
||||
function parseAddress(address: string) {
|
||||
function parseAddress(address: string): { name?: string; domain?: string } {
|
||||
const parts = address.split("@");
|
||||
return { name: parts[0], domain: parts[1] };
|
||||
}
|
||||
@@ -18,10 +18,11 @@ export type DnsIdentity = {
|
||||
};
|
||||
|
||||
function getIdentityFromJson(name: string, domain: string, json: IdentityJson): DnsIdentity | undefined {
|
||||
const relays: string[] = json.relays?.[name] ?? [];
|
||||
const pubkey = json.names[name];
|
||||
if (!pubkey) return;
|
||||
|
||||
if (pubkey) return { name, domain, pubkey, relays };
|
||||
const relays: string[] = json.relays?.[pubkey] ?? [];
|
||||
return { name, domain, pubkey, relays };
|
||||
}
|
||||
|
||||
async function fetchAllIdentities(domain: string) {
|
||||
@@ -32,6 +33,7 @@ async function fetchAllIdentities(domain: string) {
|
||||
|
||||
async function fetchIdentity(address: string) {
|
||||
const { name, domain } = parseAddress(address);
|
||||
if (!name || !domain) return undefined;
|
||||
const json = await fetch(`https://${domain}/.well-known/nostr.json?name=${name}`).then(
|
||||
(res) => res.json() as Promise<IdentityJson>
|
||||
);
|
||||
@@ -53,9 +55,9 @@ async function addToCache(domain: string, json: IdentityJson) {
|
||||
await Promise.all(wait);
|
||||
}
|
||||
|
||||
async function getIdentity(address: string) {
|
||||
async function getIdentity(address: string, alwaysFetch = false) {
|
||||
const cached = await db.get("dnsIdentifiers", address);
|
||||
if (cached) return cached;
|
||||
if (cached && !alwaysFetch) return cached;
|
||||
|
||||
// TODO: if it fails, maybe cache a failure message
|
||||
return fetchIdentity(address);
|
||||
@@ -74,9 +76,9 @@ async function pruneCache() {
|
||||
}
|
||||
|
||||
const pending: Record<string, ReturnType<typeof getIdentity> | undefined> = {};
|
||||
function dedupedGetIdentity(address: string) {
|
||||
function dedupedGetIdentity(address: string, alwaysFetch = false) {
|
||||
if (pending[address]) return pending[address];
|
||||
return (pending[address] = getIdentity(address));
|
||||
return (pending[address] = getIdentity(address, alwaysFetch));
|
||||
}
|
||||
|
||||
export const dnsIdentityService = {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { PersistentSubject } from "../classes/subject";
|
||||
import db from "./db";
|
||||
import { SavedIdentity } from "./identity";
|
||||
import { SavedIdentity } from "./account";
|
||||
|
||||
const settings = {
|
||||
identity: new PersistentSubject<SavedIdentity | null>(null),
|
||||
|
@@ -3,7 +3,7 @@ import { Button, Flex, Spinner } from "@chakra-ui/react";
|
||||
import moment from "moment";
|
||||
import { Note } from "../../components/note";
|
||||
import { useUserContacts } from "../../hooks/use-user-contacts";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
import userContactsService from "../../services/user-contacts";
|
||||
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
|
||||
import { isNote } from "../../helpers/nostr-event";
|
||||
@@ -41,7 +41,7 @@ function useExtendedContacts(pubkey: string) {
|
||||
|
||||
export const DiscoverTab = () => {
|
||||
useAppTitle("discover");
|
||||
const pubkey = useSubject(identityService.pubkey) ?? "";
|
||||
const pubkey = useSubject(accountService.pubkey) ?? "";
|
||||
const relays = useReadRelayUrls();
|
||||
|
||||
const contactsOfContacts = useExtendedContacts(pubkey);
|
||||
|
@@ -5,7 +5,7 @@ import { Note } from "../../components/note";
|
||||
import { isNote } from "../../helpers/nostr-event";
|
||||
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
|
||||
import { useUserContacts } from "../../hooks/use-user-contacts";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
import { AddIcon } from "@chakra-ui/icons";
|
||||
import { useContext } from "react";
|
||||
import { PostModalContext } from "../../providers/post-modal-provider";
|
||||
@@ -15,7 +15,7 @@ import useSubject from "../../hooks/use-subject";
|
||||
|
||||
export const FollowingTab = () => {
|
||||
const readonly = useReadonlyMode();
|
||||
const pubkey = useSubject(identityService.pubkey) ?? "";
|
||||
const pubkey = useSubject(accountService.pubkey) ?? "";
|
||||
const relays = useReadRelayUrls();
|
||||
const { openModal } = useContext(PostModalContext);
|
||||
const contacts = useUserContacts(pubkey);
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import { Avatar, Box, Flex, Heading } from "@chakra-ui/react";
|
||||
import { Navigate, Outlet, useLocation } from "react-router-dom";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
|
||||
export const LoginView = () => {
|
||||
const setup = useSubject(identityService.setup);
|
||||
const setup = useSubject(accountService.setup);
|
||||
const location = useLocation();
|
||||
|
||||
if (setup) return <Navigate to={location.state?.from ?? "/"} replace />;
|
||||
|
137
src/views/login/nip05.tsx
Normal file
137
src/views/login/nip05.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormHelperText,
|
||||
FormLabel,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputRightElement,
|
||||
Link,
|
||||
Spinner,
|
||||
Text,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { RelayUrlInput } from "../../components/relay-url-input";
|
||||
import { normalizeToHex } from "../../helpers/nip-19";
|
||||
import accountService from "../../services/account";
|
||||
import clientRelaysService from "../../services/client-relays";
|
||||
import { useDebounce } from "react-use";
|
||||
import dnsIdentityService from "../../services/dns-identity";
|
||||
import { CheckIcon } from "../../components/icons";
|
||||
import { CloseIcon } from "@chakra-ui/icons";
|
||||
|
||||
export const LoginNip05View = () => {
|
||||
const navigate = useNavigate();
|
||||
const toast = useToast();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [nip05, setNip05] = useState("");
|
||||
const [relayUrl, setRelayUrl] = useState("");
|
||||
|
||||
const [pubkey, setPubkey] = useState<string | undefined>();
|
||||
const [relays, setRelays] = useState<string[] | undefined>();
|
||||
|
||||
const handleNip05Change: React.ChangeEventHandler<HTMLInputElement> = (event) => {
|
||||
setNip05(event.target.value);
|
||||
setPubkey(undefined);
|
||||
setRelays(undefined);
|
||||
if (event.target.value) setLoading(true);
|
||||
};
|
||||
|
||||
useDebounce(
|
||||
async () => {
|
||||
if (nip05) {
|
||||
try {
|
||||
const id = await dnsIdentityService.getIdentity(nip05, true);
|
||||
setPubkey(id?.pubkey);
|
||||
setRelays(id?.relays);
|
||||
} catch (e) {}
|
||||
}
|
||||
setLoading(false);
|
||||
},
|
||||
1000,
|
||||
[nip05, setPubkey, setRelays, setLoading]
|
||||
);
|
||||
|
||||
const handleSubmit: React.FormEventHandler<HTMLDivElement> = (e) => {
|
||||
e.preventDefault();
|
||||
if (!pubkey) return toast({ status: "error", title: "Invalid NIP-05 id" });
|
||||
|
||||
if ((!relays || relays.length === 0) && !relayUrl) {
|
||||
return toast({ status: "error", title: "No relay selected" });
|
||||
}
|
||||
|
||||
accountService.loginWithPubkey(pubkey);
|
||||
|
||||
if (relayUrl) {
|
||||
clientRelaysService.bootstrapRelays.add(relayUrl);
|
||||
}
|
||||
if (relays) {
|
||||
for (const url of relays) {
|
||||
clientRelaysService.bootstrapRelays.add(url);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const renderInputIcon = () => {
|
||||
if (loading) return <Spinner size="sm" />;
|
||||
if (nip05) {
|
||||
if (pubkey) return <CheckIcon color="green.500" />;
|
||||
else return <CloseIcon color="red.500" />;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex as="form" direction="column" gap="4" onSubmit={handleSubmit} minWidth="400">
|
||||
<FormControl>
|
||||
<FormLabel>Enter user NIP-05 id</FormLabel>
|
||||
<InputGroup>
|
||||
<Input
|
||||
name="nip05"
|
||||
placeholder="user@domain.com"
|
||||
isRequired
|
||||
value={nip05}
|
||||
onChange={handleNip05Change}
|
||||
colorScheme={"green"}
|
||||
errorBorderColor={nip05 && !pubkey ? "red.500" : undefined}
|
||||
/>
|
||||
<InputRightElement children={renderInputIcon()} />
|
||||
</InputGroup>
|
||||
<FormHelperText>
|
||||
Find NIP-05 ids here.{" "}
|
||||
<Link isExternal href="https://nostrplebs.com/directory" color="blue.500" target="_blank">
|
||||
nostrplebs.com/directory
|
||||
</Link>
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
{relays ? (
|
||||
relays.length > 0 ? (
|
||||
<Text>Found {relays.length} relays</Text>
|
||||
) : (
|
||||
<FormControl>
|
||||
<FormLabel>Bootstrap relay</FormLabel>
|
||||
<RelayUrlInput
|
||||
placeholder="wss://nostr.example.com"
|
||||
isRequired
|
||||
value={relayUrl}
|
||||
onChange={(e) => setRelayUrl(e.target.value)}
|
||||
/>
|
||||
<FormHelperText>The first relay to connect to.</FormHelperText>
|
||||
</FormControl>
|
||||
)
|
||||
) : null}
|
||||
<Flex justifyContent="space-between" gap="2">
|
||||
<Button variant="link" onClick={() => navigate("../")}>
|
||||
Back
|
||||
</Button>
|
||||
<Button colorScheme="brand" ml="auto" type="submit" isDisabled={!pubkey}>
|
||||
Login
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
@@ -3,7 +3,7 @@ import { Button, Flex, FormControl, FormHelperText, FormLabel, Input, Link, useT
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { RelayUrlInput } from "../../components/relay-url-input";
|
||||
import { normalizeToHex } from "../../helpers/nip-19";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
import clientRelaysService from "../../services/client-relays";
|
||||
|
||||
export const LoginNpubView = () => {
|
||||
@@ -20,16 +20,13 @@ export const LoginNpubView = () => {
|
||||
return toast({ status: "error", title: "Invalid npub" });
|
||||
}
|
||||
|
||||
identityService.loginWithPubkey(pubkey);
|
||||
accountService.loginWithPubkey(pubkey);
|
||||
|
||||
clientRelaysService.bootstrapRelays.add(relayUrl);
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex as="form" direction="column" gap="4" onSubmit={handleSubmit}>
|
||||
<Button variant="link" onClick={() => navigate("../")}>
|
||||
Back
|
||||
</Button>
|
||||
<Flex as="form" direction="column" gap="4" onSubmit={handleSubmit} minWidth="400">
|
||||
<FormControl>
|
||||
<FormLabel>Enter user npub</FormLabel>
|
||||
<Input type="text" placeholder="npub1" isRequired value={npub} onChange={(e) => setNpub(e.target.value)} />
|
||||
@@ -50,9 +47,14 @@ export const LoginNpubView = () => {
|
||||
/>
|
||||
<FormHelperText>The first relay to connect to.</FormHelperText>
|
||||
</FormControl>
|
||||
<Button colorScheme="brand" ml="auto" type="submit">
|
||||
Login
|
||||
</Button>
|
||||
<Flex justifyContent="space-between" gap="2">
|
||||
<Button variant="link" onClick={() => navigate("../")}>
|
||||
Back
|
||||
</Button>
|
||||
<Button colorScheme="brand" ml="auto" type="submit">
|
||||
Login
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import { Alert, AlertDescription, AlertIcon, AlertTitle, Box, Button, Spinner } from "@chakra-ui/react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
|
||||
export const LoginStartView = () => {
|
||||
const navigate = useNavigate();
|
||||
const loading = useSubject(identityService.loading);
|
||||
const loading = useSubject(accountService.loading);
|
||||
if (loading) return <Spinner />;
|
||||
|
||||
return (
|
||||
@@ -17,9 +17,10 @@ export const LoginStartView = () => {
|
||||
<AlertDescription>There are bugs and things will break.</AlertDescription>
|
||||
</Box>
|
||||
</Alert>
|
||||
<Button onClick={() => identityService.loginWithExtension()} colorScheme="brand">
|
||||
<Button onClick={() => accountService.loginWithExtension()} colorScheme="brand">
|
||||
Use browser extension
|
||||
</Button>
|
||||
<Button onClick={() => navigate("./nip05")}>Login with Nip-05 Id</Button>
|
||||
<Button variant="link" onClick={() => navigate("./npub")}>
|
||||
Login with npub
|
||||
</Button>
|
||||
|
@@ -8,7 +8,7 @@ import { convertTimestampToDate } from "../../helpers/date";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
|
||||
const Kind1Notification = ({ event }: { event: NostrEvent }) => {
|
||||
@@ -39,7 +39,7 @@ const NotificationItem = memo(({ event }: { event: NostrEvent }) => {
|
||||
|
||||
const NotificationsView = () => {
|
||||
const readRelays = useReadRelayUrls();
|
||||
const pubkey = useSubject(identityService.pubkey) ?? "";
|
||||
const pubkey = useSubject(accountService.pubkey) ?? "";
|
||||
const { events, loading, loadMore } = useTimelineLoader(
|
||||
"notifications",
|
||||
readRelays,
|
||||
|
@@ -3,7 +3,7 @@ import { useMemo } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import { useUserMetadata } from "../../hooks/use-user-metadata";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
|
||||
type FormData = {
|
||||
displayName?: string;
|
||||
@@ -60,7 +60,7 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => {
|
||||
};
|
||||
|
||||
export const ProfileEditView = () => {
|
||||
const pubkey = useSubject(identityService.pubkey) ?? "";
|
||||
const pubkey = useSubject(accountService.pubkey) ?? "";
|
||||
const metadata = useUserMetadata(pubkey);
|
||||
|
||||
const defaultValues = useMemo<FormData>(
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
import { ProfileEditView } from "./edit";
|
||||
|
||||
export const ProfileView = () => {
|
||||
const pubkey = useSubject(identityService.pubkey) ?? "";
|
||||
const pubkey = useSubject(accountService.pubkey) ?? "";
|
||||
|
||||
return <ProfileEditView />;
|
||||
};
|
||||
|
@@ -17,7 +17,7 @@ import {
|
||||
import { useState } from "react";
|
||||
import settings from "../../services/settings";
|
||||
import { clearCacheData, deleteDatabase } from "../../services/db";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
|
||||
export const SettingsView = () => {
|
||||
@@ -171,7 +171,7 @@ export const SettingsView = () => {
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
<Flex gap="2" padding="4">
|
||||
<Button onClick={() => identityService.logout()}>Logout</Button>
|
||||
<Button onClick={() => accountService.logout()}>Logout</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
@@ -3,7 +3,7 @@ import { MenuIconButton, MenuIconButtonProps } from "../../../components/menu-ic
|
||||
|
||||
import { IMAGE_ICONS, SpyIcon } from "../../../components/icons";
|
||||
import { Bech32Prefix, normalizeToBech32 } from "../../../helpers/nip-19";
|
||||
import identityService from "../../../services/identity";
|
||||
import accountService from "../../../services/account";
|
||||
import { useUserMetadata } from "../../../hooks/use-user-metadata";
|
||||
import { getUserDisplayName } from "../../../helpers/user-metadata";
|
||||
|
||||
@@ -13,8 +13,8 @@ export const UserProfileMenu = ({ pubkey, ...props }: { pubkey: string } & Omit<
|
||||
|
||||
const loginAsUser = () => {
|
||||
if (confirm(`Do you want to logout and login as ${getUserDisplayName(metadata, pubkey)}?`)) {
|
||||
identityService.logout();
|
||||
identityService.loginWithPubkey(pubkey);
|
||||
accountService.logout();
|
||||
accountService.loginWithPubkey(pubkey);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -24,7 +24,7 @@ import { truncatedId } from "../../helpers/nostr-event";
|
||||
import { Bech32Prefix, normalizeToBech32 } from "../../helpers/nip-19";
|
||||
import { KeyIcon, SettingsIcon } from "../../components/icons";
|
||||
import { CopyIconButton } from "../../components/copy-icon-button";
|
||||
import identityService from "../../services/identity";
|
||||
import accountService from "../../services/account";
|
||||
import { UserFollowButton } from "../../components/user-follow-button";
|
||||
import { useAppTitle } from "../../hooks/use-app-title";
|
||||
|
||||
@@ -48,7 +48,7 @@ const UserView = () => {
|
||||
|
||||
const metadata = useUserMetadata(pubkey, [], true);
|
||||
const npub = normalizeToBech32(pubkey, Bech32Prefix.Pubkey);
|
||||
const isSelf = pubkey === identityService.pubkey.value;
|
||||
const isSelf = pubkey === accountService.pubkey.value;
|
||||
|
||||
useAppTitle(getUserDisplayName(metadata, npub ?? pubkey));
|
||||
|
||||
|
Reference in New Issue
Block a user