fix: group message bugs
This commit is contained in:
parent
084da9ebab
commit
a6f086e3be
@ -256,9 +256,6 @@ body,
|
|||||||
border: 1px solid var(--color-background-mute);
|
border: 1px solid var(--color-background-mute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.group-menu-bar {
|
|
||||||
background-color: var(--color-background);
|
|
||||||
}
|
|
||||||
code {
|
code {
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -253,6 +253,10 @@
|
|||||||
"message.style": "Message style",
|
"message.style": "Message style",
|
||||||
"message.style.bubble": "Bubble",
|
"message.style.bubble": "Bubble",
|
||||||
"message.style.plain": "Plain",
|
"message.style.plain": "Plain",
|
||||||
|
"message.multi_model_style": "Multi-model answer style",
|
||||||
|
"message.multi_model_style.horizontal": "Horizontal",
|
||||||
|
"message.multi_model_style.vertical": "Vertical",
|
||||||
|
"message.multi_model_style.fold": "Fold",
|
||||||
"reset.confirm.content": "Are you sure you want to clear all data?",
|
"reset.confirm.content": "Are you sure you want to clear all data?",
|
||||||
"reset.double.confirm.content": "All data will be lost, do you want to continue?",
|
"reset.double.confirm.content": "All data will be lost, do you want to continue?",
|
||||||
"reset.double.confirm.title": "DATA LOST !!!",
|
"reset.double.confirm.title": "DATA LOST !!!",
|
||||||
|
|||||||
@ -252,6 +252,10 @@
|
|||||||
"message.style": "メッセージスタイル",
|
"message.style": "メッセージスタイル",
|
||||||
"message.style.bubble": "バブル",
|
"message.style.bubble": "バブル",
|
||||||
"message.style.plain": "プレーン",
|
"message.style.plain": "プレーン",
|
||||||
|
"message.multi_model_style": "複数モデル回答スタイル",
|
||||||
|
"message.multi_model_style.horizontal": "水平",
|
||||||
|
"message.multi_model_style.vertical": "垂直",
|
||||||
|
"message.multi_model_style.fold": "折りたたむ",
|
||||||
"reset.confirm.content": "すべてのデータをリセットしてもよろしいですか?",
|
"reset.confirm.content": "すべてのデータをリセットしてもよろしいですか?",
|
||||||
"reset.double.confirm.content": "すべてのデータが失われます。続行しますか?",
|
"reset.double.confirm.content": "すべてのデータが失われます。続行しますか?",
|
||||||
"reset.double.confirm.title": "データが失われます!!!",
|
"reset.double.confirm.title": "データが失われます!!!",
|
||||||
|
|||||||
@ -253,6 +253,10 @@
|
|||||||
"message.style": "Стиль сообщения",
|
"message.style": "Стиль сообщения",
|
||||||
"message.style.bubble": "Пузырь",
|
"message.style.bubble": "Пузырь",
|
||||||
"message.style.plain": "Простой",
|
"message.style.plain": "Простой",
|
||||||
|
"message.multi_model_style": "Стиль ответов от нескольких моделей",
|
||||||
|
"message.multi_model_style.horizontal": "Горизонтальный",
|
||||||
|
"message.multi_model_style.vertical": "Вертикальный",
|
||||||
|
"message.multi_model_style.fold": "Свернуть",
|
||||||
"reset.confirm.content": "Вы уверены, что хотите очистить все данные?",
|
"reset.confirm.content": "Вы уверены, что хотите очистить все данные?",
|
||||||
"reset.double.confirm.content": "Все данные будут утеряны, хотите продолжить?",
|
"reset.double.confirm.content": "Все данные будут утеряны, хотите продолжить?",
|
||||||
"reset.double.confirm.title": "ДАННЫЕ БУДУТ УТЕРЯНЫ !!!",
|
"reset.double.confirm.title": "ДАННЫЕ БУДУТ УТЕРЯНЫ !!!",
|
||||||
|
|||||||
@ -253,6 +253,10 @@
|
|||||||
"message.style": "消息樣式",
|
"message.style": "消息樣式",
|
||||||
"message.style.bubble": "氣泡",
|
"message.style.bubble": "氣泡",
|
||||||
"message.style.plain": "簡潔",
|
"message.style.plain": "簡潔",
|
||||||
|
"message.multi_model_style": "多模型回答樣式",
|
||||||
|
"message.multi_model_style.horizontal": "水平",
|
||||||
|
"message.multi_model_style.vertical": "垂直",
|
||||||
|
"message.multi_model_style.fold": "折疊",
|
||||||
"reset.confirm.content": "確定要清除所有資料嗎?",
|
"reset.confirm.content": "確定要清除所有資料嗎?",
|
||||||
"reset.double.confirm.content": "所有資料將會被清除,您確定要繼續嗎?",
|
"reset.double.confirm.content": "所有資料將會被清除,您確定要繼續嗎?",
|
||||||
"reset.double.confirm.title": "資料將會丟失!!!",
|
"reset.double.confirm.title": "資料將會丟失!!!",
|
||||||
|
|||||||
@ -27,6 +27,7 @@ interface Props {
|
|||||||
total?: number
|
total?: number
|
||||||
hidePresetMessages?: boolean
|
hidePresetMessages?: boolean
|
||||||
style?: React.CSSProperties
|
style?: React.CSSProperties
|
||||||
|
isGrouped?: boolean
|
||||||
onGetMessages?: () => Message[]
|
onGetMessages?: () => Message[]
|
||||||
onSetMessages?: Dispatch<SetStateAction<Message[]>>
|
onSetMessages?: Dispatch<SetStateAction<Message[]>>
|
||||||
onDeleteMessage?: (message: Message) => Promise<void>
|
onDeleteMessage?: (message: Message) => Promise<void>
|
||||||
@ -45,6 +46,7 @@ const MessageItem: FC<Props> = ({
|
|||||||
topic,
|
topic,
|
||||||
index,
|
index,
|
||||||
hidePresetMessages,
|
hidePresetMessages,
|
||||||
|
isGrouped,
|
||||||
style,
|
style,
|
||||||
onDeleteMessage,
|
onDeleteMessage,
|
||||||
onSetMessages,
|
onSetMessages,
|
||||||
@ -187,6 +189,7 @@ const MessageItem: FC<Props> = ({
|
|||||||
index={index}
|
index={index}
|
||||||
isLastMessage={isLastMessage}
|
isLastMessage={isLastMessage}
|
||||||
isAssistantMessage={isAssistantMessage}
|
isAssistantMessage={isAssistantMessage}
|
||||||
|
isGrouped={isGrouped}
|
||||||
setModel={setModel}
|
setModel={setModel}
|
||||||
onEditMessage={onEditMessage}
|
onEditMessage={onEditMessage}
|
||||||
onDeleteMessage={onDeleteMessage}
|
onDeleteMessage={onDeleteMessage}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { useSettings } from '@renderer/hooks/useSettings'
|
|||||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
||||||
import { MultiModelMessageStyle } from '@renderer/store/settings'
|
import { MultiModelMessageStyle } from '@renderer/store/settings'
|
||||||
import { Message, Model, Topic } from '@renderer/types'
|
import { Message, Model, Topic } from '@renderer/types'
|
||||||
import { Button, Segmented } from 'antd'
|
import { Button, Segmented as AntdSegmented } from 'antd'
|
||||||
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'
|
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'
|
||||||
import styled, { css } from 'styled-components'
|
import styled, { css } from 'styled-components'
|
||||||
|
|
||||||
@ -63,6 +63,7 @@ const MessageGroup: FC<Props> = ({
|
|||||||
key={message.id}
|
key={message.id}
|
||||||
className={message.role === 'assistant' && isHorizontal && isGrouped ? 'group-message-wrapper' : ''}>
|
className={message.role === 'assistant' && isHorizontal && isGrouped ? 'group-message-wrapper' : ''}>
|
||||||
<MessageItem
|
<MessageItem
|
||||||
|
isGrouped={isGrouped}
|
||||||
message={message}
|
message={message}
|
||||||
topic={topic}
|
topic={topic}
|
||||||
index={message.index}
|
index={message.index}
|
||||||
@ -76,10 +77,10 @@ const MessageGroup: FC<Props> = ({
|
|||||||
))}
|
))}
|
||||||
</GridContainer>
|
</GridContainer>
|
||||||
{isGrouped && (
|
{isGrouped && (
|
||||||
<GroupMenuBar className="group-menu-bar">
|
<GroupMenuBar className="group-menu-bar" $layout={multiModelMessageStyle}>
|
||||||
<HStack style={{ alignItems: 'center', flex: 1, overflow: 'hidden' }}>
|
<HStack style={{ alignItems: 'center', flex: 1, overflow: 'hidden' }}>
|
||||||
<LayoutContainer>
|
<LayoutContainer>
|
||||||
{['fold', 'horizontal', 'vertical'].map((layout) => (
|
{['fold', 'vertical', 'horizontal'].map((layout) => (
|
||||||
<LayoutOption
|
<LayoutOption
|
||||||
key={layout}
|
key={layout}
|
||||||
active={multiModelMessageStyle === layout}
|
active={multiModelMessageStyle === layout}
|
||||||
@ -180,17 +181,20 @@ const MessageWrapper = styled(Scrollbar)<MessageWrapperProps>`
|
|||||||
}}
|
}}
|
||||||
`
|
`
|
||||||
|
|
||||||
const GroupMenuBar = styled.div`
|
const GroupMenuBar = styled.div<{ $layout: MultiModelMessageStyle }>`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
background-color: var(--color-background-soft);
|
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border: 0.5px solid var(--color-border);
|
||||||
|
height: 40px;
|
||||||
|
margin-left: ${({ $layout }) => ($layout === 'horizontal' ? '0' : '40px')};
|
||||||
|
transition: all 0.3s ease;
|
||||||
`
|
`
|
||||||
|
|
||||||
const LayoutContainer = styled.div`
|
const LayoutContainer = styled.div`
|
||||||
@ -203,11 +207,10 @@ const LayoutOption = styled.div<{ active: boolean }>`
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: ${({ active }) => (active ? 'var(--color-primary)' : 'transparent')};
|
background-color: ${({ active }) => (active ? 'var(--color-background-soft)' : 'transparent')};
|
||||||
color: ${({ active }) => (active ? 'var(--color-white)' : 'inherit')};
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: ${({ active }) => (active ? 'var(--color-primary)' : 'var(--color-hover)')};
|
background-color: ${({ active }) => (active ? 'var(--color-background-soft)' : 'var(--color-hover)')};
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -220,6 +223,22 @@ const ModelsContainer = styled(Scrollbar)`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const Segmented = styled(AntdSegmented)`
|
||||||
|
.ant-segmented-item {
|
||||||
|
background-color: transparent !important;
|
||||||
|
transition: none !important;
|
||||||
|
&:hover {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ant-segmented-thumb,
|
||||||
|
.ant-segmented-item-selected {
|
||||||
|
background-color: transparent !important;
|
||||||
|
border: 0.5px solid var(--color-border);
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
const SegmentedLabel = styled.div`
|
const SegmentedLabel = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@ -30,6 +30,7 @@ interface Props {
|
|||||||
assistantModel?: Model
|
assistantModel?: Model
|
||||||
model?: Model
|
model?: Model
|
||||||
index?: number
|
index?: number
|
||||||
|
isGrouped?: boolean
|
||||||
isLastMessage: boolean
|
isLastMessage: boolean
|
||||||
isAssistantMessage: boolean
|
isAssistantMessage: boolean
|
||||||
setModel: (model: Model) => void
|
setModel: (model: Model) => void
|
||||||
@ -42,6 +43,7 @@ const MessageMenubar: FC<Props> = (props) => {
|
|||||||
const {
|
const {
|
||||||
message,
|
message,
|
||||||
index,
|
index,
|
||||||
|
isGrouped,
|
||||||
model,
|
model,
|
||||||
isLastMessage,
|
isLastMessage,
|
||||||
isAssistantMessage,
|
isAssistantMessage,
|
||||||
@ -252,14 +254,16 @@ const MessageMenubar: FC<Props> = (props) => {
|
|||||||
</ActionButton>
|
</ActionButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
|
disabled={isGrouped}
|
||||||
title={t('message.message.delete.content')}
|
title={t('message.message.delete.content')}
|
||||||
okButtonProps={{ danger: true }}
|
okButtonProps={{ danger: true }}
|
||||||
icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
|
icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
|
||||||
onConfirm={() => onDeleteMessage?.(message)}>
|
onConfirm={() => onDeleteMessage?.(message)}>
|
||||||
<Tooltip title={t('common.delete')} mouseEnterDelay={1}>
|
<Tooltip title={t('common.delete')} mouseEnterDelay={1}>
|
||||||
<ActionButton className="message-action-button">
|
<ActionButton
|
||||||
|
className="message-action-button"
|
||||||
|
onClick={isGrouped ? () => onDeleteMessage?.(message) : undefined}>
|
||||||
<DeleteOutlined />
|
<DeleteOutlined />
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@ -265,8 +265,8 @@ const SettingsTab: FC<Props> = (props) => {
|
|||||||
onChange={(value) => dispatch(setMultiModelMessageStyle(value))}
|
onChange={(value) => dispatch(setMultiModelMessageStyle(value))}
|
||||||
style={{ width: 135 }}>
|
style={{ width: 135 }}>
|
||||||
<Select.Option value="fold">{t('message.message.multi_model_style.fold')}</Select.Option>
|
<Select.Option value="fold">{t('message.message.multi_model_style.fold')}</Select.Option>
|
||||||
<Select.Option value="horizontal">{t('message.message.multi_model_style.horizontal')}</Select.Option>
|
|
||||||
<Select.Option value="vertical">{t('message.message.multi_model_style.vertical')}</Select.Option>
|
<Select.Option value="vertical">{t('message.message.multi_model_style.vertical')}</Select.Option>
|
||||||
|
<Select.Option value="horizontal">{t('message.message.multi_model_style.horizontal')}</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
</SettingRow>
|
</SettingRow>
|
||||||
<SettingDivider />
|
<SettingDivider />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user