diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx index b5b7f78..09b0b5e 100644 --- a/src/components/Dashboard.jsx +++ b/src/components/Dashboard.jsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { SegmentedControlSingleChoice, Skeleton } from "@deriv-com/quill-ui"; import { useAuth } from "../hooks/useAuth.jsx"; import useSettings from "../hooks/useSettings.js"; @@ -17,6 +17,13 @@ const Dashboard = () => { settings?.allow_copiers ? "trader" : "copier" ); + // Update userType when settings change + useEffect(() => { + if (settings) { + setUserType(settings.allow_copiers ? "trader" : "copier"); + } + }, [settings]); + const isLoading = authLoading || settingsLoading; return ( @@ -31,9 +38,11 @@ const Dashboard = () => { options={[ { label: "Copy", + disabled: isLoading, }, { label: "Trade", + disabled: isLoading, }, ]} selectedItemIndex={userType === "copier" ? 0 : 1} diff --git a/src/hooks/useSettings.js b/src/hooks/useSettings.js index 31168e8..81031c9 100644 --- a/src/hooks/useSettings.js +++ b/src/hooks/useSettings.js @@ -1,94 +1,106 @@ -import { useState, useEffect, useCallback, useRef } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import useWebSocket from './useWebSocket'; import { useAuth } from '../hooks/useAuth.jsx'; const useSettings = () => { const [settings, setSettings] = useState(null); const [error, setError] = useState(null); - const [isLoading, setIsLoading] = useState(true); + const [isLoading, setIsLoading] = useState(false); const { isAuthorized, isConnected } = useAuth(); const { sendMessage } = useWebSocket(); - const hasInitialFetch = useRef(false); - const lastUpdateCall = useRef(null); const fetchSettings = useCallback(() => { - if (!isConnected || !isAuthorized || hasInitialFetch.current) { - return; - } - - setIsLoading(true); - console.log('Fetching user settings'); - hasInitialFetch.current = true; - sendMessage( - { get_settings: 1 }, - (response) => { - if (response.error) { - console.error('Failed to fetch settings:', response.error); - setError(response.error); - } else { - console.log('Settings received:', response.get_settings); - setSettings(response.get_settings); - setError(null); - } - setIsLoading(false); - } - ); - }, [isConnected, isAuthorized, sendMessage]); - - // Fetch settings on mount and when connection/auth state changes - useEffect(() => { - if (isConnected && isAuthorized) { - fetchSettings(); - } - }, [isConnected, isAuthorized, fetchSettings]); - - // Reset settings and fetch flag when connection is lost - useEffect(() => { - if (!isConnected) { - setSettings(null); - setIsLoading(true); - hasInitialFetch.current = false; - } - }, [isConnected]); - - const updateSettings = useCallback(async (newSettings) => { if (!isConnected || !isAuthorized) { - throw new Error('Not connected or authorized'); + return Promise.reject(new Error('Not connected or authorized')); } - // Add debounce to prevent rapid settings updates - const now = Date.now(); - if (lastUpdateCall.current && now - lastUpdateCall.current < 1000) { - throw new Error('Please wait before updating settings again'); + // Return cached settings if available + if (settings !== null) { + return Promise.resolve(settings); } - lastUpdateCall.current = now; + setIsLoading(true); + setError(null); + + // Fetch fresh settings only if cache is empty return new Promise((resolve, reject) => { sendMessage( - { set_settings: 1, ...newSettings }, + { get_settings: 1 }, (response) => { if (response.error) { - console.error('Failed to update settings:', response.error); + console.error('Failed to fetch settings:', response.error); setError(response.error); + setIsLoading(false); reject(response.error); } else { - console.log('Settings updated:', response.set_settings); - // After successful update, reset fetch flag and get fresh settings - hasInitialFetch.current = false; - fetchSettings(); - resolve(response.set_settings); + console.log('Settings received:', response.get_settings); + setSettings(response.get_settings); + setError(null); + setIsLoading(false); + resolve(response.get_settings); } } ); }); }, [isConnected, isAuthorized, sendMessage]); + const updateSettings = useCallback(async (newSettings) => { + if (!isConnected || !isAuthorized) { + throw new Error('Not connected or authorized'); + } + + setIsLoading(true); + setError(null); + + try { + // First update the settings + await new Promise((resolve, reject) => { + sendMessage( + { set_settings: 1, ...newSettings }, + (response) => { + if (response.error) { + console.error('Failed to update settings:', response.error); + reject(response.error); + } else { + console.log('Settings updated:', response.set_settings); + resolve(response.set_settings); + } + } + ); + }); + + // Then fetch fresh settings + await fetchSettings(); + } catch (err) { + setError(err); + throw err; + } finally { + setIsLoading(false); + } + }, [isConnected, isAuthorized, sendMessage, fetchSettings]); + + // Initial fetch on mount and when connection/auth changes + useEffect(() => { + if (isConnected && isAuthorized) { + fetchSettings(); + } + }, [isConnected, isAuthorized, fetchSettings]); + + // Reset state when connection is lost + useEffect(() => { + if (!isConnected) { + setSettings(null); + setError(null); + setIsLoading(false); + } + }, [isConnected]); + return { settings, error, isLoading, - updateSettings, - fetchSettings + fetchSettings, + updateSettings }; };