- {compactNumber.format(data.relays.length)}
+ {compactNumber.format(data?.relays?.length)}
-
- Relays
+
+
+ Relays
+
+
+
+ Edit
+
)}
diff --git a/src/app/personal/components/zapCard.tsx b/src/app/personal/components/zapCard.tsx
index 7741553f..e2aa5309 100644
--- a/src/app/personal/components/zapCard.tsx
+++ b/src/app/personal/components/zapCard.tsx
@@ -43,7 +43,7 @@ export function ZapCard() {
data.stats[db.account.pubkey].zaps_received.msats / 1000
)}
-
diff --git a/src/app/personal/editContact.tsx b/src/app/personal/editContact.tsx
new file mode 100644
index 00000000..3cb871f1
--- /dev/null
+++ b/src/app/personal/editContact.tsx
@@ -0,0 +1,55 @@
+import { useQuery } from '@tanstack/react-query';
+import { Link } from 'react-router-dom';
+
+import { useNDK } from '@libs/ndk/provider';
+import { useStorage } from '@libs/storage/provider';
+
+import { ArrowLeftIcon, LoaderIcon } from '@shared/icons';
+import { User } from '@shared/user';
+
+export function EditContactScreen() {
+ const { db } = useStorage();
+ const { ndk } = useNDK();
+ const { status, data } = useQuery({
+ queryKey: ['contacts'],
+ queryFn: async () => {
+ const user = ndk.getUser({ pubkey: db.account.pubkey });
+
+ const follows = await user.follows();
+ return [...follows];
+ },
+ refetchOnWindowFocus: false,
+ });
+
+ return (
+
+
+
+
+ Back
+
+
Contact Manager
+
+
+
+ {status === 'pending' ? (
+
+
+
+ ) : (
+ data.map((item) => (
+
+
+
+ ))
+ )}
+
+
+ );
+}
diff --git a/src/app/personal/editProfile.tsx b/src/app/personal/editProfile.tsx
new file mode 100644
index 00000000..8d2d1a5d
--- /dev/null
+++ b/src/app/personal/editProfile.tsx
@@ -0,0 +1,323 @@
+import { NDKEvent, NDKKind, NDKUserProfile } from '@nostr-dev-kit/ndk';
+import { useQueryClient } from '@tanstack/react-query';
+import { message } from '@tauri-apps/plugin-dialog';
+import { useState } from 'react';
+import { useForm } from 'react-hook-form';
+import { Link } from 'react-router-dom';
+
+import { useNDK } from '@libs/ndk/provider';
+import { useStorage } from '@libs/storage/provider';
+
+import {
+ ArrowLeftIcon,
+ CheckCircleIcon,
+ LoaderIcon,
+ PlusIcon,
+ UnverifiedIcon,
+} from '@shared/icons';
+
+import { useNostr } from '@utils/hooks/useNostr';
+
+export function EditProfileScreen() {
+ const queryClient = useQueryClient();
+
+ const [loading, setLoading] = useState(false);
+ const [picture, setPicture] = useState('');
+ const [banner, setBanner] = useState('');
+ const [nip05, setNIP05] = useState({ verified: true, text: '' });
+
+ const { db } = useStorage();
+ const { ndk } = useNDK();
+ const { upload } = useNostr();
+ const {
+ register,
+ handleSubmit,
+ reset,
+ setError,
+ formState: { isValid, errors },
+ } = useForm({
+ defaultValues: async () => {
+ const res: NDKUserProfile = queryClient.getQueryData(['user', db.account.pubkey]);
+ if (res.image) {
+ setPicture(res.image);
+ }
+ if (res.banner) {
+ setBanner(res.banner);
+ }
+ if (res.nip05) {
+ setNIP05((prev) => ({ ...prev, text: res.nip05 }));
+ }
+ return res;
+ },
+ });
+
+ const uploadAvatar = async () => {
+ try {
+ setLoading(true);
+
+ const image = await upload();
+
+ if (image) {
+ setPicture(image);
+ setLoading(false);
+ }
+ } catch (e) {
+ setLoading(false);
+ await message(`Upload failed, error: ${e}`, { title: 'Lume', type: 'error' });
+ }
+ };
+
+ const uploadBanner = async () => {
+ try {
+ setLoading(true);
+
+ const image = await upload();
+
+ if (image) {
+ setBanner(image);
+ setLoading(false);
+ }
+ } catch (e) {
+ setLoading(false);
+ await message(`Upload failed, error: ${e}`, { title: 'Lume', type: 'error' });
+ }
+ };
+
+ const onSubmit = async (data: NDKUserProfile) => {
+ // start loading
+ setLoading(true);
+
+ const content = {
+ ...data,
+ username: data.name,
+ display_name: data.name,
+ bio: data.about,
+ image: data.picture,
+ };
+
+ const event = new NDKEvent(ndk);
+ event.kind = NDKKind.Metadata;
+ event.tags = [];
+
+ if (data.nip05) {
+ const user = ndk.getUser({ pubkey: db.account.pubkey });
+ const verify = await user.validateNip05(data.nip05);
+ if (verify) {
+ event.content = JSON.stringify({ ...content, nip05: data.nip05 });
+ } else {
+ setNIP05((prev) => ({ ...prev, verified: false }));
+ setError('nip05', {
+ type: 'manual',
+ message: "Can't verify your Lume ID / NIP-05, please check again",
+ });
+ }
+ } else {
+ event.content = JSON.stringify(content);
+ }
+
+ const publishedRelays = await event.publish();
+
+ if (publishedRelays) {
+ // invalid cache
+ queryClient.invalidateQueries({
+ queryKey: ['user', db.account.pubkey],
+ });
+ // reset form
+ reset();
+ // reset state
+ setLoading(false);
+ setPicture(null);
+ setBanner(null);
+ } else {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
+
+
+ Back
+
+
Edit Profile
+
+
+
+
+ );
+}
diff --git a/src/app/personal/index.tsx b/src/app/personal/index.tsx
index 268f0aeb..d84191e7 100644
--- a/src/app/personal/index.tsx
+++ b/src/app/personal/index.tsx
@@ -6,13 +6,20 @@ import { ZapCard } from '@app/personal/components/zapCard';
export function PersonalScreen() {
return (
-
-
-
-
-
-
-
+
+
+
+
Personal Dashboard
+
+
+
);
diff --git a/src/app/users/components/profile.tsx b/src/app/users/components/profile.tsx
index cbca16e0..af411544 100644
--- a/src/app/users/components/profile.tsx
+++ b/src/app/users/components/profile.tsx
@@ -28,9 +28,9 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
const follow = async (pubkey: string) => {
try {
- const user = ndk.getUser({ hexpubkey: db.account.pubkey });
+ const user = ndk.getUser({ pubkey: db.account.pubkey });
const contacts = await user.follows();
- const add = await user.follow(new NDKUser({ hexpubkey: pubkey }), contacts);
+ const add = await user.follow(new NDKUser({ pubkey: pubkey }), contacts);
if (add) {
setFollowed(true);
@@ -44,14 +44,12 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
const unfollow = async (pubkey: string) => {
try {
- const user = ndk.getUser({ hexpubkey: db.account.pubkey });
+ const user = ndk.getUser({ pubkey: db.account.pubkey });
const contacts = await user.follows();
- contacts.delete(new NDKUser({ hexpubkey: pubkey }));
+ contacts.delete(new NDKUser({ pubkey: pubkey }));
let list: string[][];
- contacts.forEach((el) =>
- list.push(['p', el.pubkey, el.relayUrls?.[0] || '', el.profile?.name || ''])
- );
+ contacts.forEach((el) => list.push(['p', el.pubkey, el.relayUrls?.[0] || '', '']));
const event = new NDKEvent(ndk);
event.content = '';
diff --git a/src/libs/ndk/instance.ts b/src/libs/ndk/instance.ts
index 56d5f0e4..5a0028b4 100644
--- a/src/libs/ndk/instance.ts
+++ b/src/libs/ndk/instance.ts
@@ -97,7 +97,7 @@ export const NDKInstance = () => {
if (db.account) {
const circleSetting = await db.getSettingValue('circles');
- const user = instance.getUser({ hexpubkey: db.account.pubkey });
+ const user = instance.getUser({ pubkey: db.account.pubkey });
const follows = await user.follows();
const relayList = await user.relayList();
diff --git a/src/shared/accounts/active.tsx b/src/shared/accounts/active.tsx
index fb12d845..3c734827 100644
--- a/src/shared/accounts/active.tsx
+++ b/src/shared/accounts/active.tsx
@@ -24,7 +24,7 @@ export function ActiveAccount() {
}
return (
-
+
-
+
{user?.name ||
user?.display_name ||
user?.displayName ||
diff --git a/src/shared/userProfile.tsx b/src/shared/userProfile.tsx
index de2cc529..3ae11c59 100644
--- a/src/shared/userProfile.tsx
+++ b/src/shared/userProfile.tsx
@@ -22,9 +22,9 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
const follow = async (pubkey: string) => {
try {
- const user = ndk.getUser({ hexpubkey: db.account.pubkey });
+ const user = ndk.getUser({ pubkey: db.account.pubkey });
const contacts = await user.follows();
- const add = await user.follow(new NDKUser({ hexpubkey: pubkey }), contacts);
+ const add = await user.follow(new NDKUser({ pubkey: pubkey }), contacts);
if (add) {
setFollowed(true);
@@ -38,14 +38,12 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
const unfollow = async (pubkey: string) => {
try {
- const user = ndk.getUser({ hexpubkey: db.account.pubkey });
+ const user = ndk.getUser({ pubkey: db.account.pubkey });
const contacts = await user.follows();
- contacts.delete(new NDKUser({ hexpubkey: pubkey }));
+ contacts.delete(new NDKUser({ pubkey: pubkey }));
let list: string[][];
- contacts.forEach((el) =>
- list.push(['p', el.pubkey, el.relayUrls?.[0] || '', el.profile?.name || ''])
- );
+ contacts.forEach((el) => list.push(['p', el.pubkey, el.relayUrls?.[0] || '', '']));
const event = new NDKEvent(ndk);
event.content = '';
diff --git a/src/shared/widgets/nostrBandUserProfile.tsx b/src/shared/widgets/nostrBandUserProfile.tsx
index 97b045c0..29a7365d 100644
--- a/src/shared/widgets/nostrBandUserProfile.tsx
+++ b/src/shared/widgets/nostrBandUserProfile.tsx
@@ -39,9 +39,9 @@ export function NostrBandUserProfile({ data }: { data: Profile }) {
const follow = async (pubkey: string) => {
try {
- const user = ndk.getUser({ hexpubkey: db.account.pubkey });
+ const user = ndk.getUser({ pubkey: db.account.pubkey });
const contacts = await user.follows();
- const add = await user.follow(new NDKUser({ hexpubkey: pubkey }), contacts);
+ const add = await user.follow(new NDKUser({ pubkey: pubkey }), contacts);
if (add) {
setFollowed(true);
@@ -55,14 +55,12 @@ export function NostrBandUserProfile({ data }: { data: Profile }) {
const unfollow = async (pubkey: string) => {
try {
- const user = ndk.getUser({ hexpubkey: db.account.pubkey });
+ const user = ndk.getUser({ pubkey: db.account.pubkey });
const contacts = await user.follows();
- contacts.delete(new NDKUser({ hexpubkey: pubkey }));
+ contacts.delete(new NDKUser({ pubkey: pubkey }));
let list: string[][];
- contacts.forEach((el) =>
- list.push(['p', el.pubkey, el.relayUrls?.[0] || '', el.profile?.name || ''])
- );
+ contacts.forEach((el) => list.push(['p', el.pubkey, el.relayUrls?.[0] || '', '']));
const event = new NDKEvent(ndk);
event.content = '';
diff --git a/src/shared/widgets/notification.tsx b/src/shared/widgets/notification.tsx
index 7755c3d5..0123cd87 100644
--- a/src/shared/widgets/notification.tsx
+++ b/src/shared/widgets/notification.tsx
@@ -89,7 +89,7 @@ export function NotificationWidget() {
})
);
- const user = ndk.getUser({ hexpubkey: event.pubkey });
+ const user = ndk.getUser({ pubkey: event.pubkey });
await user.fetchProfile();
switch (event.kind) {
diff --git a/src/utils/hooks/useNostr.ts b/src/utils/hooks/useNostr.ts
index 00145054..7aee73f6 100644
--- a/src/utils/hooks/useNostr.ts
+++ b/src/utils/hooks/useNostr.ts
@@ -194,7 +194,7 @@ export function useNostr() {
};
const getContactsByPubkey = async (pubkey: string) => {
- const user = ndk.getUser({ hexpubkey: pubkey });
+ const user = ndk.getUser({ pubkey: pubkey });
const follows = [...(await user.follows())].map((user) => user.hexpubkey);
return getMultipleRandom([...follows], 10);
};
diff --git a/src/utils/hooks/useProfile.ts b/src/utils/hooks/useProfile.ts
index 498d0897..7f162a4a 100644
--- a/src/utils/hooks/useProfile.ts
+++ b/src/utils/hooks/useProfile.ts
@@ -18,7 +18,7 @@ export function useProfile(pubkey: string, embed?: string) {
}
const cleanPubkey = pubkey.replace(/[^a-zA-Z0-9]/g, '');
- const user = ndk.getUser({ hexpubkey: cleanPubkey });
+ const user = ndk.getUser({ pubkey: cleanPubkey });
return await user.fetchProfile();
},