feat(throttling): add global rate limit lockout flow
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
} from "../api/notifications"
|
||||
import { useTranslation } from "../hooks/useTranslation"
|
||||
import { presentNotification } from "../lib/notificationPresenter"
|
||||
import { isRateLimitActive } from "../lib/rateLimit"
|
||||
import {
|
||||
getAccessToken,
|
||||
SESSION_CHANGED_EVENT,
|
||||
@@ -171,7 +172,7 @@ export function NotificationsProvider({ children }: { children: ReactNode }) {
|
||||
)
|
||||
|
||||
const refreshNotifications = useCallback(async () => {
|
||||
if (!getAccessToken()) {
|
||||
if (!getAccessToken() || isRateLimitActive()) {
|
||||
setNotifications([])
|
||||
setUnreadCount(0)
|
||||
setTotalCount(0)
|
||||
@@ -279,7 +280,7 @@ export function NotificationsProvider({ children }: { children: ReactNode }) {
|
||||
}, [markAsSeen, openNotificationTarget, t.notifications])
|
||||
|
||||
const connectToStream = useCallback(async () => {
|
||||
if (!getAccessToken()) {
|
||||
if (!getAccessToken() || isRateLimitActive()) {
|
||||
closeEventSource()
|
||||
setConnectionStatus("idle")
|
||||
return
|
||||
@@ -413,7 +414,7 @@ export function NotificationsProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
useEffect(() => {
|
||||
const startNotifications = async () => {
|
||||
if (!getAccessToken()) {
|
||||
if (!getAccessToken() || isRateLimitActive()) {
|
||||
closeEventSource()
|
||||
setNotifications([])
|
||||
setUnreadCount(0)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { createContext, useContext, useState, useEffect, type ReactNode } from "react"
|
||||
import { fetchWorkspaces, createWorkspace, type Workspace } from "../api/workspaces"
|
||||
import { useTranslation } from "../hooks/useTranslation"
|
||||
import { toast } from "sonner"
|
||||
import { Button } from "../components/ui/button"
|
||||
import { Input } from "../components/ui/input"
|
||||
import { fetchWorkspaces, createWorkspace, type Workspace } from "../api/workspaces"
|
||||
import { useTranslation } from "../hooks/useTranslation"
|
||||
import { isRateLimitActive } from "../lib/rateLimit"
|
||||
import { toast } from "sonner"
|
||||
import { Button } from "../components/ui/button"
|
||||
import { Input } from "../components/ui/input"
|
||||
|
||||
interface WorkspaceContextType {
|
||||
workspaces: Workspace[]
|
||||
@@ -31,9 +32,10 @@ export const WorkspaceProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [isCreatingFirst, setIsCreatingFirst] = useState(false)
|
||||
|
||||
const isAuthenticated = !!localStorage.getItem("accessToken")
|
||||
const rateLimited = isRateLimitActive()
|
||||
|
||||
const refreshWorkspaces = async () => {
|
||||
if (!isAuthenticated) {
|
||||
if (!isAuthenticated || isRateLimitActive()) {
|
||||
setIsLoading(false)
|
||||
return
|
||||
}
|
||||
@@ -66,13 +68,13 @@ export const WorkspaceProvider = ({ children }: { children: ReactNode }) => {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuthenticated) {
|
||||
if (!isAuthenticated || rateLimited) {
|
||||
setIsLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
void refreshWorkspaces()
|
||||
}, [isAuthenticated])
|
||||
}, [isAuthenticated, rateLimited])
|
||||
|
||||
const setActiveWorkspace = (workspace: Workspace | null) => {
|
||||
setActiveWorkspaceState(workspace)
|
||||
@@ -100,7 +102,7 @@ export const WorkspaceProvider = ({ children }: { children: ReactNode }) => {
|
||||
}
|
||||
|
||||
// Force workspace creation if authenticated but none exist
|
||||
if (!isLoading && isAuthenticated && workspaces.length === 0) {
|
||||
if (!rateLimited && !isLoading && isAuthenticated && workspaces.length === 0) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-slate-50 dark:bg-slate-900 px-4">
|
||||
<div className="w-full max-w-md bg-white dark:bg-slate-800 p-8 rounded-xl shadow-lg border border-slate-200 dark:border-slate-700">
|
||||
|
||||
Reference in New Issue
Block a user