diff --git a/src/components/TelegramConnectionModal.tsx b/src/components/TelegramConnectionModal.tsx
index 973a13e8f..ce590cd61 100644
--- a/src/components/TelegramConnectionModal.tsx
+++ b/src/components/TelegramConnectionModal.tsx
@@ -125,7 +125,7 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
}
resolve(password.trim());
};
-
+
// Set a timeout to prevent hanging forever
setTimeout(() => {
if (passwordResolverRef.current) {
@@ -139,7 +139,7 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
async (err) => {
// Handle errors
const errorMessage = err.message || 'Authentication error';
-
+
// Check if it's a 2FA password needed error
if (errorMessage.includes('SESSION_PASSWORD_NEEDED') || errorMessage.includes('PASSWORD')) {
// This should trigger the password callback, but if it doesn't, handle it here
@@ -178,7 +178,7 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
} catch (err) {
setIsAuthenticating(false);
const errorMessage = err instanceof Error ? err.message : 'Authentication failed';
-
+
// If it's a password needed error, we should already be on the 2FA step
// Don't show it as an error, just log it
if (errorMessage.includes('SESSION_PASSWORD_NEEDED')) {
@@ -190,7 +190,7 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
}
return; // Don't show error, password callback should handle it
}
-
+
setError(errorMessage);
setCurrentStep('error');
dispatch(setAuthError(errorMessage));
@@ -207,7 +207,7 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
const updateTimer = () => {
const remaining = Math.max(0, Math.floor((qrCodeExpires * 1000 - Date.now()) / 1000));
setTimeRemaining(remaining);
-
+
// If timer reaches 0 and we're on QR step, reload the QR code
if (remaining === 0 && currentStep === 'qr' && !isAuthenticating) {
startQrCodeFlow();
@@ -235,7 +235,7 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
if (!client) return;
const isAuthorized = await client.checkAuthorization();
-
+
if (isAuthorized) {
// User is authenticated - check if we need password
try {
@@ -277,12 +277,12 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
const handle2FASubmit = async () => {
const passwordValue = password.trim();
-
+
if (!passwordValue) {
setError('Please enter your password');
return;
}
-
+
if (!passwordResolverRef.current) {
console.error('Password resolver is null - password callback may not be active');
setError('Authentication session expired. Please try again.');
@@ -298,10 +298,10 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
// This will pass the password to the Telegram library
const resolver = passwordResolverRef.current;
passwordResolverRef.current = null; // Clear before resolving to prevent double calls
-
+
console.log('Resolving password promise - sending password to Telegram');
resolver(passwordValue);
-
+
// The authentication will continue in the background via signInWithQrCode
// The success/error will be handled by the signInWithQrCode promise
// We keep isAuthenticating true until the promise resolves or rejects
@@ -340,9 +340,9 @@ const TelegramConnectionModal = ({ isOpen, onClose, onComplete }: TelegramConnec
if (!isOpen) return null;
const modalContent = (
-
-
- {/* Close button */}
-
-
-
-
-
+ {/* Close button */}
+
+
+
+
+
- {currentStep === 'loading' ? (
-
-
-
Initializing Telegram connection...
+ {currentStep === 'loading' ? (
+
+
+
Initializing Telegram connection...
+
+ ) : currentStep === 'error' ? (
+ <>
+ {/* Error Screen */}
+
+
+
Connection Error
+
{error || 'An error occurred'}
+
+
+ Cancel
+
+
+ Retry
+
+
- ) : currentStep === 'error' ? (
- <>
- {/* Error Screen */}
-
-
-
Connection Error
-
{error || 'An error occurred'}
-
-
- Cancel
-
-
- Retry
-
+ >
+ ) : currentStep === 'qr' ? (
+ <>
+ {/* QR Code Screen */}
+
+ {/* QR Code Container */}
+
+
+ {qrCodeUrl ? (
+
+
+
+ ) : (
+
+ {isAuthenticating ? (
+
+
+
Generating QR code...
+
+ ) : (
+
Loading QR code...
+ )}
+
+ )}
- >
- ) : currentStep === 'qr' ? (
- <>
- {/* QR Code Screen */}
-
- {/* QR Code Container */}
-
-
- {qrCodeUrl ? (
-
-
-
- ) : (
-
- {isAuthenticating ? (
-
-
-
Generating QR code...
-
- ) : (
-
Loading QR code...
- )}
-
- )}
-
-
- {qrCodeExpires && timeRemaining > 0 && (
-
- This code expires in {timeRemaining} seconds
-
- )}
-
- {error && (
-
- )}
-
- {/* Instructions */}
-
-
-
- 1
-
-
Open Telegram on your phone
-
-
-
-
- 2
-
-
Go to Settings > Devices > Link Desktop Device
-
-
-
-
- 3
-
-
Point your phone at this screen to confirm login
-
-
-
- >
- ) : (
- <>
- {/* 2FA Screen */}
-
-
Enter Your Password
-
- {passwordHint
- ? `Your account is protected with two-step verification. Hint: ${passwordHint}`
- : 'Your account is protected with two-step verification. Please enter your password to continue.'}
+ {qrCodeExpires && timeRemaining > 0 && (
+
+ This code expires in {timeRemaining} seconds
+ )}
- {error && (
-
-
{error}
+ {error && (
+
+ )}
+
+ {/* Instructions */}
+
+
+
+ 1
- )}
-
- {/* Password input */}
-
-
setPassword(e.target.value)}
- onKeyDown={(e) => {
- if (e.key === 'Enter' && password.trim() && !isAuthenticating) {
- handle2FASubmit();
- }
- }}
- placeholder="Enter your password"
- className="w-full px-4 py-3 bg-black/50 border border-stone-700 rounded-xl text-white placeholder-opacity-50 focus:outline-none focus:border-primary-500 transition-colors"
- autoComplete="off"
- data-form-type="other"
- data-lpignore="true"
- data-1p-ignore="true"
- data-bwignore="true"
- data-dashlane-ignore="true"
- data-bitwarden-watching="false"
- autoFocus
- disabled={isAuthenticating}
- />
+
Open Telegram on your phone
- {/* Action buttons */}
-
-
- Back
-
-
- {isAuthenticating ? 'Verifying...' : 'Continue'}
-
+
+
+ 2
+
+
Go to Settings > Devices > Link Desktop Device
+
+
+
+
+ 3
+
+
Point your phone at this screen to confirm login
- >
- )}
-
+
+ >
+ ) : (
+ <>
+ {/* 2FA Screen */}
+
+
Enter Your Password
+
+ {passwordHint
+ ? `Your account is protected with two-step verification. Hint: ${passwordHint}`
+ : 'Your account is protected with two-step verification. Please enter your password to continue.'}
+
+
+ {error && (
+
+ )}
+
+ {/* Password input */}
+
+ setPassword(e.target.value)}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' && password.trim() && !isAuthenticating) {
+ handle2FASubmit();
+ }
+ }}
+ placeholder="Enter your password"
+ className="w-full px-4 py-3 bg-black/50 border border-stone-700 rounded-xl text-white placeholder-opacity-50 focus:outline-none focus:border-primary-500 transition-colors"
+ autoComplete="off"
+ data-form-type="other"
+ data-lpignore="true"
+ data-1p-ignore="true"
+ data-bwignore="true"
+ data-dashlane-ignore="true"
+ data-bitwarden-watching="false"
+ autoFocus
+ disabled={isAuthenticating}
+ />
+
+
+ {/* Action buttons */}
+
+
+ Back
+
+
+ {isAuthenticating ? 'Verifying...' : 'Continue'}
+
+
+
+ >
+ )}
+
);
diff --git a/src/pages/onboarding/steps/ConnectStep.tsx b/src/pages/onboarding/steps/ConnectStep.tsx
index 9f6a78472..1a4e06c9e 100644
--- a/src/pages/onboarding/steps/ConnectStep.tsx
+++ b/src/pages/onboarding/steps/ConnectStep.tsx
@@ -2,10 +2,10 @@ import { useState } from 'react';
import GoogleIcon from '../../../assets/icons/GoogleIcon';
import TelegramConnectionModal from '../../../components/TelegramConnectionModal';
-import BinanceIcon from './icons/binance.svg';
-import NotionIcon from './icons/notion.svg';
-import TelegramIcon from './icons/telegram.svg';
-import MetamaskIcon from './icons/metamask.svg';
+import BinanceIcon from '../../../assets/icons/binance.svg';
+import NotionIcon from '../../../assets/icons/notion.svg';
+import TelegramIcon from '../../../assets/icons/telegram.svg';
+import MetamaskIcon from '../../../assets/icons/metamask.svg';
interface ConnectStepProps {
diff --git a/src/store/telegram/reducers.ts b/src/store/telegram/reducers.ts
index e4b3e6842..93e6db5a9 100644
--- a/src/store/telegram/reducers.ts
+++ b/src/store/telegram/reducers.ts
@@ -1,4 +1,4 @@
-import { PayloadAction } from '@reduxjs/toolkit';
+import { PayloadAction } from "@reduxjs/toolkit";
import type {
TelegramState,
TelegramConnectionStatus,
@@ -7,50 +7,74 @@ import type {
TelegramChat,
TelegramMessage,
TelegramThread,
-} from './types';
+} from "./types";
export const reducers = {
// Connection actions
- setConnectionStatus: (state: TelegramState, action: PayloadAction
) => {
+ setConnectionStatus: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.connectionStatus = action.payload;
- if (action.payload !== 'error') {
+ if (action.payload !== "error") {
state.connectionError = null;
}
},
- setConnectionError: (state: TelegramState, action: PayloadAction) => {
+ setConnectionError: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.connectionError = action.payload;
if (action.payload) {
- state.connectionStatus = 'error';
+ state.connectionStatus = "error";
}
},
// Authentication actions
- setAuthStatus: (state: TelegramState, action: PayloadAction) => {
+ setAuthStatus: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.authStatus = action.payload;
- if (action.payload !== 'error') {
+ if (action.payload !== "error") {
state.authError = null;
}
},
- setAuthError: (state: TelegramState, action: PayloadAction) => {
+ setAuthError: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.authError = action.payload;
if (action.payload) {
- state.authStatus = 'error';
+ state.authStatus = "error";
}
},
- setPhoneNumber: (state: TelegramState, action: PayloadAction) => {
+ setPhoneNumber: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.phoneNumber = action.payload;
},
- setSessionString: (state: TelegramState, action: PayloadAction) => {
+ setSessionString: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.sessionString = action.payload;
},
// User actions
- setCurrentUser: (state: TelegramState, action: PayloadAction) => {
+ setCurrentUser: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.currentUser = action.payload;
},
// Chat actions
- setChats: (state: TelegramState, action: PayloadAction>) => {
+ setChats: (
+ state: TelegramState,
+ action: PayloadAction>,
+ ) => {
state.chats = action.payload;
},
addChat: (state: TelegramState, action: PayloadAction) => {
@@ -60,7 +84,10 @@ export const reducers = {
state.chatsOrder.unshift(chat.id);
}
},
- updateChat: (state: TelegramState, action: PayloadAction & { id: string }>) => {
+ updateChat: (
+ state: TelegramState,
+ action: PayloadAction & { id: string }>,
+ ) => {
const { id, ...updates } = action.payload;
if (state.chats[id]) {
state.chats[id] = { ...state.chats[id], ...updates };
@@ -74,7 +101,10 @@ export const reducers = {
state.selectedChatId = null;
}
},
- setSelectedChat: (state: TelegramState, action: PayloadAction) => {
+ setSelectedChat: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.selectedChatId = action.payload;
// Clear selected thread when changing chat
if (action.payload !== state.selectedChatId) {
@@ -86,7 +116,10 @@ export const reducers = {
},
// Message actions
- addMessage: (state: TelegramState, action: PayloadAction) => {
+ addMessage: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
const message = action.payload;
const { chatId, id } = message;
@@ -100,7 +133,10 @@ export const reducers = {
state.messagesOrder[chatId].push(id);
}
},
- addMessages: (state: TelegramState, action: PayloadAction<{ chatId: string; messages: TelegramMessage[] }>) => {
+ addMessages: (
+ state: TelegramState,
+ action: PayloadAction<{ chatId: string; messages: TelegramMessage[] }>,
+ ) => {
const { chatId, messages } = action.payload;
if (!state.messages[chatId]) {
@@ -117,7 +153,11 @@ export const reducers = {
},
updateMessage: (
state: TelegramState,
- action: PayloadAction<{ chatId: string; messageId: string; updates: Partial }>
+ action: PayloadAction<{
+ chatId: string;
+ messageId: string;
+ updates: Partial;
+ }>,
) => {
const { chatId, messageId, updates } = action.payload;
if (state.messages[chatId]?.[messageId]) {
@@ -127,12 +167,15 @@ export const reducers = {
};
}
},
- removeMessage: (state: TelegramState, action: PayloadAction<{ chatId: string; messageId: string }>) => {
+ removeMessage: (
+ state: TelegramState,
+ action: PayloadAction<{ chatId: string; messageId: string }>,
+ ) => {
const { chatId, messageId } = action.payload;
if (state.messages[chatId]?.[messageId]) {
delete state.messages[chatId][messageId];
state.messagesOrder[chatId] = state.messagesOrder[chatId].filter(
- (id) => id !== messageId
+ (id) => id !== messageId,
);
}
},
@@ -159,7 +202,11 @@ export const reducers = {
},
updateThread: (
state: TelegramState,
- action: PayloadAction<{ chatId: string; threadId: string; updates: Partial }>
+ action: PayloadAction<{
+ chatId: string;
+ threadId: string;
+ updates: Partial;
+ }>,
) => {
const { chatId, threadId, updates } = action.payload;
if (state.threads[chatId]?.[threadId]) {
@@ -169,15 +216,24 @@ export const reducers = {
};
}
},
- setSelectedThread: (state: TelegramState, action: PayloadAction) => {
+ setSelectedThread: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.selectedThreadId = action.payload;
},
// Search actions
- setSearchQuery: (state: TelegramState, action: PayloadAction) => {
+ setSearchQuery: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.searchQuery = action.payload;
},
- setFilteredChatIds: (state: TelegramState, action: PayloadAction) => {
+ setFilteredChatIds: (
+ state: TelegramState,
+ action: PayloadAction,
+ ) => {
state.filteredChatIds = action.payload;
},