diff --git a/package.json b/package.json index 3142ea8e..a82ac475 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "html-to-text": "^9.0.5", "immer": "^10.0.2", "light-bolt11-decoder": "^3.0.0", + "lru-cache": "^10.0.0", "million": "2.5.4-beta.2", "nostr-fetch": "^0.12.2", "nostr-tools": "^1.14.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cdf55f7c..e08b31c6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -136,6 +136,9 @@ dependencies: light-bolt11-decoder: specifier: ^3.0.0 version: 3.0.0 + lru-cache: + specifier: ^10.0.0 + version: 10.0.0 million: specifier: 2.5.4-beta.2 version: 2.5.4-beta.2 diff --git a/public/lume.png b/public/lume.png new file mode 100644 index 00000000..e830d7ef Binary files /dev/null and b/public/lume.png differ diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 43a99a62..8988832d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,11 +4,11 @@ )] // use rand::distributions::{Alphanumeric, DistString}; -use tauri::{Manager}; +use tauri::Manager; use tauri_plugin_autostart::MacosLauncher; use tauri_plugin_sql::{Migration, MigrationKind}; use window_shadows::set_shadow; -use window_vibrancy::{apply_blur, apply_vibrancy, NSVisualEffectMaterial}; +use window_vibrancy::{apply_mica, apply_vibrancy, NSVisualEffectMaterial}; #[derive(Clone, serde::Serialize)] struct Payload { @@ -16,6 +16,16 @@ struct Payload { cwd: String, } +#[tauri::command] +async fn close_splashscreen(window: tauri::Window) { + // Close splashscreen + if let Some(splashscreen) = window.get_window("splashscreen") { + splashscreen.close().unwrap(); + } + // Show main window + window.get_window("main").unwrap().show().unwrap(); +} + fn main() { tauri::Builder::default() .plugin( @@ -147,7 +157,7 @@ fn main() { .plugin(tauri_plugin_shell::init()) .setup(|app| { let window = app.get_window("main").unwrap(); - + // native shadow set_shadow(&window, true).expect("Unsupported platform!"); @@ -156,11 +166,12 @@ fn main() { .expect("Unsupported platform! 'apply_vibrancy' is only supported on macOS"); #[cfg(target_os = "windows")] - apply_blur(&window, Some((18, 18, 18, 125))) + apply_mica(&window, None, None) .expect("Unsupported platform! 'apply_blur' is only supported on Windows"); Ok(()) }) + .invoke_handler(tauri::generate_handler![close_splashscreen]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index a4831bde..3d663431 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -94,20 +94,32 @@ }, "windows": [ { - "fullscreen": false, - "hiddenTitle": true, - "minHeight": 400, - "minWidth": 500, + "width": 1080, + "height": 800, + "minWidth": 1080, + "minHeight": 800, "resizable": true, "theme": "Dark", "title": "Lume", "titleBarStyle": "Overlay", "transparent": true, + "center": true, + "fullscreen": false, + "hiddenTitle": true, + "visible": false + }, + { "width": 400, "height": 500, - "center": true + "decorations": true, + "hiddenTitle": true, + "center": true, + "resizable": false, + "titleBarStyle": "Overlay", + "label": "splashscreen", + "url": "splashscreen" } ], "macOSPrivateApi": true } -} \ No newline at end of file +} diff --git a/src/app.tsx b/src/app.tsx index 1001d0aa..fb7a57e9 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,4 +1,4 @@ -import { RouterProvider, createBrowserRouter } from 'react-router-dom'; +import { RouterProvider, createBrowserRouter, redirect } from 'react-router-dom'; import { AuthCreateScreen } from '@app/auth/create'; import { CreateStep1Screen } from '@app/auth/create/step-1'; @@ -15,33 +15,62 @@ import { OnboardingScreen } from '@app/auth/onboarding'; import { ResetScreen } from '@app/auth/reset'; import { UnlockScreen } from '@app/auth/unlock'; import { WelcomeScreen } from '@app/auth/welcome'; -import { ChannelScreen } from '@app/channel'; import { ChatScreen } from '@app/chats'; import { ErrorScreen } from '@app/error'; import { EventScreen } from '@app/events'; -import { Root } from '@app/root'; import { AccountSettingsScreen } from '@app/settings/account'; import { GeneralSettingsScreen } from '@app/settings/general'; import { ShortcutsSettingsScreen } from '@app/settings/shortcuts'; import { SpaceScreen } from '@app/space'; +import { SplashScreen } from '@app/splash'; import { TrendingScreen } from '@app/trending'; import { UserScreen } from '@app/users'; +import { getActiveAccount } from '@libs/storage'; + import { AppLayout } from '@shared/appLayout'; import { AuthLayout } from '@shared/authLayout'; -import { Protected } from '@shared/protected'; +import { LoaderIcon } from '@shared/icons'; import { SettingsLayout } from '@shared/settingsLayout'; import './index.css'; +const appLoader = async () => { + const account = await getActiveAccount(); + const privkey = sessionStorage.getItem('stronghold'); + + if (!account) { + return redirect('/auth/welcome'); + } + + if (account && account.privkey.length > 35) { + return redirect('/auth/migrate'); + } + + if (account && !privkey) { + return redirect('/auth/unlock'); + } + + return null; +}; + const router = createBrowserRouter([ { path: '/', - element: ( - - - - ), + element: , + errorElement: , + loader: appLoader, + children: [ + { path: '', element: }, + { path: 'trending', element: }, + { path: 'events/:id', element: }, + { path: 'users/:pubkey', element: }, + { path: 'chats/:pubkey', element: }, + ], + }, + { + path: '/splashscreen', + element: , errorElement: , }, { @@ -75,29 +104,9 @@ const router = createBrowserRouter([ { path: 'reset', element: }, ], }, - { - path: '/app', - element: ( - - - - ), - children: [ - { path: 'space', element: }, - { path: 'trending', element: }, - { path: 'events/:id', element: }, - { path: 'users/:pubkey', element: }, - { path: 'chats/:pubkey', element: }, - { path: 'channel/:id', element: }, - ], - }, { path: '/settings', - element: ( - - - - ), + element: , children: [ { path: 'general', element: }, { path: 'shortcuts', element: }, @@ -110,7 +119,11 @@ export default function App() { return ( Loading..

} + fallbackElement={ +
+ +
+ } future={{ v7_startTransition: true }} /> ); diff --git a/src/app/auth/components/user.tsx b/src/app/auth/components/user.tsx index ae66942c..99e2e399 100644 --- a/src/app/auth/components/user.tsx +++ b/src/app/auth/components/user.tsx @@ -11,10 +11,10 @@ export function User({ pubkey, fallback }: { pubkey: string; fallback?: string } if (status === 'loading') { return (
-
+
- - + +
); diff --git a/src/app/auth/create/step-1.tsx b/src/app/auth/create/step-1.tsx index b4ad76a1..36f34831 100644 --- a/src/app/auth/create/step-1.tsx +++ b/src/app/auth/create/step-1.tsx @@ -37,13 +37,9 @@ export function CreateStep1Screen() { }; const download = async () => { - await writeTextFile( - 'lume-keys.txt', - `Public key: ${pubkey}\nPrivate key: ${privkey}`, - { - dir: BaseDirectory.Download, - } - ); + await writeTextFile('lume-keys.txt', `Public key: ${npub}\nPrivate key: ${nsec}`, { + dir: BaseDirectory.Download, + }); setDownloaded(true); }; @@ -89,7 +85,7 @@ export function CreateStep1Screen() {
@@ -99,29 +95,21 @@ export function CreateStep1Screen() { readOnly type={privkeyInput} value={nsec} - className="relative w-full rounded-lg bg-zinc-800 py-3 pl-3.5 pr-11 text-white !outline-none placeholder:text-white/50" + className="relative h-11 w-full rounded-lg bg-white/10 py-1 pl-3.5 pr-11 text-white !outline-none placeholder:text-white/50" />
-
+

Your private key is your password. If you lose this key, you will lose access to your account! Copy it and keep it in a safe place. There is no way @@ -138,7 +126,9 @@ export function CreateStep1Screen() { )} {downloaded ? ( - Saved in download folder + + Saved in Download folder + ) : (

-
+

Password is use to secure your key store in local machine, when you move to other clients, you just need to copy your private key as nsec or @@ -122,10 +114,10 @@ export function CreateStep2Screen() {