Skip to content

Commit

Permalink
fix: retry fixing get_settings rate limit issue (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
aum-deriv authored Jan 17, 2025
1 parent 4442092 commit ab9934b
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 60 deletions.
11 changes: 10 additions & 1 deletion src/components/Dashboard.jsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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 (
Expand All @@ -31,9 +38,11 @@ const Dashboard = () => {
options={[
{
label: "Copy",
disabled: isLoading,
},
{
label: "Trade",
disabled: isLoading,
},
]}
selectedItemIndex={userType === "copier" ? 0 : 1}
Expand Down
130 changes: 71 additions & 59 deletions src/hooks/useSettings.js
Original file line number Diff line number Diff line change
@@ -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
};
};

Expand Down

0 comments on commit ab9934b

Please sign in to comment.