use-app-favicon.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import { useAsyncEffect } from 'ahooks'
  2. import { appDefaultIconBackground } from '@/config'
  3. import { searchEmoji } from '@/utils/emoji'
  4. import type { AppIconType } from '@/types/app'
  5. type UseAppFaviconOptions = {
  6. enable?: boolean
  7. icon_type?: AppIconType | null
  8. icon?: string
  9. icon_background?: string | null
  10. icon_url?: string | null
  11. }
  12. export function useAppFavicon(options: UseAppFaviconOptions) {
  13. const {
  14. enable = true,
  15. icon_type = 'emoji',
  16. icon,
  17. icon_background,
  18. icon_url,
  19. } = options
  20. useAsyncEffect(async () => {
  21. if (!enable || (icon_type === 'image' && !icon_url) || (icon_type === 'emoji' && !icon))
  22. return
  23. const isValidImageIcon = icon_type === 'image' && icon_url
  24. const link: HTMLLinkElement = document.querySelector('link[rel*="icon"]') || document.createElement('link')
  25. link.href = isValidImageIcon
  26. ? icon_url
  27. : 'data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22>'
  28. + `<rect width=%22100%25%22 height=%22100%25%22 fill=%22${encodeURIComponent(icon_background || appDefaultIconBackground)}%22 rx=%2230%22 ry=%2230%22 />`
  29. + `<text x=%2212.5%22 y=%221em%22 font-size=%2275%22>${
  30. icon ? await searchEmoji(icon) : '🤖'
  31. }</text>`
  32. + '</svg>'
  33. link.rel = 'shortcut icon'
  34. link.type = 'image/svg'
  35. document.getElementsByTagName('head')[0].appendChild(link)
  36. }, [enable, icon, icon_background])
  37. }