import { GPUStackVersionAtom, UpdateCheckAtom } from '@/atoms/user'; import DropDownActions from '@/components/drop-down-actions'; import IconFont from '@/components/icon-font'; import VersionInfo, { modalConfig } from '@/components/version-info'; import externalLinks from '@/constants/external-links'; import useBodyScroll from '@/hooks/use-body-scroll'; import { logout } from '@/pages/login/apis'; import { useModel } from '@@/plugin-model'; import { DiscordOutlined, GithubOutlined, HomeOutlined, LogoutOutlined, ReadOutlined, SettingOutlined } from '@ant-design/icons'; import { history, useIntl, useNavigate } from '@umijs/max'; import { Avatar, Button, Divider, Modal } from 'antd'; import { useAtom } from 'jotai'; import { useMemo } from 'react'; import styled from 'styled-components'; import { DEFAULT_ENTER_PAGE } from '../config/settings'; const UpdateDot = styled.span` margin-left: 5px; display: flex; width: 8px; height: 8px; border-radius: 4px; background-color: var(--ant-orange-5); `; const NewLabel = styled.span` position: relative; top: -4px; right: 4px; padding: 2px 4px; display: flex; color: #fff; height: 15px; justify-content: center; align-items: center; background-color: var(--ant-orange-5); border-radius: 6px 6px 6px 0; transform: scale(0.9); .text { transform: scale(0.8); line-height: 1em; } `; const IconWrapper = styled.span` cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--ant-color-text-secondary); `; const Wrapper = styled.div` display: flex; align-items: center; gap: 24px; height: 40px; `; const DropdownWrapper = styled.div` min-width: 160px; box-shadow: var(--ant-box-shadow-secondary); background-color: var(--ant-color-bg-elevated); border-radius: var(--ant-border-radius-lg); padding: var(--ant-padding-xs); .ant-dropdown-menu { padding: 0; box-shadow: none; background-color: transparent; border-radius: 0; a { color: var(--ant-color-text); } } `; const CustomItem = styled.div` display: flex; align-items: center; gap: 8px; height: 32px; justify-content: flex-start; height: 32px; padding: 0 var(--ant-padding-xs); cursor: pointer; &.user-info { cursor: default; justify-content: space-between; .user-name { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; max-width: 100px; } } &:not(.user-info):hover { background-color: var(--ant-control-item-bg-hover); } background-color: var(--ant-color-bg-elevated); `; export const ExtraContent = (props: { isDarkTheme?: boolean }) => { const { isDarkTheme } = props; const { saveScrollHeight, restoreScrollHeight } = useBodyScroll(); const [modal, contextHolder] = Modal.useModal(); const [version] = useAtom(GPUStackVersionAtom); const [updateCheck] = useAtom(UpdateCheckAtom); const intl = useIntl(); const initialInfo = useModel('@@initialState') || { initialState: undefined, loading: false, setInitialState: null }; const { initialState } = initialInfo; const navigate = useNavigate(); const loginPath = DEFAULT_ENTER_PAGE.login; // only admin can see upgrade info, and current version is a prod version(exclude dev/rc) const showUpgrade = useMemo(() => { return ( initialState?.currentUser?.is_admin && updateCheck.latest_version && updateCheck.latest_version !== version?.version && version?.isProd ); }, [ updateCheck.latest_version, version.version, version.isProd, initialState?.currentUser?.is_admin ]); const avatarStyle = useMemo(() => { if (isDarkTheme) { return { color: 'var(--ant-color-text)', border: 'none' }; } return {}; }, [isDarkTheme]); const showVersion = () => { saveScrollHeight(); modal.info({ ...modalConfig, width: 460, content: , onCancel: restoreScrollHeight }); }; const handleLogout = async () => { await logout(); navigate(loginPath); }; const helpList = [ { key: 'site', icon: , label: 'GPUStack', url: externalLinks.site }, { key: 'github', icon: , label: intl.formatMessage({ id: 'common.issue.report' }), url: externalLinks.reportIssue }, { key: 'faq', icon: , label: intl.formatMessage({ id: 'common.button.faq' }), url: externalLinks.faq }, { key: 'Discord', icon: , label: 'Discord', url: externalLinks.discord }, { key: 'docs', icon: , label: intl.formatMessage({ id: 'common.button.docs' }), url: externalLinks.documentation } ]; const helpMenu = { items: helpList.map((item) => ({ key: item.key, label: ( {item.icon} {item.label} ) })) }; const userMenu = { items: [ { key: 'apikeys', label: ( {intl?.formatMessage?.({ id: 'menu.apikeys' })} ), onClick: () => { history.push('/api-keys'); } }, { key: 'settings', label: ( {intl?.formatMessage?.({ id: 'common.button.settings' })} ), onClick: () => { history.push('/profile'); } } ] }; const userPopupRender = (originNode: React.ReactNode) => { return ( } /> {initialState?.currentUser?.username} {originNode} {intl?.formatMessage?.({ id: 'common.button.logout' })} ); }; const helpPopupRender = (originNode: React.ReactNode) => { return {originNode}; }; return ( {contextHolder}
{showUpgrade && ( {intl.formatMessage({ id: 'common.text.new' })} )}
} />
); };