Skip to content
Open

v2 #7

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@
"singleQuote": true,
"semi": true,
"importOrder": [
"^react.*",
"^next.*",
"^\\w+.*",
"^@",
"^#/components/ui/(.*)$",
"^#/components/(.*)$",
"^#/(.*)$",
"^#/lib/(.*)$",
"^[./]"
],
"importOrderSeparation": true,
Expand Down
6 changes: 1 addition & 5 deletions app/add-account/page.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="flex h-screen items-center justify-center bg-muted/50">
<AddAccount
apiId={env.TELEGRAM_API_ID}
apiHash={env.TELEGRAM_API_HASH}
/>
<AddAccount />
</div>
);
}
Expand Down
30 changes: 2 additions & 28 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,15 @@
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() {
notStore();
const accounts = await getAccounts();

if (accounts.length === 0) {
return (
<div className="relative flex h-screen items-center justify-center bg-muted/50">
<AddAccount
apiId={env.TELEGRAM_API_ID}
apiHash={env.TELEGRAM_API_HASH}
/>
<div className="absolute left-0 top-0 z-10 flex h-[45%] w-full flex-col items-center justify-center gap-2 bg-primary">
<Image
src={logo}
alt="DriveGram"
width={40}
height={40}
draggable={false}
/>
<h1 className="pt-4 text-4xl font-bold text-white">
DriveGram
</h1>
<p className="text-lg text-white/80">
Personal cloud storage powered by
Telegram
</p>
</div>
</div>
);
redirect('/add-account');
}

return (
Expand Down
2 changes: 1 addition & 1 deletion components.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
"components": "#/lib/components",
"utils": "#/lib/utils"
}
}
}
3 changes: 1 addition & 2 deletions lib/client/context.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { TelegramClient } from 'telegram';

import { createContext, useContext } from 'react';
import { TelegramClient } from 'telegram';

export const clientContext = createContext(
{} as TelegramClient,
Expand Down
3 changes: 1 addition & 2 deletions lib/client/provider.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
174 changes: 63 additions & 111 deletions lib/components/accounts/add.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -22,26 +17,21 @@ import {
} from '../ui/card';
import { Input } from '../ui/input';

let resolvers = new Map<string, Function>();

function AddAccount({
apiId,
apiHash,
}: {
apiId: number;
apiHash: string;
}) {
function AddAccount() {
const r = useRouter();
const saveSession =
trpc.saveAccountSession.useMutation();

const [client, setClient] =
useState<TelegramClient | null>(null);
const sendPhoneCode =
trpc.sendPhoneCode.useMutation();

const [loading, setLoading] = useState(false);
const verifyOtp = trpc.verifyOtp.useMutation();

const [user, setUser] =
useState<Partial<Api.User> | null>(null);
const verifyPass =
trpc.verifyPassword.useMutation();

const [user, setUser] = useState<{
id: string;
firstName: string;
} | null>(null);

const [step, setStep] = useState(1);

Expand All @@ -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() {
Expand All @@ -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) {
Expand All @@ -181,7 +134,6 @@ function AddAccount({
</CardHeader>
<CardFooter>
<Button
// isLoading={loading}
onClick={() => {
handleSaveSession();
}}
Expand Down Expand Up @@ -233,7 +185,7 @@ function AddAccount({
{step === 1 && (
<Button
onClick={handeSendOtp}
isLoading={loading}
isLoading={sendPhoneCode.isLoading}
>
Send OTP
</Button>
Expand All @@ -242,7 +194,7 @@ function AddAccount({
{step === 2 && (
<Button
onClick={handleVerifyOtp}
isLoading={loading}
isLoading={verifyOtp.isLoading}
>
Verify OTP
</Button>
Expand All @@ -253,9 +205,9 @@ function AddAccount({
onClick={() => {
handleVerifyPassword();
}}
isLoading={loading}
isLoading={verifyPass.isLoading}
>
Continue
Verify Password
</Button>
)}
</CardFooter>
Expand Down
5 changes: 2 additions & 3 deletions lib/components/accounts/picker.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -34,7 +33,7 @@ function AccountPicker({
key={account.id}
href={`/account/${account.id}`}
>
<Card className="hover:bg-muted p-4">
<Card className="p-4 hover:bg-muted">
<h1 className="font-semibold">
{account.name}
</h1>
Expand Down
3 changes: 1 addition & 2 deletions lib/components/common/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Loading