mirror of
https://github.com/langgenius/dify.git
synced 2026-01-04 21:47:22 +00:00
fix: show configured brand info in browser tabs
This commit is contained in:
@@ -25,6 +25,7 @@ import { useAppContext } from '@/context/app-context'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import type { App } from '@/types/app'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
export type IAppDetailLayoutProps = {
|
||||
children: React.ReactNode
|
||||
@@ -94,9 +95,10 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
|
||||
return navs
|
||||
}, [])
|
||||
|
||||
useDocumentTitle(appDetail?.name || t('common.menus.appDetail'))
|
||||
|
||||
useEffect(() => {
|
||||
if (appDetail) {
|
||||
document.title = `${(appDetail.name || 'App')} - Dify`
|
||||
const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand'
|
||||
const mode = isMobile ? 'collapse' : 'expand'
|
||||
setAppSiderbarExpand(isMobile ? mode : localeMode)
|
||||
|
||||
@@ -29,6 +29,7 @@ import { useStore as useTagStore } from '@/app/components/base/tag-management/st
|
||||
import TagManagementModal from '@/app/components/base/tag-management'
|
||||
import TagFilter from '@/app/components/base/tag-management/filter'
|
||||
import CheckboxWithLabel from '@/app/components/datasets/create/website/base/checkbox-with-label'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
const getKey = (
|
||||
pageIndex: number,
|
||||
@@ -96,7 +97,6 @@ const Apps = () => {
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
document.title = `${t('common.menus.apps')} - Dify`
|
||||
if (localStorage.getItem(NEED_REFRESH_APP_LIST_KEY) === '1') {
|
||||
localStorage.removeItem(NEED_REFRESH_APP_LIST_KEY)
|
||||
mutate()
|
||||
@@ -128,6 +128,8 @@ const Apps = () => {
|
||||
return () => observer?.disconnect()
|
||||
}, [isLoading, setSize, anchorRef, mutate, data, error])
|
||||
|
||||
useDocumentTitle(isLoading ? '' : t('common.menus.apps'))
|
||||
|
||||
const { run: handleSearch } = useDebounceFn(() => {
|
||||
setSearchKeywords(keywords)
|
||||
}, { wait: 500 })
|
||||
|
||||
@@ -6,13 +6,11 @@ import style from '../list.module.css'
|
||||
import Apps from './Apps'
|
||||
import { useEducationInit } from '@/app/education-apply/hooks'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
const AppList = () => {
|
||||
const { t } = useTranslation()
|
||||
useEducationInit()
|
||||
const { systemFeatures } = useGlobalPublicStore()
|
||||
useDocumentTitle(t('common.menus.apps'))
|
||||
return (
|
||||
<div className='relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-background-body'>
|
||||
<Apps />
|
||||
|
||||
@@ -31,6 +31,7 @@ import { getLocaleOnClient } from '@/i18n'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import LinkedAppsPanel from '@/app/components/base/linked-apps-panel'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
export type IAppDetailLayoutProps = {
|
||||
children: React.ReactNode
|
||||
@@ -158,10 +159,7 @@ const DatasetDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
|
||||
return baseNavigation
|
||||
}, [datasetRes?.provider, datasetId, t])
|
||||
|
||||
useEffect(() => {
|
||||
if (datasetRes)
|
||||
document.title = `${datasetRes.name || 'Dataset'} - Dify`
|
||||
}, [datasetRes])
|
||||
useDocumentTitle(datasetRes?.name || t('common.menus.datasets'))
|
||||
|
||||
const setAppSiderbarExpand = useStore(state => state.setAppSiderbarExpand)
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import { useStore as useTagStore } from '@/app/components/base/tag-management/st
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useExternalApiPanel } from '@/context/external-api-panel-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
const Container = () => {
|
||||
const { t } = useTranslation()
|
||||
@@ -39,8 +40,7 @@ const Container = () => {
|
||||
const showTagManagementModal = useTagStore(s => s.showTagManagementModal)
|
||||
const { showExternalApiPanel, setShowExternalApiPanel } = useExternalApiPanel()
|
||||
const [includeAll, { toggle: toggleIncludeAll }] = useBoolean(false)
|
||||
|
||||
document.title = `${t('dataset.knowledge')} - Dify`
|
||||
useDocumentTitle(t('dataset.knowledge'))
|
||||
|
||||
const options = useMemo(() => {
|
||||
return [
|
||||
|
||||
@@ -60,7 +60,6 @@ const Datasets = ({
|
||||
|
||||
useEffect(() => {
|
||||
loadingStateRef.current = isLoading
|
||||
document.title = `${t('dataset.knowledge')} - Dify`
|
||||
}, [isLoading, t])
|
||||
|
||||
const onScroll = useCallback(
|
||||
|
||||
@@ -20,6 +20,7 @@ import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import { checkOrSetAccessToken } from '@/app/components/share/utils'
|
||||
import AppUnavailable from '@/app/components/base/app-unavailable'
|
||||
import cn from '@/utils/classnames'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
type ChatWithHistoryProps = {
|
||||
className?: string
|
||||
@@ -46,14 +47,10 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
|
||||
|
||||
useEffect(() => {
|
||||
themeBuilder?.buildTheme(site?.chat_color_theme, site?.chat_color_theme_inverted)
|
||||
if (site) {
|
||||
if (customConfig)
|
||||
document.title = `${site.title}`
|
||||
else
|
||||
document.title = `${site.title} - Powered by Dify`
|
||||
}
|
||||
}, [site, customConfig, themeBuilder])
|
||||
|
||||
useDocumentTitle(site?.title || 'Chat')
|
||||
|
||||
if (appInfoLoading) {
|
||||
return (
|
||||
<Loading type='app' />
|
||||
|
||||
@@ -21,6 +21,7 @@ import Header from '@/app/components/base/chat/embedded-chatbot/header'
|
||||
import ChatWrapper from '@/app/components/base/chat/embedded-chatbot/chat-wrapper'
|
||||
import LogoSite from '@/app/components/base/logo/logo-site'
|
||||
import cn from '@/utils/classnames'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
const Chatbot = () => {
|
||||
const {
|
||||
@@ -44,14 +45,10 @@ const Chatbot = () => {
|
||||
|
||||
useEffect(() => {
|
||||
themeBuilder?.buildTheme(site?.chat_color_theme, site?.chat_color_theme_inverted)
|
||||
if (site) {
|
||||
if (customConfig)
|
||||
document.title = `${site.title}`
|
||||
else
|
||||
document.title = `${site.title} - Powered by Dify`
|
||||
}
|
||||
}, [site, customConfig, themeBuilder])
|
||||
|
||||
useDocumentTitle(site?.title || 'Chat')
|
||||
|
||||
if (appInfoLoading) {
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useAppContext } from '@/context/app-context'
|
||||
import { fetchMembers } from '@/service/common'
|
||||
import type { InstalledApp } from '@/models/explore'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
export type IExploreProps = {
|
||||
children: React.ReactNode
|
||||
@@ -23,8 +24,9 @@ const Explore: FC<IExploreProps> = ({
|
||||
const [installedApps, setInstalledApps] = useState<InstalledApp[]>([])
|
||||
const { t } = useTranslation()
|
||||
|
||||
useDocumentTitle(t('common.menus.explore'))
|
||||
|
||||
useEffect(() => {
|
||||
document.title = `${t('explore.title')} - Dify`;
|
||||
(async () => {
|
||||
const { accounts } = await fetchMembers({ url: '/workspaces/current/members', params: {} })
|
||||
if (!accounts)
|
||||
|
||||
@@ -42,6 +42,7 @@ import { noop } from 'lodash-es'
|
||||
import { PLUGIN_TYPE_SEARCH_MAP } from '../marketplace/plugin-type-switch'
|
||||
import { PLUGIN_PAGE_TABS_MAP } from '../hooks'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
const PACKAGE_IDS_KEY = 'package-ids'
|
||||
const BUNDLE_INFO_KEY = 'bundle-info'
|
||||
@@ -58,8 +59,7 @@ const PluginPage = ({
|
||||
const { locale } = useContext(I18n)
|
||||
const searchParams = useSearchParams()
|
||||
const { replace } = useRouter()
|
||||
|
||||
document.title = `${t('plugin.metadata.title')} - Dify`
|
||||
useDocumentTitle(t('plugin.metadata.title'))
|
||||
|
||||
// just support install one package now
|
||||
const packageId = useMemo(() => {
|
||||
|
||||
@@ -42,6 +42,7 @@ import cn from '@/utils/classnames'
|
||||
import { useGetAppAccessMode, useGetUserCanAccessApp } from '@/service/access-control'
|
||||
import { AccessMode } from '@/models/access-control'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
const GROUP_SIZE = 5 // to avoid RPM(Request per minute) limit. The group task finished then the next group.
|
||||
enum TaskStatus {
|
||||
@@ -105,7 +106,6 @@ const TextGeneration: FC<IMainProps> = ({
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const [appId, setAppId] = useState<string>('')
|
||||
const [siteInfo, setSiteInfo] = useState<SiteInfo | null>(null)
|
||||
const [canReplaceLogo, setCanReplaceLogo] = useState<boolean>(false)
|
||||
const [customConfig, setCustomConfig] = useState<Record<string, any> | null>(null)
|
||||
const [promptConfig, setPromptConfig] = useState<PromptConfig | null>(null)
|
||||
const [moreLikeThisConfig, setMoreLikeThisConfig] = useState<MoreLikeThisConfig | null>(null)
|
||||
@@ -411,10 +411,9 @@ const TextGeneration: FC<IMainProps> = ({
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const [appData, appParams]: any = await fetchInitData()
|
||||
const { app_id: appId, site: siteInfo, can_replace_logo, custom_config } = appData
|
||||
const { app_id: appId, site: siteInfo, custom_config } = appData
|
||||
setAppId(appId)
|
||||
setSiteInfo(siteInfo as SiteInfo)
|
||||
setCanReplaceLogo(can_replace_logo)
|
||||
setCustomConfig(custom_config)
|
||||
changeLanguage(siteInfo.default_language)
|
||||
|
||||
@@ -435,17 +434,10 @@ const TextGeneration: FC<IMainProps> = ({
|
||||
setMoreLikeThisConfig(more_like_this)
|
||||
setTextToSpeechConfig(text_to_speech)
|
||||
})()
|
||||
}, [])
|
||||
}, [fetchInitData])
|
||||
|
||||
// Can Use metadata(https://beta.nextjs.org/docs/api-reference/metadata) to set title. But it only works in server side client.
|
||||
useEffect(() => {
|
||||
if (siteInfo?.title) {
|
||||
if (canReplaceLogo)
|
||||
document.title = `${siteInfo.title}`
|
||||
else
|
||||
document.title = `${siteInfo.title} - Powered by Dify`
|
||||
}
|
||||
}, [siteInfo?.title, canReplaceLogo])
|
||||
useDocumentTitle(siteInfo?.title || t('share.generation.title'))
|
||||
|
||||
useAppFavicon({
|
||||
enable: !isInstalledApp,
|
||||
|
||||
@@ -1,19 +1,10 @@
|
||||
'use client'
|
||||
import { useLayoutEffect } from 'react'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { useFavicon, useTitle } from 'ahooks'
|
||||
|
||||
export default function useDocumentTitle(title: string) {
|
||||
const { systemFeatures } = useGlobalPublicStore()
|
||||
useLayoutEffect(() => {
|
||||
const prefix = title ? `${title} - ` : ''
|
||||
if (systemFeatures.branding.enabled) {
|
||||
document.title = `${prefix}${systemFeatures.branding.application_title}`
|
||||
const faviconEle = document.querySelector('link[rel*=\'icon\']') as HTMLLinkElement
|
||||
if (faviconEle)
|
||||
faviconEle.href = systemFeatures.branding.favicon
|
||||
}
|
||||
else {
|
||||
document.title = `${prefix}Dify`
|
||||
}
|
||||
}, [systemFeatures, title])
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const prefix = title ? `${title} - ` : ''
|
||||
useTitle(systemFeatures.branding.enabled ? `${prefix}${systemFeatures.branding.application_title}` : `${prefix}Dify`)
|
||||
useFavicon(systemFeatures.branding.enabled ? systemFeatures.branding.favicon : '/favicon.ico')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user