Merge pull request #22846 from BerriAI/litellm_hide_bounce_icon

[Feature] Add option to hide bouncing icon in header
This commit is contained in:
yuneng-jiang 2026-03-04 19:59:29 -08:00 committed by GitHub
commit 6aeceb6512
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 63 additions and 7 deletions

View file

@ -0,0 +1,33 @@
import { LOCAL_STORAGE_EVENT, getLocalStorageItem } from "@/utils/localStorageUtils";
import { useSyncExternalStore } from "react";
function subscribe(callback: () => void) {
const onStorage = (e: StorageEvent) => {
if (e.key === "disableBouncingIcon") {
callback();
}
};
const onCustom = (e: Event) => {
const { key } = (e as CustomEvent).detail;
if (key === "disableBouncingIcon") {
callback();
}
};
window.addEventListener("storage", onStorage);
window.addEventListener(LOCAL_STORAGE_EVENT, onCustom);
return () => {
window.removeEventListener("storage", onStorage);
window.removeEventListener(LOCAL_STORAGE_EVENT, onCustom);
};
}
function getSnapshot() {
return getLocalStorageItem("disableBouncingIcon") === "true";
}
export function useDisableBouncingIcon() {
return useSyncExternalStore(subscribe, getSnapshot);
}

View file

@ -1,5 +1,6 @@
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
import { useDisableBlogPosts } from "@/app/(dashboard)/hooks/useDisableBlogPosts";
import { useDisableBouncingIcon } from "@/app/(dashboard)/hooks/useDisableBouncingIcon";
import { useDisableShowPrompts } from "@/app/(dashboard)/hooks/useDisableShowPrompts";
import { useDisableUsageIndicator } from "@/app/(dashboard)/hooks/useDisableUsageIndicator";
import {
@ -31,6 +32,7 @@ const UserDropdown: React.FC<UserDropdownProps> = ({ onLogout }) => {
const disableShowPrompts = useDisableShowPrompts();
const disableUsageIndicator = useDisableUsageIndicator();
const disableBlogPosts = useDisableBlogPosts();
const disableBouncingIcon = useDisableBouncingIcon();
const [disableShowNewBadge, setDisableShowNewBadge] = useState(false);
useEffect(() => {
@ -167,6 +169,23 @@ const UserDropdown: React.FC<UserDropdownProps> = ({ onLogout }) => {
aria-label="Toggle hide blog posts"
/>
</Space>
<Space style={{ width: "100%", justifyContent: "space-between" }}>
<Text type="secondary">Hide Bouncing Icon</Text>
<Switch
size="small"
checked={disableBouncingIcon}
onChange={(checked) => {
if (checked) {
setLocalStorageItem("disableBouncingIcon", "true");
emitLocalStorageChange("disableBouncingIcon");
} else {
removeLocalStorageItem("disableBouncingIcon");
emitLocalStorageChange("disableBouncingIcon");
}
}}
aria-label="Toggle hide bouncing icon"
/>
</Space>
</Space>
);

View file

@ -1,4 +1,5 @@
import { useHealthReadiness } from "@/app/(dashboard)/hooks/healthReadiness/useHealthReadiness";
import { useDisableBouncingIcon } from "@/app/(dashboard)/hooks/useDisableBouncingIcon";
import { getProxyBaseUrl } from "@/components/networking";
import { useTheme } from "@/contexts/ThemeContext";
import { clearTokenCookies } from "@/utils/cookieUtils";
@ -45,6 +46,7 @@ const Navbar: React.FC<NavbarProps> = ({
const { logoUrl } = useTheme();
const { data: healthData } = useHealthReadiness();
const version = healthData?.litellm_version;
const disableBouncingIcon = useDisableBouncingIcon();
// Simple logo URL: use custom logo if available, otherwise default
const imageUrl = logoUrl || `${baseUrl}/get_image`;
@ -101,13 +103,15 @@ const Navbar: React.FC<NavbarProps> = ({
</Link>
{version && (
<div className="relative">
<span
className="absolute -top-1 -left-2 text-lg animate-bounce"
style={{ animationDuration: "2s" }}
title="Thanks for using LiteLLM!"
>
🌑
</span>
{!disableBouncingIcon && (
<span
className="absolute -top-1 -left-2 text-lg animate-bounce"
style={{ animationDuration: "2s" }}
title="Thanks for using LiteLLM!"
>
🌑
</span>
)}
<Tag className="relative text-xs font-medium cursor-pointer z-10">
<a
href="https://docs.litellm.ai/release_notes"