wip
This commit is contained in:
539
src/app.tsx
539
src/app.tsx
@@ -7,6 +7,8 @@ import { OnboardingScreen } from '@app/auth/onboarding';
|
||||
import { BrowseScreen } from '@app/browse';
|
||||
import { ErrorScreen } from '@app/error';
|
||||
|
||||
import { useStorage } from '@libs/storage/provider';
|
||||
|
||||
import { Frame } from '@shared/frame';
|
||||
import { LoaderIcon } from '@shared/icons';
|
||||
import { AppLayout } from '@shared/layouts/app';
|
||||
@@ -14,275 +16,279 @@ import { AuthLayout } from '@shared/layouts/auth';
|
||||
import { NoteLayout } from '@shared/layouts/note';
|
||||
import { SettingsLayout } from '@shared/layouts/settings';
|
||||
|
||||
import { checkActiveAccount } from '@utils/checkActiveAccount';
|
||||
|
||||
import './index.css';
|
||||
|
||||
async function Loader() {
|
||||
try {
|
||||
const account = await checkActiveAccount();
|
||||
|
||||
const stronghold = sessionStorage.getItem('stronghold');
|
||||
const privkey = JSON.parse(stronghold).state.privkey || null;
|
||||
|
||||
const onboarding = localStorage.getItem('onboarding');
|
||||
const step = JSON.parse(onboarding).state.step || null;
|
||||
|
||||
if (!account) {
|
||||
return redirect('/auth/welcome');
|
||||
} else {
|
||||
if (step) {
|
||||
return redirect(step);
|
||||
}
|
||||
|
||||
if (!privkey) {
|
||||
return redirect('/auth/unlock');
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (e) {
|
||||
await message(e, { title: 'An unexpected error has occurred', type: 'error' });
|
||||
}
|
||||
}
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: '/',
|
||||
element: <AppLayout />,
|
||||
errorElement: <ErrorScreen />,
|
||||
loader: Loader,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { SpaceScreen } = await import('@app/space');
|
||||
return { Component: SpaceScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'browse',
|
||||
element: <BrowseScreen />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { BrowseUsersScreen } = await import('@app/browse/users');
|
||||
return { Component: BrowseUsersScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'relays',
|
||||
async lazy() {
|
||||
const { BrowseRelaysScreen } = await import('@app/browse/relays');
|
||||
return { Component: BrowseRelaysScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'users/:pubkey',
|
||||
async lazy() {
|
||||
const { UserScreen } = await import('@app/users');
|
||||
return { Component: UserScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'chats/:pubkey',
|
||||
async lazy() {
|
||||
const { ChatScreen } = await import('@app/chats');
|
||||
return { Component: ChatScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'notifications',
|
||||
async lazy() {
|
||||
const { NotificationScreen } = await import('@app/notifications');
|
||||
return { Component: NotificationScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'nwc',
|
||||
async lazy() {
|
||||
const { NWCScreen } = await import('@app/nwc');
|
||||
return { Component: NWCScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/notes',
|
||||
element: <NoteLayout />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: 'text/:id',
|
||||
async lazy() {
|
||||
const { TextNoteScreen } = await import('@app/notes/text');
|
||||
return { Component: TextNoteScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'article/:id',
|
||||
async lazy() {
|
||||
const { ArticleNoteScreen } = await import('@app/notes/article');
|
||||
return { Component: ArticleNoteScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/splashscreen',
|
||||
errorElement: <ErrorScreen />,
|
||||
async lazy() {
|
||||
const { SplashScreen } = await import('@app/splash');
|
||||
return { Component: SplashScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/auth',
|
||||
element: <AuthLayout />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: 'welcome',
|
||||
async lazy() {
|
||||
const { WelcomeScreen } = await import('@app/auth/welcome');
|
||||
return { Component: WelcomeScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'import',
|
||||
element: <AuthImportScreen />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { ImportStep1Screen } = await import('@app/auth/import/step-1');
|
||||
return { Component: ImportStep1Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-2',
|
||||
async lazy() {
|
||||
const { ImportStep2Screen } = await import('@app/auth/import/step-2');
|
||||
return { Component: ImportStep2Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-3',
|
||||
async lazy() {
|
||||
const { ImportStep3Screen } = await import('@app/auth/import/step-3');
|
||||
return { Component: ImportStep3Screen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
element: <AuthCreateScreen />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { CreateStep1Screen } = await import('@app/auth/create/step-1');
|
||||
return { Component: CreateStep1Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-2',
|
||||
async lazy() {
|
||||
const { CreateStep2Screen } = await import('@app/auth/create/step-2');
|
||||
return { Component: CreateStep2Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-3',
|
||||
async lazy() {
|
||||
const { CreateStep3Screen } = await import('@app/auth/create/step-3');
|
||||
return { Component: CreateStep3Screen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'onboarding',
|
||||
element: <OnboardingScreen />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { OnboardStep1Screen } = await import('@app/auth/onboarding/step-1');
|
||||
return { Component: OnboardStep1Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-2',
|
||||
async lazy() {
|
||||
const { OnboardStep2Screen } = await import('@app/auth/onboarding/step-2');
|
||||
return { Component: OnboardStep2Screen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'complete',
|
||||
async lazy() {
|
||||
const { CompleteScreen } = await import('@app/auth/complete');
|
||||
return { Component: CompleteScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'unlock',
|
||||
async lazy() {
|
||||
const { UnlockScreen } = await import('@app/auth/unlock');
|
||||
return { Component: UnlockScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'migrate',
|
||||
async lazy() {
|
||||
const { MigrateScreen } = await import('@app/auth/migrate');
|
||||
return { Component: MigrateScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'reset',
|
||||
async lazy() {
|
||||
const { ResetScreen } = await import('@app/auth/reset');
|
||||
return { Component: ResetScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
element: <SettingsLayout />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { GeneralSettingsScreen } = await import('@app/settings/general');
|
||||
return { Component: GeneralSettingsScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'backup',
|
||||
async lazy() {
|
||||
const { AccountSettingsScreen } = await import('@app/settings/account');
|
||||
return { Component: AccountSettingsScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
export default function App() {
|
||||
const { db } = useStorage();
|
||||
|
||||
const accountLoader = async () => {
|
||||
try {
|
||||
const account = await db.checkAccount();
|
||||
|
||||
const stronghold = sessionStorage.getItem('stronghold');
|
||||
const privkey = JSON.parse(stronghold).state.privkey || null;
|
||||
|
||||
const onboarding = localStorage.getItem('onboarding');
|
||||
const step = JSON.parse(onboarding).state.step || null;
|
||||
|
||||
if (!account) {
|
||||
return redirect('/auth/welcome');
|
||||
} else {
|
||||
if (step) {
|
||||
return redirect(step);
|
||||
}
|
||||
|
||||
if (!privkey) {
|
||||
return redirect('/auth/unlock');
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (e) {
|
||||
await message(e, { title: 'An unexpected error has occurred', type: 'error' });
|
||||
}
|
||||
};
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: '/',
|
||||
element: <AppLayout />,
|
||||
errorElement: <ErrorScreen />,
|
||||
loader: accountLoader,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { SpaceScreen } = await import('@app/space');
|
||||
return { Component: SpaceScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'browse',
|
||||
element: <BrowseScreen />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { BrowseUsersScreen } = await import('@app/browse/users');
|
||||
return { Component: BrowseUsersScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'relays',
|
||||
async lazy() {
|
||||
const { BrowseRelaysScreen } = await import('@app/browse/relays');
|
||||
return { Component: BrowseRelaysScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'users/:pubkey',
|
||||
async lazy() {
|
||||
const { UserScreen } = await import('@app/users');
|
||||
return { Component: UserScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'chats/:pubkey',
|
||||
async lazy() {
|
||||
const { ChatScreen } = await import('@app/chats');
|
||||
return { Component: ChatScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'notifications',
|
||||
async lazy() {
|
||||
const { NotificationScreen } = await import('@app/notifications');
|
||||
return { Component: NotificationScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'nwc',
|
||||
async lazy() {
|
||||
const { NWCScreen } = await import('@app/nwc');
|
||||
return { Component: NWCScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/notes',
|
||||
element: <NoteLayout />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: 'text/:id',
|
||||
async lazy() {
|
||||
const { TextNoteScreen } = await import('@app/notes/text');
|
||||
return { Component: TextNoteScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'article/:id',
|
||||
async lazy() {
|
||||
const { ArticleNoteScreen } = await import('@app/notes/article');
|
||||
return { Component: ArticleNoteScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/splashscreen',
|
||||
errorElement: <ErrorScreen />,
|
||||
async lazy() {
|
||||
const { SplashScreen } = await import('@app/splash');
|
||||
return { Component: SplashScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/auth',
|
||||
element: <AuthLayout />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: 'welcome',
|
||||
async lazy() {
|
||||
const { WelcomeScreen } = await import('@app/auth/welcome');
|
||||
return { Component: WelcomeScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'import',
|
||||
element: <AuthImportScreen />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { ImportStep1Screen } = await import('@app/auth/import/step-1');
|
||||
return { Component: ImportStep1Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-2',
|
||||
async lazy() {
|
||||
const { ImportStep2Screen } = await import('@app/auth/import/step-2');
|
||||
return { Component: ImportStep2Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-3',
|
||||
async lazy() {
|
||||
const { ImportStep3Screen } = await import('@app/auth/import/step-3');
|
||||
return { Component: ImportStep3Screen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
element: <AuthCreateScreen />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { CreateStep1Screen } = await import('@app/auth/create/step-1');
|
||||
return { Component: CreateStep1Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-2',
|
||||
async lazy() {
|
||||
const { CreateStep2Screen } = await import('@app/auth/create/step-2');
|
||||
return { Component: CreateStep2Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-3',
|
||||
async lazy() {
|
||||
const { CreateStep3Screen } = await import('@app/auth/create/step-3');
|
||||
return { Component: CreateStep3Screen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'onboarding',
|
||||
element: <OnboardingScreen />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { OnboardStep1Screen } = await import(
|
||||
'@app/auth/onboarding/step-1'
|
||||
);
|
||||
return { Component: OnboardStep1Screen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'step-2',
|
||||
async lazy() {
|
||||
const { OnboardStep2Screen } = await import(
|
||||
'@app/auth/onboarding/step-2'
|
||||
);
|
||||
return { Component: OnboardStep2Screen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'complete',
|
||||
async lazy() {
|
||||
const { CompleteScreen } = await import('@app/auth/complete');
|
||||
return { Component: CompleteScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'unlock',
|
||||
async lazy() {
|
||||
const { UnlockScreen } = await import('@app/auth/unlock');
|
||||
return { Component: UnlockScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'migrate',
|
||||
async lazy() {
|
||||
const { MigrateScreen } = await import('@app/auth/migrate');
|
||||
return { Component: MigrateScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'reset',
|
||||
async lazy() {
|
||||
const { ResetScreen } = await import('@app/auth/reset');
|
||||
return { Component: ResetScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
element: <SettingsLayout />,
|
||||
errorElement: <ErrorScreen />,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
async lazy() {
|
||||
const { GeneralSettingsScreen } = await import('@app/settings/general');
|
||||
return { Component: GeneralSettingsScreen };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'backup',
|
||||
async lazy() {
|
||||
const { AccountSettingsScreen } = await import('@app/settings/account');
|
||||
return { Component: AccountSettingsScreen };
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
return (
|
||||
<RouterProvider
|
||||
router={router}
|
||||
@@ -291,6 +297,7 @@ export default function App() {
|
||||
<LoaderIcon className="h-6 w-6 animate-spin text-white" />
|
||||
</Frame>
|
||||
}
|
||||
future={{ v7_startTransition: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
|
||||
|
||||
import { useStorage } from '@libs/storage/provider';
|
||||
|
||||
import { PlusIcon } from '@shared/icons';
|
||||
import { Image } from '@shared/image';
|
||||
import { NIP05 } from '@shared/nip05';
|
||||
import { TextNote } from '@shared/notes';
|
||||
@@ -50,14 +51,26 @@ export const UserDrawer = memo(function UserDrawer({ pubkey }: { pubkey: string
|
||||
|
||||
return (
|
||||
<Dialog.Root>
|
||||
<Dialog.Trigger asChild>
|
||||
<button type="button">
|
||||
<User pubkey={pubkey} variant="avatar" />
|
||||
</button>
|
||||
</Dialog.Trigger>
|
||||
<div className="group relative">
|
||||
<Dialog.Trigger asChild>
|
||||
<button type="button" className="relative z-10">
|
||||
<User pubkey={pubkey} variant="avatar" />
|
||||
</button>
|
||||
</Dialog.Trigger>
|
||||
<div className="absolute -bottom-14 left-0 flex flex-col opacity-0 transition-all duration-300 ease-smooth group-hover:-bottom-16 group-hover:opacity-100">
|
||||
<div className="mt-4">
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex h-12 w-12 items-center justify-center rounded-lg bg-white/10 backdrop-blur-xl hover:bg-white/20"
|
||||
>
|
||||
<PlusIcon className="h-4 w-4 text-white" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Content className="fixed right-0 top-0 z-50 flex h-full w-[400px] items-center justify-center">
|
||||
<div className="h-full w-full overflow-y-auto border-l border-white/10 bg-white/20 px-3 py-3 backdrop-blur-xl">
|
||||
<Dialog.Content className="fixed right-0 top-0 z-50 flex h-full w-[400px] items-center justify-center px-4 pb-4 pt-16">
|
||||
<div className="h-full w-full overflow-y-auto rounded-lg border-t border-white/10 bg-white/20 px-3 py-3 backdrop-blur-xl">
|
||||
{status === 'loading' ? (
|
||||
<div>
|
||||
<p>Loading...</p>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { NavLink, Outlet } from 'react-router-dom';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
import { DotsPattern } from '@shared/icons';
|
||||
|
||||
export function BrowseScreen() {
|
||||
return (
|
||||
<div className="relative h-full w-full">
|
||||
<div className="absolute left-0 right-0 top-4 flex w-full items-center justify-between px-3">
|
||||
<div className="absolute left-0 right-0 top-4 z-30 flex w-full items-center justify-between px-3">
|
||||
<div className="w-10" />
|
||||
<div className="inline-flex gap-1 rounded-full border-t border-white/10 bg-white/20 p-1">
|
||||
<div className="inline-flex gap-1 rounded-full border-t border-white/10 bg-white/20 p-1 backdrop-blur-xl">
|
||||
<NavLink
|
||||
to="/browse/"
|
||||
className={({ isActive }) =>
|
||||
@@ -32,7 +34,12 @@ export function BrowseScreen() {
|
||||
</div>
|
||||
<div className="w-10" />
|
||||
</div>
|
||||
<Outlet />
|
||||
<div className="absolute z-10 h-full w-full">
|
||||
<DotsPattern className="h-full w-full text-white/10" />
|
||||
</div>
|
||||
<div className="relative z-20">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { UserDrawer } from '@app/browse/components/userDrawer';
|
||||
|
||||
import { useStorage } from '@libs/storage/provider';
|
||||
|
||||
import { User } from '@shared/user';
|
||||
|
||||
import { getMultipleRandom } from '@utils/transform';
|
||||
|
||||
export function BrowseUsersScreen() {
|
||||
const { db } = useStorage();
|
||||
const data = useMemo(() => getMultipleRandom(db.account.follows, 10), []);
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<div>
|
||||
<User pubkey={db.account.pubkey} variant="avatar" />
|
||||
<div className="mt-4 flex flex-col gap-2">
|
||||
{db.account.follows.map((user) => (
|
||||
<UserDrawer key={user} pubkey={user} />
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
<User pubkey={db.account.pubkey} variant="avatar" />
|
||||
<div className="flex items-center gap-4">
|
||||
{data.map((user) => (
|
||||
<UserDrawer key={user} pubkey={user} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||
import { BaseDirectory, removeFile } from '@tauri-apps/api/fs';
|
||||
import { Platform } from '@tauri-apps/api/os';
|
||||
import Database from 'tauri-plugin-sql-api';
|
||||
import { Stronghold } from 'tauri-plugin-stronghold-api';
|
||||
|
||||
@@ -11,13 +10,11 @@ import { Account, DBEvent, Relays, Widget } from '@utils/types';
|
||||
|
||||
export class LumeStorage {
|
||||
public db: Database;
|
||||
public platform: Platform;
|
||||
public secureDB: Stronghold;
|
||||
public account: Account | null = null;
|
||||
|
||||
constructor(sqlite: Database, platform: Platform, stronghold?: Stronghold) {
|
||||
constructor(sqlite: Database, stronghold?: Stronghold) {
|
||||
this.db = sqlite;
|
||||
this.platform = platform ?? undefined;
|
||||
this.secureDB = stronghold ?? undefined;
|
||||
this.account = null;
|
||||
}
|
||||
@@ -59,6 +56,13 @@ export class LumeStorage {
|
||||
return await removeFile('lume.stronghold', { dir: BaseDirectory.AppConfig });
|
||||
}
|
||||
|
||||
public async checkAccount() {
|
||||
const result: Array<Account> = await this.db.select(
|
||||
'SELECT * FROM accounts WHERE is_active = 1;'
|
||||
);
|
||||
return result.length > 0;
|
||||
}
|
||||
|
||||
public async getActiveAccount() {
|
||||
const results: Array<Account> = await this.db.select(
|
||||
'SELECT * FROM accounts WHERE is_active = "1" ORDER BY id DESC LIMIT 1;'
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { message } from '@tauri-apps/api/dialog';
|
||||
import { platform } from '@tauri-apps/api/os';
|
||||
import { appConfigDir } from '@tauri-apps/api/path';
|
||||
import { PropsWithChildren, createContext, useContext, useEffect, useState } from 'react';
|
||||
import Database from 'tauri-plugin-sql-api';
|
||||
|
||||
@@ -17,14 +15,10 @@ const StorageContext = createContext<StorageContext>({
|
||||
const StorageProvider = ({ children }: PropsWithChildren<object>) => {
|
||||
const [db, setDB] = useState<LumeStorage>(undefined);
|
||||
|
||||
async function initLumeStorage() {
|
||||
const initLumeStorage = async () => {
|
||||
try {
|
||||
const dir = await appConfigDir();
|
||||
const sqlite = await Database.load('sqlite:lume.db');
|
||||
const platformName = await platform();
|
||||
const lumeStorage = new LumeStorage(sqlite, platformName);
|
||||
|
||||
console.log('App config dir: ', dir);
|
||||
const lumeStorage = new LumeStorage(sqlite);
|
||||
|
||||
if (!lumeStorage.account) await lumeStorage.getActiveAccount();
|
||||
setDB(lumeStorage);
|
||||
@@ -34,7 +28,7 @@ const StorageProvider = ({ children }: PropsWithChildren<object>) => {
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!db) initLumeStorage();
|
||||
|
||||
20
src/shared/icons/dots.tsx
Normal file
20
src/shared/icons/dots.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { SVGProps } from 'react';
|
||||
|
||||
export function DotsPattern(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg {...props}>
|
||||
<pattern
|
||||
id="pattern-circles"
|
||||
width="30"
|
||||
height="30"
|
||||
x="0"
|
||||
y="0"
|
||||
patternContentUnits="userSpaceOnUse"
|
||||
patternUnits="userSpaceOnUse"
|
||||
>
|
||||
<circle cx="2" cy="2" r="1.626" fill="currentColor"></circle>
|
||||
</pattern>
|
||||
<rect width="100%" height="100%" x="0" y="0" fill="url(#pattern-circles)"></rect>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -65,3 +65,4 @@ export * from './alby';
|
||||
export * from './stars';
|
||||
export * from './nwc';
|
||||
export * from './timeline';
|
||||
export * from './dots';
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import Database from 'tauri-plugin-sql-api';
|
||||
|
||||
import { Account } from '@utils/types';
|
||||
|
||||
async function connect(): Promise<Database> {
|
||||
let db: null | Database = null;
|
||||
|
||||
if (db) {
|
||||
return db;
|
||||
}
|
||||
|
||||
try {
|
||||
db = await Database.load('sqlite:lume.db');
|
||||
} catch (e) {
|
||||
throw new Error('Failed to connect to database, error: ', e);
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
export async function checkActiveAccount() {
|
||||
const db = await connect();
|
||||
const result: Array<Account> = await db.select(
|
||||
'SELECT * FROM accounts WHERE is_active = 1;'
|
||||
);
|
||||
|
||||
return result.length > 0;
|
||||
}
|
||||
@@ -24,3 +24,9 @@ export function getRepostID(tags: NDKTag[]) {
|
||||
|
||||
return quoteID;
|
||||
}
|
||||
|
||||
// get random n elements from array
|
||||
export function getMultipleRandom(arr: string[], num: number) {
|
||||
const shuffled = [...arr].sort(() => 0.5 - Math.random());
|
||||
return shuffled.slice(0, num);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user