mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-10-23 03:42:59 -05:00
feat(branding): derive logoUrl in useSettings hook (#12159)
This commit is contained in:
1 parent
ca2ea9d91b
commit
f74788ac3e
4 files changed
+28
-34
No files matched your search
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import useSWR from "swr";
|
||||
import { useMemo } from "react";
|
||||
import useCCPairs from "@/hooks/useCCPairs";
|
||||
import { errorHandlingFetcher } from "@/lib/fetcher";
|
||||
import { SWR_KEYS } from "@/lib/swr-keys";
|
||||
@@ -74,10 +75,21 @@ export function useSettings(): AppSettings {
|
||||
}
|
||||
);
|
||||
|
||||
// Cache-buster: the logo endpoint URL never changes, so the browser serves
|
||||
// a cached image even after an admin uploads a new logo. Regenerating this
|
||||
// timestamp whenever the enterprise settings reference changes forces a
|
||||
// re-fetch. We use referential equality on the SWR data (compare: a===b),
|
||||
// so this only fires when SWR actually receives new enterprise data.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const logoBuster = useMemo(() => Date.now(), [enterprise]);
|
||||
|
||||
return {
|
||||
...core,
|
||||
enterprise: enterprise ?? null,
|
||||
appName: enterprise?.application_name?.trim() || "Onyx",
|
||||
logoUrl: enterprise?.use_custom_logo
|
||||
? `/api/enterprise-settings/logo?v=${logoBuster}`
|
||||
: null,
|
||||
vectorDbEnabled:
|
||||
!settingsLoading && !settingsError && core.vector_db_enabled !== false,
|
||||
isLoading:
|
||||
|
||||
@@ -176,6 +176,13 @@ export interface AppSettings extends Settings {
|
||||
enterprise: EnterpriseSettings | null;
|
||||
/** Resolved display name: enterprise.application_name || "Onyx". */
|
||||
appName: string;
|
||||
/**
|
||||
* URL of the logo image to render, or `null` to use the default Onyx SVG.
|
||||
* Includes a cache-buster that updates whenever enterprise settings are
|
||||
* revalidated, forcing the browser to re-fetch after an admin uploads a
|
||||
* new logo.
|
||||
*/
|
||||
logoUrl: string | null;
|
||||
/** False when DISABLE_VECTOR_DB is set server-side. */
|
||||
vectorDbEnabled: boolean;
|
||||
isLoading: boolean;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { useSettings } from "@/lib/settings/hooks";
|
||||
|
||||
export default function DynamicMetadata() {
|
||||
const settings = useSettings();
|
||||
const { appName } = settings;
|
||||
const { appName, logoUrl } = useSettings();
|
||||
|
||||
useEffect(() => {
|
||||
if (document.title !== appName) {
|
||||
@@ -13,16 +12,5 @@ export default function DynamicMetadata() {
|
||||
}
|
||||
}, [appName]);
|
||||
|
||||
// Cache-buster so the favicon re-fetches after an admin uploads a new logo.
|
||||
const cacheBuster = useMemo(
|
||||
() => Date.now(),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[settings.enterprise]
|
||||
);
|
||||
|
||||
const favicon = settings.enterprise?.use_custom_logo
|
||||
? `/api/enterprise-settings/logo?v=${cacheBuster}`
|
||||
: "/onyx.ico";
|
||||
|
||||
return <link rel="icon" href={favicon} />;
|
||||
return <link rel="icon" href={logoUrl ?? "/onyx.ico"} />;
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
import { cn } from "@opal/utils";
|
||||
import Text from "@/refresh-components/texts/Text";
|
||||
import Truncated from "@/refresh-components/texts/Truncated";
|
||||
import { useMemo } from "react";
|
||||
import { SvgOnyxLogo, SvgOnyxLogoTyped } from "@opal/logos";
|
||||
|
||||
export interface LogoProps {
|
||||
@@ -27,21 +26,9 @@ export default function Logo({
|
||||
onyxBranded,
|
||||
}: LogoProps) {
|
||||
const resolvedSize = size ?? DEFAULT_LOGO_SIZE_PX;
|
||||
const settings = useSettings();
|
||||
const enterpriseSettings = settings.enterprise;
|
||||
const logoDisplayStyle = enterpriseSettings?.logo_display_style;
|
||||
const applicationName = enterpriseSettings?.application_name;
|
||||
|
||||
// Cache-buster: the logo URL never changes (/api/enterprise-settings/logo)
|
||||
// so the browser serves the in-memory cached image even after an admin
|
||||
// uploads a new one. Generating a fresh timestamp each time enterprise
|
||||
// settings are revalidated by SWR appends a unique query param to force
|
||||
// the browser to re-fetch the image.
|
||||
const logoBuster = useMemo(
|
||||
() => Date.now(),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[enterpriseSettings]
|
||||
);
|
||||
const { enterprise, logoUrl } = useSettings();
|
||||
const logoDisplayStyle = enterprise?.logo_display_style;
|
||||
const applicationName = enterprise?.application_name;
|
||||
|
||||
if (onyxBranded) {
|
||||
return folded ? (
|
||||
@@ -51,7 +38,7 @@ export default function Logo({
|
||||
);
|
||||
}
|
||||
|
||||
const logo = enterpriseSettings?.use_custom_logo ? (
|
||||
const logo = logoUrl ? (
|
||||
<div
|
||||
className={cn(
|
||||
"aspect-square rounded-full overflow-hidden relative shrink-0",
|
||||
@@ -62,7 +49,7 @@ export default function Logo({
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
alt="Logo"
|
||||
src={`/api/enterprise-settings/logo?v=${logoBuster}`}
|
||||
src={logoUrl}
|
||||
className="object-cover object-center w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
@@ -84,7 +71,7 @@ export default function Logo({
|
||||
<Truncated headingH3>{applicationName}</Truncated>
|
||||
)}
|
||||
{!NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED &&
|
||||
!enterpriseSettings?.hide_onyx_branding && (
|
||||
!enterprise?.hide_onyx_branding && (
|
||||
<Text
|
||||
secondaryBody
|
||||
text03
|
||||
|
||||
Reference in new issue
Block a user