From 875225591a61ad73ecdaef0104d737ecf17c46be Mon Sep 17 00:00:00 2001 From: reya Date: Wed, 15 Nov 2023 14:20:45 +0700 Subject: [PATCH] wip: settings screen --- src/app.tsx | 74 ++-- src/app/personal/editContact.tsx | 55 --- src/app/personal/editProfile.tsx | 323 ------------------ src/app/personal/index.tsx | 26 -- src/app/settings/about.tsx | 3 + src/app/settings/advanced.tsx | 3 + src/app/settings/backup.tsx | 3 + .../components/contactCard.tsx | 2 +- .../components/postCard.tsx | 0 .../components/profileCard.tsx | 2 +- .../components/relayCard.tsx | 0 .../components/zapCard.tsx | 0 src/app/settings/editContact.tsx | 41 +++ src/app/settings/editProfile.tsx | 303 ++++++++++++++++ src/app/settings/general.tsx | 3 + src/app/settings/index.tsx | 20 +- src/shared/accounts/active.tsx | 2 +- src/shared/accounts/more.tsx | 14 +- src/shared/layouts/settings.tsx | 79 ++++- 19 files changed, 500 insertions(+), 453 deletions(-) delete mode 100644 src/app/personal/editContact.tsx delete mode 100644 src/app/personal/editProfile.tsx delete mode 100644 src/app/personal/index.tsx create mode 100644 src/app/settings/about.tsx create mode 100644 src/app/settings/advanced.tsx create mode 100644 src/app/settings/backup.tsx rename src/app/{personal => settings}/components/contactCard.tsx (97%) rename src/app/{personal => settings}/components/postCard.tsx (100%) rename src/app/{personal => settings}/components/profileCard.tsx (98%) rename src/app/{personal => settings}/components/relayCard.tsx (100%) rename src/app/{personal => settings}/components/zapCard.tsx (100%) create mode 100644 src/app/settings/editContact.tsx create mode 100644 src/app/settings/editProfile.tsx create mode 100644 src/app/settings/general.tsx diff --git a/src/app.tsx b/src/app.tsx index bdc93bd4..2c4d295a 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -113,34 +113,6 @@ export default function App() { }, ], }, - { - path: '/personal', - element: , - errorElement: , - children: [ - { - path: '', - async lazy() { - const { PersonalScreen } = await import('@app/personal'); - return { Component: PersonalScreen }; - }, - }, - { - path: 'edit-profile', - async lazy() { - const { EditProfileScreen } = await import('@app/personal/editProfile'); - return { Component: EditProfileScreen }; - }, - }, - { - path: 'edit-contact', - async lazy() { - const { EditContactScreen } = await import('@app/personal/editContact'); - return { Component: EditContactScreen }; - }, - }, - ], - }, { path: '/new', element: , @@ -260,8 +232,50 @@ export default function App() { { path: '', async lazy() { - const { SettingsScreen } = await import('@app/settings'); - return { Component: SettingsScreen }; + const { UserSettingScreen } = await import('@app/settings'); + return { Component: UserSettingScreen }; + }, + }, + { + path: 'edit-profile', + async lazy() { + const { EditProfileScreen } = await import('@app/settings/editProfile'); + return { Component: EditProfileScreen }; + }, + }, + { + path: 'edit-contact', + async lazy() { + const { EditContactScreen } = await import('@app/settings/editContact'); + return { Component: EditContactScreen }; + }, + }, + { + path: 'general', + async lazy() { + const { GeneralSettingScreen } = await import('@app/settings/general'); + return { Component: GeneralSettingScreen }; + }, + }, + { + path: 'backup', + async lazy() { + const { BackupSettingScreen } = await import('@app/settings/backup'); + return { Component: BackupSettingScreen }; + }, + }, + { + path: 'advanced', + async lazy() { + const { AdvancedSettingScreen } = await import('@app/settings/advanced'); + return { Component: AdvancedSettingScreen }; + }, + }, + { + path: 'about', + async lazy() { + const { AboutScreen } = await import('@app/settings/about'); + return { Component: AboutScreen }; }, }, ], diff --git a/src/app/personal/editContact.tsx b/src/app/personal/editContact.tsx deleted file mode 100644 index 3cb871f1..00000000 --- a/src/app/personal/editContact.tsx +++ /dev/null @@ -1,55 +0,0 @@ -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 deleted file mode 100644 index 8d2d1a5d..00000000 --- a/src/app/personal/editProfile.tsx +++ /dev/null @@ -1,323 +0,0 @@ -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

-
-
-
-
- - -
-
- {banner ? ( - user's banner - ) : ( -
- )} -
- -
-
-
-
- user's avatar -
- -
-
-
-
-
-
- - -
-
- - -
-
- -
- -
- {nip05.verified ? ( - - - Verified - - ) : ( - - - Unverified - - )} -
- {errors.nip05 && ( -

- {errors.nip05.message.toString()} -

- )} -
-
-
- - -
-
- - -
-
- -