mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 09:37:28 +00:00
💄 style: mount DynamicFavicon for agent operation favicon switching (#13416)
* ✨ feat: mount DynamicFavicon to enable favicon state switching during agent operations Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: add favicon link tags to SPA HTML templates and handle missing links in updateFaviconDOM Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c59c066330
commit
e76ab1f990
5 changed files with 42 additions and 0 deletions
|
|
@ -3,6 +3,8 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="shortcut icon" href="/favicon-32x32.ico" />
|
||||
<link rel="manifest" href="/manifest.webmanifest" />
|
||||
<!--SEO_META-->
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="shortcut icon" href="/favicon-32x32.ico" />
|
||||
<!--SEO_META-->
|
||||
<style>
|
||||
html body {
|
||||
|
|
|
|||
22
src/layout/GlobalProvider/DynamicFavicon.tsx
Normal file
22
src/layout/GlobalProvider/DynamicFavicon.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
'use client';
|
||||
|
||||
import { memo, useEffect } from 'react';
|
||||
|
||||
import { useFaviconSetters } from '@/layout/GlobalProvider/FaviconProvider';
|
||||
import { useChatStore } from '@/store/chat';
|
||||
import { operationSelectors } from '@/store/chat/slices/operation/selectors';
|
||||
|
||||
const DynamicFavicon = memo(() => {
|
||||
const isRunning = useChatStore(operationSelectors.isAgentRuntimeRunning);
|
||||
const { setFavicon } = useFaviconSetters();
|
||||
|
||||
useEffect(() => {
|
||||
setFavicon(isRunning ? 'progress' : 'default');
|
||||
}, [isRunning, setFavicon]);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
DynamicFavicon.displayName = 'DynamicFavicon';
|
||||
|
||||
export default DynamicFavicon;
|
||||
|
|
@ -56,6 +56,20 @@ const updateFaviconDOM = (state: FaviconState, isDev: boolean) => {
|
|||
'link[rel="icon"], link[rel="shortcut icon"]',
|
||||
);
|
||||
|
||||
if (existingLinks.length === 0) {
|
||||
// No favicon links found — create them
|
||||
const iconLink = document.createElement('link');
|
||||
iconLink.rel = 'icon';
|
||||
iconLink.href = `${getFaviconPath(state, isDev)}?v=${Date.now()}`;
|
||||
head.append(iconLink);
|
||||
|
||||
const shortcutLink = document.createElement('link');
|
||||
shortcutLink.rel = 'shortcut icon';
|
||||
shortcutLink.href = `${getFaviconPath(state, isDev, '32x32')}?v=${Date.now()}`;
|
||||
head.append(shortcutLink);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove existing favicon links and create new ones to bust cache
|
||||
existingLinks.forEach((link) => {
|
||||
const oldHref = link.href;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { DragUploadProvider } from '@/components/DragUploadZone/DragUploadProvid
|
|||
import { isDesktop } from '@/const/version';
|
||||
import AuthProvider from '@/layout/AuthProvider';
|
||||
import AppTheme from '@/layout/GlobalProvider/AppTheme';
|
||||
import DynamicFavicon from '@/layout/GlobalProvider/DynamicFavicon';
|
||||
import { FaviconProvider } from '@/layout/GlobalProvider/FaviconProvider';
|
||||
import { GroupWizardProvider } from '@/layout/GlobalProvider/GroupWizardProvider';
|
||||
import ImportSettings from '@/layout/GlobalProvider/ImportSettings';
|
||||
|
|
@ -54,6 +55,7 @@ const SPAGlobalProvider = memo<PropsWithChildren>(({ children }) => {
|
|||
|
||||
{isDesktop && <ServerVersionOutdatedAlert />}
|
||||
<FaviconProvider>
|
||||
<DynamicFavicon />
|
||||
<GroupWizardProvider>
|
||||
<DragUploadProvider>
|
||||
<LazyMotion features={domMax}>
|
||||
|
|
|
|||
Loading…
Reference in a new issue