diff --git a/src/app/auth/components/user.tsx b/src/app/auth/components/user.tsx index 3d836750..0cd962b3 100644 --- a/src/app/auth/components/user.tsx +++ b/src/app/auth/components/user.tsx @@ -34,7 +34,7 @@ export function User({ pubkey, fallback }: { pubkey: string; fallback?: string } {user?.name || user?.displayName || user?.display_name} - + {user?.nip05?.toLowerCase() || shortenKey(pubkey)} diff --git a/src/app/auth/create/step-3.tsx b/src/app/auth/create/step-3.tsx index e370ec7c..2f2271a6 100644 --- a/src/app/auth/create/step-3.tsx +++ b/src/app/auth/create/step-3.tsx @@ -24,12 +24,13 @@ export function CreateStep3Screen() { formState: { isDirty, isValid }, } = useForm(); - const onSubmit = (data: any) => { + const onSubmit = (data: { name: string; about: string }) => { setLoading(true); try { const profile = { ...data, username: data.name, + name: data.name, display_name: data.name, bio: data.about, }; diff --git a/src/app/auth/onboarding.tsx b/src/app/auth/onboarding.tsx index 15977e30..dc53955d 100644 --- a/src/app/auth/onboarding.tsx +++ b/src/app/auth/onboarding.tsx @@ -22,7 +22,7 @@ export function OnboardingScreen() { // publish event publish({ - content: 'Running Lume, join with me: https://lume.nu', + content: 'Running Lume, join with me #nostr #lume : https://lume.nu', kind: 1, tags: [], }); @@ -55,7 +55,7 @@ export function OnboardingScreen() { )} - Running Lume, join with me + Running Lume, join with me #nostr #lume ))} + )} diff --git a/src/libs/storage.tsx b/src/libs/storage.tsx index 36ad79c8..69dd8dab 100644 --- a/src/libs/storage.tsx +++ b/src/libs/storage.tsx @@ -55,7 +55,7 @@ export async function createAccount( await createBlock( 0, 'Have fun together!', - 'https://i.nostrimg.com/cf7bdc227592686a0fcefcecb63fa860aab74c3c36dcd1cb6b09530188db7791/file.jpg' + 'https://void.cat/d/N5KUHEQCVg7SywXUPiJ7yq.jpg' ); } const getAccount = await getActiveAccount(); diff --git a/src/shared/avatarUploader.tsx b/src/shared/avatarUploader.tsx index c54ef84b..f77e5c90 100644 --- a/src/shared/avatarUploader.tsx +++ b/src/shared/avatarUploader.tsx @@ -1,54 +1,18 @@ -import { open } from '@tauri-apps/api/dialog'; -import { Body, fetch } from '@tauri-apps/api/http'; import { useState } from 'react'; import { LoaderIcon, PlusIcon } from '@shared/icons'; -import { createBlobFromFile } from '@utils/createBlobFromFile'; +import { useImageUploader } from '@utils/hooks/useUploader'; export function AvatarUploader({ setPicture }: { setPicture: any }) { + const upload = useImageUploader(); const [loading, setLoading] = useState(false); - const openFileDialog = async () => { - const selected: any = await open({ - multiple: false, - filters: [ - { - name: 'Image', - extensions: ['png', 'jpeg', 'jpg', 'gif'], - }, - ], - }); - if (Array.isArray(selected)) { - // user selected multiple files - } else if (selected === null) { - // user cancelled the selection - } else { - setLoading(true); - - const filename = selected.split('/').pop(); - const file = await createBlobFromFile(selected); - const buf = await file.arrayBuffer(); - - const res: { data: { file: { id: string } } } = await fetch( - 'https://void.cat/upload?cli=false', - { - method: 'POST', - timeout: 5, - headers: { - accept: '*/*', - 'Content-Type': 'application/octet-stream', - 'V-Filename': filename, - 'V-Description': 'Upload from https://lume.nu', - 'V-Strip-Metadata': 'true', - }, - body: Body.bytes(buf), - } - ); - const image = `https://void.cat/d/${res.data.file.id}.jpg`; - + const uploadAvatar = async () => { + const image = await upload(null); + if (image.url) { // update parent state - setPicture(image); + setPicture(image.url); // disable loader setLoading(false); @@ -58,7 +22,7 @@ export function AvatarUploader({ setPicture }: { setPicture: any }) { return ( openFileDialog()} + onClick={() => uploadAvatar()} className="inline-flex h-full w-full items-center justify-center bg-zinc-900/40" > {loading ? ( diff --git a/src/shared/bannerUploader.tsx b/src/shared/bannerUploader.tsx index 3bee2b88..57644ec0 100644 --- a/src/shared/bannerUploader.tsx +++ b/src/shared/bannerUploader.tsx @@ -1,52 +1,16 @@ -import { open } from '@tauri-apps/api/dialog'; -import { Body, fetch } from '@tauri-apps/api/http'; import { useState } from 'react'; import { LoaderIcon, PlusIcon } from '@shared/icons'; -import { createBlobFromFile } from '@utils/createBlobFromFile'; +import { useImageUploader } from '@utils/hooks/useUploader'; export function BannerUploader({ setBanner }: { setBanner: any }) { + const upload = useImageUploader(); const [loading, setLoading] = useState(false); - const openFileDialog = async () => { - const selected: any = await open({ - multiple: false, - filters: [ - { - name: 'Image', - extensions: ['png', 'jpeg', 'jpg', 'gif'], - }, - ], - }); - if (Array.isArray(selected)) { - // user selected multiple files - } else if (selected === null) { - // user cancelled the selection - } else { - setLoading(true); - - const filename = selected.split('/').pop(); - const file = await createBlobFromFile(selected); - const buf = await file.arrayBuffer(); - - const res: { data: { file: { id: string } } } = await fetch( - 'https://void.cat/upload?cli=false', - { - method: 'POST', - timeout: 5, - headers: { - accept: '*/*', - 'Content-Type': 'application/octet-stream', - 'V-Filename': filename, - 'V-Description': 'Upload from https://lume.nu', - 'V-Strip-Metadata': 'true', - }, - body: Body.bytes(buf), - } - ); - const image = `https://void.cat/d/${res.data.file.id}.jpg`; - + const uploadBanner = async () => { + const image = await upload(null); + if (image.url) { // update parent state setBanner(image); @@ -58,7 +22,7 @@ export function BannerUploader({ setBanner }: { setBanner: any }) { return ( openFileDialog()} + onClick={() => uploadBanner()} className="inline-flex h-full w-full items-center justify-center bg-zinc-900/40" > {loading ? ( diff --git a/src/shared/editProfileModal.tsx b/src/shared/editProfileModal.tsx index 2af76409..8a8e98fc 100644 --- a/src/shared/editProfileModal.tsx +++ b/src/shared/editProfileModal.tsx @@ -312,6 +312,20 @@ export function EditProfileModal() { className="relative h-10 w-full rounded-lg bg-zinc-800 px-3 py-2 text-zinc-100 !outline-none placeholder:text-zinc-500" /> + + + Lightning address + + + { - const selected: any = await open({ - multiple: false, - filters: [ - { - name: 'Image & Video', - extensions: ['png', 'jpeg', 'jpg', 'gif', 'mp4', 'mov'], - }, - ], - }); - if (Array.isArray(selected)) { - // user selected multiple files - } else if (selected === null) { - // user cancelled the selection - } else { - // start loading - setLoading(true); - - const filename = selected.split('/').pop(); - const file = await createBlobFromFile(selected); - const buf = await file.arrayBuffer(); - - const res: { data: { file: { id: string } } } = await fetch( - 'https://void.cat/upload?cli=false', - { - method: 'POST', - timeout: 5, - headers: { - accept: '*/*', - 'Content-Type': 'application/octet-stream', - 'V-Filename': filename, - 'V-Description': 'Upload from https://lume.nu', - 'V-Strip-Metadata': 'true', - }, - body: Body.bytes(buf), - } - ); - - const image = `https://void.cat/d/${res.data.file.id}.webp`; - + const uploadMedia = async () => { + const image = await upload(null); + if (image.url) { // update state - setState((prev: string) => `${prev}\n${image}`); + setState((prev: string) => `${prev}\n${image.url}`); // stop loading setLoading(false); } @@ -63,7 +26,7 @@ export function MediaUploader({ setState }: { setState: any }) { openFileDialog()} + onClick={() => uploadMedia()} className="group inline-flex h-6 w-6 items-center justify-center rounded bg-zinc-700 hover:bg-zinc-600" > {loading ? ( diff --git a/src/shared/notes/actions.tsx b/src/shared/notes/actions.tsx index b17bf512..dc9ce132 100644 --- a/src/shared/notes/actions.tsx +++ b/src/shared/notes/actions.tsx @@ -8,6 +8,7 @@ import { NoteZap } from '@shared/notes/actions/zap'; import { BLOCK_KINDS } from '@stores/constants'; +import { useAccount } from '@utils/hooks/useAccount'; import { useBlock } from '@utils/hooks/useBlock'; export function NoteActions({ @@ -22,6 +23,7 @@ export function NoteActions({ root?: string; }) { const { add } = useBlock(); + const { account } = useAccount(); return ( @@ -30,7 +32,7 @@ export function NoteActions({ - + {(account?.lud06 || account?.lud16) && } {!noOpenThread && ( <> diff --git a/src/shared/notes/actions/zap.tsx b/src/shared/notes/actions/zap.tsx index 1f72120c..8a0cc708 100644 --- a/src/shared/notes/actions/zap.tsx +++ b/src/shared/notes/actions/zap.tsx @@ -23,7 +23,7 @@ export function NoteZap({ id }: { id: string }) { }; const createZapRequest = async () => { - const res = await createZap(event as NostrEvent, amount); + const res = await createZap(event as unknown as NostrEvent, amount); if (res) setInvoice(res); }; diff --git a/src/shared/protected.tsx b/src/shared/protected.tsx index dec04391..d5cf51ab 100644 --- a/src/shared/protected.tsx +++ b/src/shared/protected.tsx @@ -1,6 +1,8 @@ import { ReactNode } from 'react'; import { Navigate } from 'react-router-dom'; +import { LoaderIcon } from '@shared/icons'; + import { useStronghold } from '@stores/stronghold'; import { useAccount } from '@utils/hooks/useAccount'; @@ -9,15 +11,23 @@ export function Protected({ children }: { children: ReactNode }) { const privkey = useStronghold((state) => state.privkey); const { status, account } = useAccount(); - if (status === 'success' && !account) { + if (status === 'loading') { + return ( + + + + ); + } + + if (!account) { return ; } - if (status === 'success' && account && account.privkey.length > 35) { + if (account && account.privkey.length > 35) { return ; } - if (status === 'success' && account && !privkey) { + if (account && !privkey) { return ; } diff --git a/src/utils/hooks/useAccount.tsx b/src/utils/hooks/useAccount.tsx index bcc6aca9..1d258451 100644 --- a/src/utils/hooks/useAccount.tsx +++ b/src/utils/hooks/useAccount.tsx @@ -1,11 +1,21 @@ import { useQuery } from '@tanstack/react-query'; +import { useNDK } from '@libs/ndk/provider'; import { getActiveAccount } from '@libs/storage'; export function useAccount() { + const { ndk } = useNDK(); const { status, data: account } = useQuery( ['currentAccount'], - async () => await getActiveAccount(), + async () => { + const account = await getActiveAccount(); + if (account?.pubkey) { + const user = ndk.getUser({ hexpubkey: account?.pubkey }); + await user.fetchProfile(); + return { ...account, ...user.profile }; + } + return account; + }, { staleTime: Infinity, refetchOnMount: true,
Running Lume, join with me
Running Lume, join with me #nostr #lume