mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-07 22:10:21 +08:00
refactor(ModelList): improve group style (#8761)
* refactor(ModelList): 重构模型列表组件结构,优化分组渲染逻辑 将扁平化列表结构改为嵌套结构,提升分组模型的渲染性能 移除不必要的状态依赖,简化组件逻辑 添加分组容器样式,改善视觉呈现 * Revert "refactor(ModelList): 重构模型列表组件结构,优化分组渲染逻辑" This reverts commitf60f6267e6. * refactor(ModelList): 优化模型列表的渲染和样式 - 使用startTransition优化折叠/展开性能 - 重构数据结构,将单个模型渲染改为批量渲染 - 改进组头和模型项的样式和布局 * Revert "refactor(ModelList): 优化模型列表的渲染和样式" This reverts commite18286c70e. * feat(模型列表): 优化模型列表项的样式和分组显示 添加last属性标记列表最后一项,优化分组标题和列表项的样式 移除多余的底部间距,调整边框圆角以提升视觉一致性 * refactor: 移除调试用的console.log语句 * style(ManageModelsList): 调整分组标题的内边距以改善视觉间距 * style(ModelList): 移动按钮位置 * style(ManageModelsList): 调整列表项和分组标题的高度以优化空间使用 * style(ManageModelsList): 为滚动容器添加圆角边框样式
This commit is contained in:
parent
fb2dccc7ff
commit
63198ee3d2
@ -26,6 +26,7 @@ interface GroupRowData {
|
|||||||
interface ModelRowData {
|
interface ModelRowData {
|
||||||
type: 'model'
|
type: 'model'
|
||||||
model: Model
|
model: Model
|
||||||
|
last?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type RowData = GroupRowData | ModelRowData
|
type RowData = GroupRowData | ModelRowData
|
||||||
@ -62,9 +63,16 @@ const ManageModelsList: React.FC<ManageModelsListProps> = ({ modelGroups, provid
|
|||||||
// 只添加非空组
|
// 只添加非空组
|
||||||
rows.push({ type: 'group', groupName, models })
|
rows.push({ type: 'group', groupName, models })
|
||||||
if (!collapsedGroups.has(groupName)) {
|
if (!collapsedGroups.has(groupName)) {
|
||||||
models.forEach((model) => {
|
rows.push(
|
||||||
rows.push({ type: 'model', model })
|
...models.map(
|
||||||
})
|
(model, index) =>
|
||||||
|
({
|
||||||
|
type: 'model',
|
||||||
|
model,
|
||||||
|
last: index === models.length - 1 ? true : undefined
|
||||||
|
}) as const
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -131,18 +139,15 @@ const ManageModelsList: React.FC<ManageModelsListProps> = ({ modelGroups, provid
|
|||||||
isSticky={useCallback((index: number) => flatRows[index].type === 'group', [flatRows])}
|
isSticky={useCallback((index: number) => flatRows[index].type === 'group', [flatRows])}
|
||||||
overscan={5}
|
overscan={5}
|
||||||
scrollerStyle={{
|
scrollerStyle={{
|
||||||
paddingRight: '10px'
|
paddingRight: '10px',
|
||||||
}}
|
borderRadius: '8px'
|
||||||
itemContainerStyle={{
|
|
||||||
paddingBottom: '8px'
|
|
||||||
}}>
|
}}>
|
||||||
{(row) => {
|
{(row) => {
|
||||||
if (row.type === 'group') {
|
if (row.type === 'group') {
|
||||||
const isCollapsed = collapsedGroups.has(row.groupName)
|
const isCollapsed = collapsedGroups.has(row.groupName)
|
||||||
return (
|
return (
|
||||||
<GroupHeader
|
<GroupHeaderContainer isCollapsed={isCollapsed}>
|
||||||
style={{ background: 'var(--color-background)' }}
|
<GroupHeader isCollapsed={isCollapsed} onClick={() => handleGroupToggle(row.groupName)}>
|
||||||
onClick={() => handleGroupToggle(row.groupName)}>
|
|
||||||
<Flex align="center" gap={10} style={{ flex: 1 }}>
|
<Flex align="center" gap={10} style={{ flex: 1 }}>
|
||||||
<ChevronRight
|
<ChevronRight
|
||||||
size={16}
|
size={16}
|
||||||
@ -157,11 +162,18 @@ const ManageModelsList: React.FC<ManageModelsListProps> = ({ modelGroups, provid
|
|||||||
</Flex>
|
</Flex>
|
||||||
{renderGroupTools(row.models)}
|
{renderGroupTools(row.models)}
|
||||||
</GroupHeader>
|
</GroupHeader>
|
||||||
|
</GroupHeaderContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModelListItem model={row.model} provider={provider} onAddModel={onAddModel} onRemoveModel={onRemoveModel} />
|
<ModelListItem
|
||||||
|
last={row.last}
|
||||||
|
model={row.model}
|
||||||
|
provider={provider}
|
||||||
|
onAddModel={onAddModel}
|
||||||
|
onRemoveModel={onRemoveModel}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</DynamicVirtualList>
|
</DynamicVirtualList>
|
||||||
@ -174,12 +186,13 @@ interface ModelListItemProps {
|
|||||||
provider: Provider
|
provider: Provider
|
||||||
onAddModel: (model: Model) => void
|
onAddModel: (model: Model) => void
|
||||||
onRemoveModel: (model: Model) => void
|
onRemoveModel: (model: Model) => void
|
||||||
|
last?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModelListItem: React.FC<ModelListItemProps> = memo(({ model, provider, onAddModel, onRemoveModel }) => {
|
const ModelListItem: React.FC<ModelListItemProps> = memo(({ model, provider, onAddModel, onRemoveModel, last }) => {
|
||||||
const isAdded = useMemo(() => isModelInProvider(provider, model.id), [provider, model.id])
|
const isAdded = useMemo(() => isModelInProvider(provider, model.id), [provider, model.id])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<ModelListItemContainer last={last}>
|
||||||
<FileItem
|
<FileItem
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: isAdded ? 'rgba(0, 126, 0, 0.06)' : '',
|
backgroundColor: isAdded ? 'rgba(0, 126, 0, 0.06)' : '',
|
||||||
@ -198,17 +211,33 @@ const ModelListItem: React.FC<ModelListItemProps> = memo(({ model, provider, onA
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</ModelListItemContainer>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const GroupHeader = styled.div`
|
const GroupHeader = styled.div<{ isCollapsed: boolean }>`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
background-color: var(--color-background-mute);
|
||||||
|
border-radius: ${(props) => (props.isCollapsed ? '8px' : '8px 8px 0 0')};
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 8px;
|
padding: 0 13px;
|
||||||
min-height: 50px;
|
min-height: 35px;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const GroupHeaderContainer = styled.div<{ isCollapsed: boolean }>`
|
||||||
|
padding-bottom: ${(props) => (props.isCollapsed ? '8px' : '0')};
|
||||||
|
`
|
||||||
|
|
||||||
|
const ModelListItemContainer = styled.div<{ last?: boolean }>`
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
padding: 4px;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: ${(props) => (props.last ? '0 0 8px 8px' : '0')};
|
||||||
|
border-bottom: ${(props) => (props.last ? '1px solid var(--color-border)' : 'none')};
|
||||||
|
margin-bottom: ${(props) => (props.last ? '8px' : '0')};
|
||||||
|
`
|
||||||
|
|
||||||
export default memo(ManageModelsList)
|
export default memo(ManageModelsList)
|
||||||
|
|||||||
@ -206,6 +206,7 @@ const ModelList: React.FC<ModelListProps> = ({ providerId }) => {
|
|||||||
) : (
|
) : (
|
||||||
<div style={{ height: 5 }} />
|
<div style={{ height: 5 }} />
|
||||||
)}
|
)}
|
||||||
|
</Flex>
|
||||||
<Flex gap={10} style={{ marginTop: 12 }}>
|
<Flex gap={10} style={{ marginTop: 12 }}>
|
||||||
<Button type="primary" onClick={onManageModel} icon={<ListCheck size={16} />} disabled={isHealthChecking}>
|
<Button type="primary" onClick={onManageModel} icon={<ListCheck size={16} />} disabled={isHealthChecking}>
|
||||||
{t('button.manage')}
|
{t('button.manage')}
|
||||||
@ -214,7 +215,6 @@ const ModelList: React.FC<ModelListProps> = ({ providerId }) => {
|
|||||||
{t('button.add')}
|
{t('button.add')}
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user