mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-06-04 11:14:10 +08:00
Fix: web app theme intialization (#14761)
This commit is contained in:
parent
64e122c5f6
commit
bb4e7da720
@ -1,7 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import type { Metadata } from 'next'
|
import type { Metadata } from 'next'
|
||||||
import { SharePageContextProvider } from '@/context/share-page-context'
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
icons: 'data:,', // prevent browser from using default favicon
|
icons: 'data:,', // prevent browser from using default favicon
|
||||||
@ -12,9 +11,7 @@ const Layout: FC<{
|
|||||||
}> = ({ children }) => {
|
}> = ({ children }) => {
|
||||||
return (
|
return (
|
||||||
<div className="min-w-[300px] h-full pb-[env(safe-area-inset-bottom)]">
|
<div className="min-w-[300px] h-full pb-[env(safe-area-inset-bottom)]">
|
||||||
<SharePageContextProvider>
|
{children}
|
||||||
{children}
|
|
||||||
</SharePageContextProvider>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
RiPlayLargeFill,
|
RiPlayLargeFill,
|
||||||
} from '@remixicon/react'
|
} from '@remixicon/react'
|
||||||
import Toast from '@/app/components/base/toast'
|
import Toast from '@/app/components/base/toast'
|
||||||
import { useAppContext } from '@/context/app-context'
|
import useTheme from '@/hooks/use-theme'
|
||||||
import { Theme } from '@/types/app'
|
import { Theme } from '@/types/app'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({ src }) => {
|
|||||||
const [hasStartedPlaying, setHasStartedPlaying] = useState(false)
|
const [hasStartedPlaying, setHasStartedPlaying] = useState(false)
|
||||||
const [hoverTime, setHoverTime] = useState(0)
|
const [hoverTime, setHoverTime] = useState(0)
|
||||||
const [isAudioAvailable, setIsAudioAvailable] = useState(true)
|
const [isAudioAvailable, setIsAudioAvailable] = useState(true)
|
||||||
const { theme } = useAppContext()
|
const { theme } = useTheme()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const audio = audioRef.current
|
const audio = audioRef.current
|
||||||
|
@ -206,7 +206,7 @@ const ChatWrapper = () => {
|
|||||||
isResponding={isResponding}
|
isResponding={isResponding}
|
||||||
chatContainerInnerClassName={`mx-auto pt-6 w-full max-w-[720px] ${isMobile && 'px-4'}`}
|
chatContainerInnerClassName={`mx-auto pt-6 w-full max-w-[720px] ${isMobile && 'px-4'}`}
|
||||||
chatFooterClassName='pb-4'
|
chatFooterClassName='pb-4'
|
||||||
chatFooterInnerClassName={`mx-auto w-full max-w-[720px] ${isMobile && 'px-4'}`}
|
chatFooterInnerClassName={`mx-auto w-full max-w-[720px] ${isMobile ? 'px-2' : 'px-4'}`}
|
||||||
onSend={doSend}
|
onSend={doSend}
|
||||||
inputs={currentConversationId ? currentConversationItem?.inputs as any : newConversationInputs}
|
inputs={currentConversationId ? currentConversationItem?.inputs as any : newConversationInputs}
|
||||||
inputsForm={inputsForms}
|
inputsForm={inputsForms}
|
||||||
|
@ -48,10 +48,13 @@ export class ThemeBuilder {
|
|||||||
private buildChecker = false
|
private buildChecker = false
|
||||||
|
|
||||||
public get theme() {
|
public get theme() {
|
||||||
if (this._theme === undefined)
|
if (this._theme === undefined) {
|
||||||
throw new Error('The theme should be built first and then accessed')
|
this._theme = new Theme()
|
||||||
else
|
|
||||||
return this._theme
|
return this._theme
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return this._theme
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public buildTheme(chatColorTheme: string | null = null, chatColorThemeInverted = false) {
|
public buildTheme(chatColorTheme: string | null = null, chatColorThemeInverted = false) {
|
||||||
|
@ -26,7 +26,7 @@ import MarkdownButton from '@/app/components/base/markdown-blocks/button'
|
|||||||
import MarkdownForm from '@/app/components/base/markdown-blocks/form'
|
import MarkdownForm from '@/app/components/base/markdown-blocks/form'
|
||||||
import ThinkBlock from '@/app/components/base/markdown-blocks/think-block'
|
import ThinkBlock from '@/app/components/base/markdown-blocks/think-block'
|
||||||
import { Theme } from '@/types/app'
|
import { Theme } from '@/types/app'
|
||||||
import { useAppContext } from '@/context/app-context'
|
import useTheme from '@/hooks/use-theme'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
// Available language https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_LANGUAGES_HLJS.MD
|
// Available language https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_LANGUAGES_HLJS.MD
|
||||||
@ -107,7 +107,7 @@ export function PreCode(props: { children: any }) {
|
|||||||
// or use the non-minified dev environment for full errors and additional helpful warnings.
|
// or use the non-minified dev environment for full errors and additional helpful warnings.
|
||||||
|
|
||||||
const CodeBlock: any = memo(({ inline, className, children, ...props }: any) => {
|
const CodeBlock: any = memo(({ inline, className, children, ...props }: any) => {
|
||||||
const { theme } = useAppContext()
|
const { theme } = useTheme()
|
||||||
const [isSVG, setIsSVG] = useState(true)
|
const [isSVG, setIsSVG] = useState(true)
|
||||||
const match = /language-(\w+)/.exec(className || '')
|
const match = /language-(\w+)/.exec(className || '')
|
||||||
const language = match?.[1]
|
const language = match?.[1]
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
'use client'
|
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
|
||||||
import { createContext, useContextSelector } from 'use-context-selector'
|
|
||||||
import type { FC, ReactNode } from 'react'
|
|
||||||
import { Theme } from '@/types/app'
|
|
||||||
|
|
||||||
export type SharePageContextValue = {
|
|
||||||
theme: Theme
|
|
||||||
setTheme: (theme: Theme) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const SharePageContext = createContext<SharePageContextValue>({
|
|
||||||
theme: Theme.light,
|
|
||||||
setTheme: () => { },
|
|
||||||
})
|
|
||||||
|
|
||||||
export function useSelector<T>(selector: (value: SharePageContextValue) => T): T {
|
|
||||||
return useContextSelector(SharePageContext, selector)
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SharePageContextProviderProps = {
|
|
||||||
children: ReactNode
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SharePageContextProvider: FC<SharePageContextProviderProps> = ({ children }) => {
|
|
||||||
const [theme, setTheme] = useState<Theme>(Theme.light)
|
|
||||||
const handleSetTheme = useCallback((theme: Theme) => {
|
|
||||||
setTheme(theme)
|
|
||||||
globalThis.document.documentElement.setAttribute('data-theme', theme)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
globalThis.document.documentElement.setAttribute('data-theme', theme)
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SharePageContext.Provider value={{
|
|
||||||
theme,
|
|
||||||
setTheme: handleSetTheme,
|
|
||||||
}}>
|
|
||||||
{children}
|
|
||||||
</SharePageContext.Provider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SharePageContextProvider
|
|
Loading…
x
Reference in New Issue
Block a user