mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-27 04:31:27 +08:00
fix: resolve issue of top navigation bar being obscured by miniapp (#8517)
* 修复顶部导航栏被小程序遮挡的问题 * chore: 删除多余文件 * fix: remove redundant changes * style: modify padding * fix(TabContainer): 切换页面时隐藏小程序弹窗 * fix(WebviewContainer): 修正顶部导航栏存在时的webview高度计算 当顶部导航栏存在时,高度计算需要减去两个导航栏高度变量 * fix(TabContainer): 在添加新标签时隐藏minapp弹窗 * fix(MinappPopupContainer): 修复按钮组在顶部导航栏时的边距问题 根据导航栏位置动态调整按钮组的右边距,当导航栏在顶部时不添加额外边距 * feat(useAppInit): 根据导航栏位置调整窗口背景色 根据导航栏位置(isTopNavbar)动态调整窗口背景色,当导航栏在顶部时使用固定背景色,否则保持原有逻辑 * feat(miniapps): 优化顶部导航栏中固定应用标签的样式和交互 重构顶部导航栏中固定应用标签的布局,添加应用名称显示 调整悬停和激活状态的样式,提升用户体验 * fix: 修正顶部导航栏在有 pinned 应用时的背景色显示问题 当有 pinned 应用时,顶部导航栏应显示背景色,之前逻辑错误地要求至少两个应用才显示 * refactor(PinnedMinapps): 移除多余的Tooltip组件并优化结构 * style(PinnedMinapps): 优化顶部导航项的悬停和激活样式 调整悬停效果,移除圆形背景改为底部边框高亮 激活状态改为1px边框并移除冗余的圆角设置 --------- Co-authored-by: xinming wong <xinmingwong@xinmingdeMacBook-Air.local> Co-authored-by: icarus <eurfelux@gmail.com>
This commit is contained in:
parent
49db4c3bb8
commit
0f7091f3a8
@ -143,7 +143,7 @@ const MinappPopupContainer: React.FC = () => {
|
||||
const { pinned, updatePinnedMinapps } = useMinapps()
|
||||
const { t } = useTranslation()
|
||||
const backgroundColor = useNavBackgroundColor()
|
||||
const { isTopNavbar } = useNavbarPosition()
|
||||
const { isLeftNavbar, isTopNavbar } = useNavbarPosition()
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
/** control the drawer open or close */
|
||||
@ -165,8 +165,6 @@ const MinappPopupContainer: React.FC = () => {
|
||||
/** whether the minapps open link external is enabled */
|
||||
const { minappsOpenLinkExternal } = useSettings()
|
||||
|
||||
const { isLeftNavbar } = useNavbarPosition()
|
||||
|
||||
const isInDevelopment = process.env.NODE_ENV === 'development'
|
||||
|
||||
useBridge()
|
||||
@ -405,7 +403,7 @@ const MinappPopupContainer: React.FC = () => {
|
||||
</Tooltip>
|
||||
)}
|
||||
<Spacer />
|
||||
<ButtonsGroup className={isWin || isLinux ? 'windows' : ''}>
|
||||
<ButtonsGroup className={isWin || isLinux ? 'windows' : ''} isTopNavBar={isTopNavbar}>
|
||||
<Tooltip title={t('minapp.popup.goBack')} mouseEnterDelay={0.8} placement="bottom">
|
||||
<TitleButton onClick={() => handleGoBack(appInfo.id)}>
|
||||
<ArrowLeftOutlined />
|
||||
@ -507,6 +505,7 @@ const MinappPopupContainer: React.FC = () => {
|
||||
closeIcon={null}
|
||||
style={{
|
||||
marginLeft: isLeftNavbar ? 'var(--sidebar-width)' : 0,
|
||||
marginTop: isTopNavbar ? 'var(--navbar-height)' : 0,
|
||||
backgroundColor: window.root.style.background
|
||||
}}>
|
||||
{/* 在所有小程序中显示GoogleLoginTip */}
|
||||
@ -541,7 +540,7 @@ const TitleContainer = styled.div`
|
||||
padding-left: ${isMac ? '20px' : '10px'};
|
||||
}
|
||||
[navbar-position='top'] & {
|
||||
padding-left: ${isMac ? '80px' : '10px'};
|
||||
padding-left: ${isMac ? '20px' : '10px'};
|
||||
border-bottom: 0.5px solid var(--color-border);
|
||||
}
|
||||
`
|
||||
@ -563,14 +562,14 @@ const TitleTextTooltip = styled.span`
|
||||
}
|
||||
`
|
||||
|
||||
const ButtonsGroup = styled.div`
|
||||
const ButtonsGroup = styled.div<{ isTopNavBar: boolean }>`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
-webkit-app-region: no-drag;
|
||||
&.windows {
|
||||
margin-right: ${isWin ? '130px' : isLinux ? '100px' : 0};
|
||||
margin-right: ${(props) => (props.isTopNavBar ? 0 : isWin ? '130px' : isLinux ? '100px' : 0)};
|
||||
background-color: var(--color-background-mute);
|
||||
border-radius: 50px;
|
||||
padding: 0 3px;
|
||||
|
||||
@ -23,7 +23,7 @@ const WebviewContainer = memo(
|
||||
}) => {
|
||||
const webviewRef = useRef<WebviewTag | null>(null)
|
||||
const { enableSpellCheck } = useSettings()
|
||||
const { isLeftNavbar } = useNavbarPosition()
|
||||
const { isLeftNavbar, isTopNavbar } = useNavbarPosition()
|
||||
|
||||
const setRef = (appid: string) => {
|
||||
onSetRefCallback(appid, null)
|
||||
@ -74,7 +74,7 @@ const WebviewContainer = memo(
|
||||
|
||||
const WebviewStyle: React.CSSProperties = {
|
||||
width: isLeftNavbar ? 'calc(100vw - var(--sidebar-width))' : '100vw',
|
||||
height: 'calc(100vh - var(--navbar-height))',
|
||||
height: isTopNavbar ? 'calc(100vh - var(--navbar-height) - var(--navbar-height))' : '100vh',
|
||||
backgroundColor: 'var(--color-background)',
|
||||
display: 'inline-flex'
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import { PlusOutlined } from '@ant-design/icons'
|
||||
import { isLinux, isMac, isWin } from '@renderer/config/constant'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useFullscreen } from '@renderer/hooks/useFullscreen'
|
||||
import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
|
||||
import { getTitleLabel } from '@renderer/i18n/label'
|
||||
import tabsService from '@renderer/services/TabsService'
|
||||
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||
@ -69,6 +70,7 @@ const TabsContainer: React.FC<TabsContainerProps> = ({ children }) => {
|
||||
const activeTabId = useAppSelector((state) => state.tabs.activeTabId)
|
||||
const isFullscreen = useFullscreen()
|
||||
const { theme, setTheme } = useTheme()
|
||||
const { hideMinappPopup } = useMinappPopup()
|
||||
|
||||
const getTabId = (path: string): string => {
|
||||
if (path === '/') return 'home'
|
||||
@ -116,10 +118,12 @@ const TabsContainer: React.FC<TabsContainerProps> = ({ children }) => {
|
||||
}
|
||||
|
||||
const handleAddTab = () => {
|
||||
hideMinappPopup()
|
||||
navigate('/launchpad')
|
||||
}
|
||||
|
||||
const handleSettingsClick = () => {
|
||||
hideMinappPopup()
|
||||
navigate(lastSettingsPath)
|
||||
}
|
||||
|
||||
@ -130,7 +134,15 @@ const TabsContainer: React.FC<TabsContainerProps> = ({ children }) => {
|
||||
.filter((tab) => !specialTabs.includes(tab.id))
|
||||
.map((tab) => {
|
||||
return (
|
||||
<Tab key={tab.id} active={tab.id === activeTabId} onClick={() => navigate(tab.path)}>
|
||||
<Tab
|
||||
key={tab.id}
|
||||
active={tab.id === activeTabId}
|
||||
onClick={() => {
|
||||
hideMinappPopup()
|
||||
// 我不确定这个还需不需要,从Siderbar那边复制过来的
|
||||
// await modelGenerating()
|
||||
navigate(tab.path)
|
||||
}}>
|
||||
<TabHeader>
|
||||
{tab.id && <TabIcon>{getTabIcon(tab.id)}</TabIcon>}
|
||||
<TabTitle>{getTitleLabel(tab.id)}</TabTitle>
|
||||
|
||||
@ -3,6 +3,7 @@ import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
|
||||
import { useMinapps } from '@renderer/hooks/useMinapps'
|
||||
import { useRuntime } from '@renderer/hooks/useRuntime'
|
||||
import { useNavbarPosition, useSettings } from '@renderer/hooks/useSettings'
|
||||
import { MinAppType } from '@renderer/types'
|
||||
import type { MenuProps } from 'antd'
|
||||
import { Dropdown, Tooltip } from 'antd'
|
||||
import { FC, useEffect, useState } from 'react'
|
||||
@ -26,7 +27,7 @@ export const TopNavbarOpenedMinappTabs: FC = () => {
|
||||
return () => clearTimeout(timer)
|
||||
}, [openedKeepAliveMinapps])
|
||||
|
||||
const handleOnClick = (app) => {
|
||||
const handleOnClick = (app: MinAppType) => {
|
||||
if (minappShow && currentMinappId === app.id) {
|
||||
hideMinappPopup()
|
||||
} else {
|
||||
@ -42,7 +43,7 @@ export const TopNavbarOpenedMinappTabs: FC = () => {
|
||||
|
||||
return (
|
||||
<TopNavContainer
|
||||
style={{ backgroundColor: keepAliveMinapps.length > 1 ? 'var(--color-list-item)' : 'transparent' }}>
|
||||
style={{ backgroundColor: keepAliveMinapps.length > 0 ? 'var(--color-list-item)' : 'transparent' }}>
|
||||
<TopNavMenus>
|
||||
{keepAliveMinapps.map((app) => {
|
||||
const menuItems: MenuProps['items'] = [
|
||||
@ -64,18 +65,19 @@ export const TopNavbarOpenedMinappTabs: FC = () => {
|
||||
const isActive = minappShow && currentMinappId === app.id
|
||||
|
||||
return (
|
||||
<Tooltip key={app.id} title={app.name} mouseEnterDelay={0.8} placement="bottom">
|
||||
<StyledLink>
|
||||
<Dropdown menu={{ items: menuItems }} trigger={['contextMenu']} overlayStyle={{ zIndex: 10000 }}>
|
||||
<TopNavIcon
|
||||
theme={theme}
|
||||
onClick={() => handleOnClick(app)}
|
||||
className={`${isActive ? 'opened-active' : ''}`}>
|
||||
<StyledLink key={app.id}>
|
||||
<Dropdown menu={{ items: menuItems }} trigger={['contextMenu']} overlayStyle={{ zIndex: 10000 }}>
|
||||
<TopNavItemContainer
|
||||
className={`${isActive ? 'opened-active' : ''}`}
|
||||
onClick={() => handleOnClick(app)}
|
||||
theme={theme}>
|
||||
<TopNavIcon theme={theme}>
|
||||
<MinAppIcon size={22} app={app} style={{ border: 'none', padding: 0 }} />
|
||||
</TopNavIcon>
|
||||
</Dropdown>
|
||||
</StyledLink>
|
||||
</Tooltip>
|
||||
<TopNavLabel>{app.name}</TopNavLabel>
|
||||
</TopNavItemContainer>
|
||||
</Dropdown>
|
||||
</StyledLink>
|
||||
)
|
||||
})}
|
||||
</TopNavMenus>
|
||||
@ -327,7 +329,7 @@ const TabsWrapper = styled.div`
|
||||
const TopNavContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 2px;
|
||||
padding: 2px;
|
||||
gap: 6px;
|
||||
background-color: var(--color-list-item);
|
||||
border-radius: 20px;
|
||||
@ -351,16 +353,39 @@ const TopNavIcon = styled(Icon)`
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: ${({ theme }) => (theme === 'dark' ? 'var(--color-black)' : 'var(--color-white)')};
|
||||
opacity: 0.8;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.opened-active {
|
||||
background-color: ${({ theme }) => (theme === 'dark' ? 'var(--color-black)' : 'var(--color-white)')};
|
||||
border: 0.5px solid var(--color-border);
|
||||
border-radius: 50%;
|
||||
border-radius: 25%;
|
||||
.icon {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const TopNavLabel = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 4px;
|
||||
`
|
||||
|
||||
const TopNavItemContainer = styled.div`
|
||||
display: flex;
|
||||
padding: 4px 2px;
|
||||
transition: border 0.2s ease;
|
||||
border-radius: 18px;
|
||||
/* 避免布局偏移 */
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 2px solid var(--color-primary);
|
||||
opacity: 0.8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.opened-active {
|
||||
border: 1px solid var(--color-primary);
|
||||
.icon {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ import { useEffect } from 'react'
|
||||
import { useDefaultModel } from './useAssistant'
|
||||
import useFullScreenNotice from './useFullScreenNotice'
|
||||
import { useRuntime } from './useRuntime'
|
||||
import { useSettings } from './useSettings'
|
||||
import { useNavbarPosition, useSettings } from './useSettings'
|
||||
import useUpdateHandler from './useUpdateHandler'
|
||||
|
||||
const logger = loggerService.withContext('useAppInit')
|
||||
@ -31,6 +31,7 @@ export function useAppInit() {
|
||||
const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
|
||||
const { theme } = useTheme()
|
||||
const memoryConfig = useAppSelector(selectMemoryConfig)
|
||||
const { isTopNavbar } = useNavbarPosition()
|
||||
|
||||
useEffect(() => {
|
||||
document.getElementById('spinner')?.remove()
|
||||
@ -85,13 +86,17 @@ export function useAppInit() {
|
||||
const transparentWindow = windowStyle === 'transparent' && isMac && !minappShow
|
||||
|
||||
if (minappShow) {
|
||||
window.root.style.background =
|
||||
windowStyle === 'transparent' && isMac ? 'var(--color-background)' : 'var(--navbar-background)'
|
||||
if (isTopNavbar) {
|
||||
window.root.style.background = 'var(--navbar-background)'
|
||||
} else {
|
||||
window.root.style.background =
|
||||
windowStyle === 'transparent' && isMac ? 'var(--color-background)' : 'var(--navbar-background)'
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
window.root.style.background = transparentWindow ? 'var(--navbar-background-mac)' : 'var(--navbar-background)'
|
||||
}, [windowStyle, minappShow, theme])
|
||||
}, [windowStyle, minappShow, theme, isTopNavbar])
|
||||
|
||||
useEffect(() => {
|
||||
if (isLocalAi) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user