diff --git a/bun.lockb b/bun.lockb index 56a1718b..d25561ea 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 35b8b5b1..f7163016 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "**/*.{ts, tsx, css, md, html, json}": "prettier --cache --write" }, "dependencies": { - "@ctrl/magnet-link": "^3.1.2", "@getalby/sdk": "^2.4.0", "@nostr-dev-kit/ndk": "^1.0.0", "@nostr-fetch/adapter-ndk": "^0.12.2", @@ -38,10 +37,8 @@ "@tiptap/react": "^2.1.8", "@tiptap/starter-kit": "^2.1.8", "@tiptap/suggestion": "^2.1.8", - "@void-cat/api": "^1.0.7", "dayjs": "^1.11.9", "destr": "^2.0.1", - "framer-motion": "^10.16.4", "get-urls": "^12.1.0", "html-to-text": "^9.0.5", "light-bolt11-decoder": "^3.0.0", @@ -54,7 +51,6 @@ "react-currency-input-field": "^3.6.11", "react-dom": "^18.2.0", "react-hook-form": "^7.46.1", - "react-hotkeys-hook": "^4.4.1", "react-markdown": "^8.0.7", "react-player": "^2.13.0", "react-router-dom": "^6.15.0", @@ -65,7 +61,6 @@ "tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#v1", "tauri-plugin-stronghold-api": "github:tauri-apps/tauri-plugin-stronghold#v1", "tauri-plugin-upload-api": "github:tauri-apps/tauri-plugin-upload#v1", - "tippy.js": "^6.3.7", "zustand": "^4.4.1" }, "devDependencies": { diff --git a/src/app.tsx b/src/app.tsx index cdb894f6..cd9c8897 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -207,6 +207,13 @@ const router = createBrowserRouter([ }, ], }, + { + path: 'complete', + async lazy() { + const { CompleteScreen } = await import('@app/auth/complete'); + return { Component: CompleteScreen }; + }, + }, { path: 'unlock', async lazy() { diff --git a/src/app/auth/complete.tsx b/src/app/auth/complete.tsx new file mode 100644 index 00000000..5a3a3291 --- /dev/null +++ b/src/app/auth/complete.tsx @@ -0,0 +1,43 @@ +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +export function CompleteScreen() { + const navigate = useNavigate(); + const [count, setCount] = useState(3); + + useEffect(() => { + let counter: NodeJS.Timeout; + + if (count > 0) { + counter = setTimeout(() => setCount(count - 1), 1000); + } + + if (count === 0) { + navigate('/', { replace: true }); + } + + return () => { + clearTimeout(counter); + }; + }, [count]); + + return ( +
+
+

+ You're ready, redirecting in {count} + ... +

+

+ Thank you for using Lume. Lume doesn't use telemetry. If you encounter any + problems, please submit a report via the "Report Issue" button. +
+ You can find it while using the application. +

+
+
+ lume +
+
+ ); +} diff --git a/src/app/auth/create/step-3.tsx b/src/app/auth/create/step-3.tsx index f9c08c1c..b05e14e0 100644 --- a/src/app/auth/create/step-3.tsx +++ b/src/app/auth/create/step-3.tsx @@ -112,7 +112,7 @@ export function CreateStep3Screen() { type={'text'} {...register('name', { required: true, - minLength: 4, + minLength: 1, })} spellCheck={false} className="relative h-12 w-full rounded-lg bg-white/20 px-3 py-1 text-white !outline-none backdrop-blur-xl placeholder:text-white/70" diff --git a/src/app/auth/import/step-1.tsx b/src/app/auth/import/step-1.tsx index e7ac3047..e06f4ef9 100644 --- a/src/app/auth/import/step-1.tsx +++ b/src/app/auth/import/step-1.tsx @@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom'; import { useStorage } from '@libs/storage/provider'; -import { LoaderIcon } from '@shared/icons'; +import { EyeOffIcon, EyeOnIcon, LoaderIcon } from '@shared/icons'; import { ArrowRightCircleIcon } from '@shared/icons/arrowRightCircle'; import { useOnboarding } from '@stores/onboarding'; @@ -37,6 +37,7 @@ export function ImportStep1Screen() { const setStep = useOnboarding((state) => state.setStep); const [loading, setLoading] = useState(false); + const [passwordInput, setPasswordInput] = useState('password'); const { db } = useStorage(); const { @@ -78,6 +79,15 @@ export function ImportStep1Screen() { } }; + // toggle private key + const showPassword = () => { + if (passwordInput === 'password') { + setPasswordInput('text'); + } else { + setPasswordInput('password'); + } + }; + useEffect(() => { // save current step, if user close app and reopen it setStep('/auth/import'); @@ -96,12 +106,25 @@ export function ImportStep1Screen() { - +
+ + +
{errors.privkey &&

{errors.privkey.message}

}
diff --git a/src/app/auth/onboarding/step-2.tsx b/src/app/auth/onboarding/step-2.tsx index 6c7dd542..0fd99a89 100644 --- a/src/app/auth/onboarding/step-2.tsx +++ b/src/app/auth/onboarding/step-2.tsx @@ -60,7 +60,7 @@ export function OnboardStep2Screen() { // clear local storage clearStep(); - navigate('/', { replace: true }); + navigate('/auth/complete', { replace: true }); }; const submit = async () => { @@ -77,7 +77,7 @@ export function OnboardStep2Screen() { // clear local storage clearStep(); - navigate('/', { replace: true }); + navigate('/auth/complete', { replace: true }); } catch (e) { setLoading(false); await message(e, { title: 'Lume', type: 'error' }); diff --git a/src/app/auth/welcome.tsx b/src/app/auth/welcome.tsx index 49153f31..c8e3ca05 100644 --- a/src/app/auth/welcome.tsx +++ b/src/app/auth/welcome.tsx @@ -2,7 +2,6 @@ import { LogicalSize, getCurrent } from '@tauri-apps/api/window'; import { useEffect } from 'react'; import { Link } from 'react-router-dom'; -import { Frame } from '@shared/frame'; import { ArrowRightCircleIcon } from '@shared/icons/arrowRightCircle'; export function WelcomeScreen() { @@ -29,7 +28,7 @@ export function WelcomeScreen() { }, []); return ( - +

Welcome to Lume

@@ -58,6 +57,6 @@ export function WelcomeScreen() {
lume
- +
); } diff --git a/src/utils/hooks/useUploader.ts b/src/utils/hooks/useUploader.ts deleted file mode 100644 index 7ece1928..00000000 --- a/src/utils/hooks/useUploader.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { magnetDecode } from '@ctrl/magnet-link'; -import { open } from '@tauri-apps/api/dialog'; -import { VoidApi } from '@void-cat/api'; - -import { createBlobFromFile } from '@utils/createBlobFromFile'; -import { useNostr } from '@utils/hooks/useNostr'; - -export function useImageUploader() { - const { publish } = useNostr(); - - const upload = async (file: null | string, nip94?: boolean) => { - const voidcat = new VoidApi('https://void.cat'); - - let filepath = file; - if (!file) { - const selected = await open({ - multiple: false, - filters: [ - { - name: 'Image', - extensions: [ - 'png', - 'jpeg', - 'jpg', - 'gif', - 'mp4', - 'mp3', - 'webm', - 'mkv', - 'avi', - 'mov', - ], - }, - ], - }); - if (Array.isArray(selected)) { - // user selected multiple files - } else if (selected === null) { - // user cancelled the selection - } else { - filepath = selected; - } - } - - const filename = filepath.split('/').pop(); - const filetype = filename.split('.').pop(); - - const blob = await createBlobFromFile(filepath); - const uploader = voidcat.getUploader(blob); - - // upload file - const res = await uploader.upload(); - - if (res.ok) { - const url = - res.file?.metadata?.url ?? `https://void.cat/d/${res.file?.id}.${filetype}`; - - if (nip94) { - const tags = [ - ['url', url], - ['x', res.file?.metadata?.digest ?? ''], - ['m', res.file?.metadata?.mimeType ?? 'application/octet-stream'], - ['size', res.file?.metadata?.size.toString() ?? '0'], - ]; - - if (res.file?.metadata?.magnetLink) { - tags.push(['magnet', res.file.metadata.magnetLink]); - const parsedMagnet = magnetDecode(res.file.metadata.magnetLink); - if (parsedMagnet?.infoHash) { - tags.push(['i', parsedMagnet?.infoHash]); - } - } - - await publish({ content: '', kind: 1063, tags: tags }); - } - - return { - url: url, - error: null, - }; - } - - return { - url: null, - error: 'Upload failed', - }; - }; - - return upload; -}