import { useMemo, useCallback, useState, useEffect, useRef } from 'react'; import { easings } from '@react-spring/web'; import { EModelEndpoint } from 'librechat-data-provider'; import { useChatContext, useAgentsMapContext, useAssistantsMapContext } from '~/Providers'; import { useGetEndpointsQuery, useGetStartupConfig } from '~/data-provider'; import { BirthdayIcon, TooltipAnchor, SplitText } from '~/components'; import ConvoIcon from '~/components/Endpoints/ConvoIcon'; import { useLocalize, useAuthContext } from '~/hooks'; import { getIconEndpoint, getEntity } from '~/utils'; const containerClassName = 'shadow-stroke relative flex h-full items-center justify-center rounded-full bg-white text-black'; export default function Landing({ centerFormOnLanding }: { centerFormOnLanding: boolean }) { const { conversation } = useChatContext(); const agentsMap = useAgentsMapContext(); const assistantMap = useAssistantsMapContext(); const { data: startupConfig } = useGetStartupConfig(); const { data: endpointsConfig } = useGetEndpointsQuery(); const { user } = useAuthContext(); const localize = useLocalize(); const [textHasMultipleLines, setTextHasMultipleLines] = useState(false); const [lineCount, setLineCount] = useState(1); const [contentHeight, setContentHeight] = useState(0); const contentRef = useRef(null); const endpointType = useMemo(() => { let ep = conversation?.endpoint ?? ''; if ( [ EModelEndpoint.chatGPTBrowser, EModelEndpoint.azureOpenAI, EModelEndpoint.gptPlugins, ].includes(ep as EModelEndpoint) ) { ep = EModelEndpoint.openAI; } return getIconEndpoint({ endpointsConfig, iconURL: conversation?.iconURL, endpoint: ep, }); }, [conversation?.endpoint, conversation?.iconURL, endpointsConfig]); const { entity, isAgent, isAssistant } = getEntity({ endpoint: endpointType, agentsMap, assistantMap, agent_id: conversation?.agent_id, assistant_id: conversation?.assistant_id, }); const name = entity?.name ?? ''; const description = (entity?.description || conversation?.greeting) ?? ''; const getGreeting = useCallback(() => { if (typeof startupConfig?.interface?.customWelcome === 'string') { const customWelcome = startupConfig.interface.customWelcome; // Replace {{user.name}} with actual user name if available if (user?.name && customWelcome.includes('{{user.name}}')) { return customWelcome.replace(/{{user.name}}/g, user.name); } return customWelcome; } const now = new Date(); const hours = now.getHours(); const dayOfWeek = now.getDay(); const isWeekend = dayOfWeek === 0 || dayOfWeek === 6; // Early morning (midnight to 4:59 AM) if (hours >= 0 && hours < 5) { return localize('com_ui_late_night'); } // Morning (6 AM to 11:59 AM) else if (hours < 12) { if (isWeekend) { return localize('com_ui_weekend_morning'); } return localize('com_ui_good_morning'); } // Afternoon (12 PM to 4:59 PM) else if (hours < 17) { return localize('com_ui_good_afternoon'); } // Evening (5 PM to 8:59 PM) else { return localize('com_ui_good_evening'); } }, [localize, startupConfig?.interface?.customWelcome, user?.name]); const handleLineCountChange = useCallback((count: number) => { setTextHasMultipleLines(count > 1); setLineCount(count); }, []); useEffect(() => { if (contentRef.current) { setContentHeight(contentRef.current.offsetHeight); } }, [lineCount, description]); const getDynamicMargin = useMemo(() => { let margin = 'mb-0'; if (lineCount > 2 || (description && description.length > 100)) { margin = 'mb-10'; } else if (lineCount > 1 || (description && description.length > 0)) { margin = 'mb-6'; } else if (textHasMultipleLines) { margin = 'mb-4'; } if (contentHeight > 200) { margin = 'mb-16'; } else if (contentHeight > 150) { margin = 'mb-12'; } return margin; }, [lineCount, description, textHasMultipleLines, contentHeight]); return (
{startupConfig?.showBirthdayIcon && ( )}
{((isAgent || isAssistant) && name) || name ? (
) : ( )}
{description && (
{description}
)}
); }