diff --git a/.prettierrc b/.prettierrc index 9a5be66..fe4ca68 100644 --- a/.prettierrc +++ b/.prettierrc @@ -5,13 +5,9 @@ "singleQuote": true, "semi": true, "importOrder": [ - "^react.*", - "^next.*", + "^\\w+.*", "^@", - "^#/components/ui/(.*)$", - "^#/components/(.*)$", "^#/(.*)$", - "^#/lib/(.*)$", "^[./]" ], "importOrderSeparation": true, diff --git a/app/add-account/page.tsx b/app/add-account/page.tsx index 5764a99..4cbadb3 100644 --- a/app/add-account/page.tsx +++ b/app/add-account/page.tsx @@ -1,16 +1,12 @@ import { unstable_noStore as notStore } from 'next/cache'; import AddAccount from '#/lib/components/accounts/add'; -import { env } from '#/lib/env'; function Page() { notStore(); return (
- +
); } diff --git a/app/page.tsx b/app/page.tsx index 7fa26db..88f8ae1 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,10 +1,7 @@ import { unstable_noStore as notStore } from 'next/cache'; -import Image from 'next/image'; +import { redirect } from 'next/navigation'; -import AddAccount from '#/lib/components/accounts/add'; import AccountPicker from '#/lib/components/accounts/picker'; -import { env } from '#/lib/env'; -import logo from '#/lib/logo.svg'; import { getAccounts } from '#/lib/services/accounts'; async function Home() { @@ -12,30 +9,7 @@ async function Home() { const accounts = await getAccounts(); if (accounts.length === 0) { - return ( -
- -
- DriveGram -

- DriveGram -

-

- Personal cloud storage powered by - Telegram -

-
-
- ); + redirect('/add-account'); } return ( diff --git a/components.json b/components.json index 7709631..da33f42 100644 --- a/components.json +++ b/components.json @@ -14,4 +14,4 @@ "components": "#/lib/components", "utils": "#/lib/utils" } -} \ No newline at end of file +} diff --git a/lib/client/context.ts b/lib/client/context.ts index ee6f0c8..753be9b 100644 --- a/lib/client/context.ts +++ b/lib/client/context.ts @@ -1,6 +1,5 @@ -import { TelegramClient } from 'telegram'; - import { createContext, useContext } from 'react'; +import { TelegramClient } from 'telegram'; export const clientContext = createContext( {} as TelegramClient, diff --git a/lib/client/provider.tsx b/lib/client/provider.tsx index 4a24678..b7e89ae 100644 --- a/lib/client/provider.tsx +++ b/lib/client/provider.tsx @@ -1,11 +1,10 @@ 'use client'; +import { useEffect, useState } from 'react'; import { toast } from 'sonner'; import { TelegramClient } from 'telegram'; import { StringSession } from 'telegram/sessions'; -import { useEffect, useState } from 'react'; - import AddAccount from '../components/accounts/add'; import { clientContext } from './context'; diff --git a/lib/components/accounts/add.tsx b/lib/components/accounts/add.tsx index d6ed5b8..06954a3 100644 --- a/lib/components/accounts/add.tsx +++ b/lib/components/accounts/add.tsx @@ -1,13 +1,8 @@ 'use client'; -import { toast } from 'sonner'; -import { Api, TelegramClient } from 'telegram'; -import { StringSession } from 'telegram/sessions'; - -import { useRef, useState } from 'react'; - -import Link from 'next/link'; import { useRouter } from 'next/navigation'; +import { useRef, useState } from 'react'; +import { toast } from 'sonner'; import { trpc } from '#/lib/trpc/client'; @@ -22,26 +17,21 @@ import { } from '../ui/card'; import { Input } from '../ui/input'; -let resolvers = new Map(); - -function AddAccount({ - apiId, - apiHash, -}: { - apiId: number; - apiHash: string; -}) { +function AddAccount() { const r = useRouter(); - const saveSession = - trpc.saveAccountSession.useMutation(); - const [client, setClient] = - useState(null); + const sendPhoneCode = + trpc.sendPhoneCode.useMutation(); - const [loading, setLoading] = useState(false); + const verifyOtp = trpc.verifyOtp.useMutation(); - const [user, setUser] = - useState | null>(null); + const verifyPass = + trpc.verifyPassword.useMutation(); + + const [user, setUser] = useState<{ + id: string; + firstName: string; + } | null>(null); const [step, setStep] = useState(1); @@ -56,64 +46,17 @@ function AddAccount({ refs.phoneNumber.current?.value; if (!phoneNumber) { - toast.error('Please fill all fields'); + toast.error('Please enter phone number'); return; } - let _client = client; - if (!_client) { - (_client = new TelegramClient( - new StringSession(''), - apiId, - apiHash, - { - connectionRetries: 5, - }, - )), - setClient(_client); - } - setLoading(true); - - try { - await _client.start({ + await sendPhoneCode + .mutateAsync({ phoneNumber, - phoneCode: async () => { - setStep(2); - setLoading(false); - return new Promise((resolve) => { - resolvers.set('phoneCode', resolve); - }); - }, - password: async () => { - setStep(3); - setLoading(false); - if (refs.otp.current) { - refs.otp.current.value = ''; - } - return new Promise((resolve) => { - resolvers.set('password', resolve); - }); - }, - onError: (err) => { - setLoading(false); - toast.error(err.message); - }, + }) + .then(() => { + setStep(2); }); - } catch (err) { - setLoading(false); - if (err instanceof Error) { - toast.error(err.message); - } else toast.error('Failed to send OTP'); - return; - } - - try { - setLoading(false); - const user = await _client.getMe(); - setUser(user); - } catch (e) { - toast.error('Failed to get user'); - } } async function handleVerifyOtp() { @@ -125,47 +68,57 @@ function AddAccount({ return; } - const otpResolver = - resolvers.get('phoneCode'); - if (!otpResolver) return; - - setLoading(true); - await otpResolver(otp); + await verifyOtp + .mutateAsync({ + code: otp, + }) + .then((res) => { + if (res.error) { + toast.error(res.error); + return; + } + + if (res.next === 'require_password') { + setStep(3); + } else { + if (res.id) { + setUser({ + id: res.id, + firstName: res.firstName, + }); + } + } + }); } - async function handleVerifyPassword( - skip?: boolean, - ) { + async function handleVerifyPassword() { const password = refs.password.current?.value; - if (!password && !skip) { + if (!password) { toast.error('Please enter password'); return; } - const passwordResolver = - resolvers.get('password'); - - if (!passwordResolver) return; - - setLoading(true); - await passwordResolver(password); + await verifyPass + .mutateAsync({ + password: password, + }) + .then((res) => { + if (res.id) { + setUser({ + id: res.id, + firstName: res.firstName, + }); + } else { + toast.error( + res.error || 'An error occurred', + ); + } + }); } async function handleSaveSession() { - if (client && user) { - setLoading(true); - const session = client.session.save() + ''; - saveSession - .mutateAsync({ - accountId: user.id?.toString()!, - name: user.firstName!, - session, - }) - .then(() => { - r.push(`/account/${user.id}`); - }); - } + r.push(`/account/${user?.id}`); } if (user) { @@ -181,7 +134,6 @@ function AddAccount({ @@ -242,7 +194,7 @@ function AddAccount({ {step === 2 && ( @@ -253,9 +205,9 @@ function AddAccount({ onClick={() => { handleVerifyPassword(); }} - isLoading={loading} + isLoading={verifyPass.isLoading} > - Continue + Verify Password )} diff --git a/lib/components/accounts/picker.tsx b/lib/components/accounts/picker.tsx index 0625fb7..1a0932f 100644 --- a/lib/components/accounts/picker.tsx +++ b/lib/components/accounts/picker.tsx @@ -1,6 +1,5 @@ -import React from 'react'; - import Link from 'next/link'; +import React from 'react'; import { Button } from '#/lib/components/ui/button'; import { @@ -34,7 +33,7 @@ function AccountPicker({ key={account.id} href={`/account/${account.id}`} > - +

{account.name}

diff --git a/lib/components/common/sidebar.tsx b/lib/components/common/sidebar.tsx index 9d81320..2621715 100644 --- a/lib/components/common/sidebar.tsx +++ b/lib/components/common/sidebar.tsx @@ -7,13 +7,12 @@ import { SettingsIcon, TrashIcon, } from 'lucide-react'; -import prettyBytes from 'pretty-bytes'; - import Link from 'next/link'; import { useParams, usePathname, } from 'next/navigation'; +import prettyBytes from 'pretty-bytes'; import { Card } from '../ui/card'; import FileStats from './file-stats'; diff --git a/lib/components/file-manager/files/item.tsx b/lib/components/file-manager/files/item.tsx index b54edcf..22c2f3e 100644 --- a/lib/components/file-manager/files/item.tsx +++ b/lib/components/file-manager/files/item.tsx @@ -14,7 +14,6 @@ import { TrashIcon, VideoIcon, } from 'lucide-react'; - import React, { useMemo, useState } from 'react'; import { @@ -91,7 +90,7 @@ function FileItem({ {file.isBookmarked && ( )} diff --git a/lib/components/file-manager/folders/item.tsx b/lib/components/file-manager/folders/item.tsx index 66f81ee..de7d7f9 100644 --- a/lib/components/file-manager/folders/item.tsx +++ b/lib/components/file-manager/folders/item.tsx @@ -9,7 +9,6 @@ import { InfoIcon, TrashIcon, } from 'lucide-react'; - import React, { useState } from 'react'; import { diff --git a/lib/components/file-manager/list.tsx b/lib/components/file-manager/list.tsx index 76fd7f7..3ce05fd 100644 --- a/lib/components/file-manager/list.tsx +++ b/lib/components/file-manager/list.tsx @@ -1,10 +1,8 @@ 'use client'; import { AnimatePresence } from 'framer-motion'; - -import React from 'react'; - import { useRouter } from 'next/navigation'; +import React from 'react'; import { useFileManager } from '#/lib/file-manager'; @@ -99,7 +97,7 @@ function ListItems() { )} -
+
{selectedFile ? ( & { - separator?: React.ReactNode + React.ComponentPropsWithoutRef<'nav'> & { + separator?: React.ReactNode; } ->(({ ...props }, ref) =>