mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 23:10:20 +08:00
Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2
This commit is contained in:
commit
0a94609f78
5
.github/CODEOWNERS
vendored
5
.github/CODEOWNERS
vendored
@ -1,3 +1,8 @@
|
|||||||
|
/src/renderer/src/store/ @0xfullex
|
||||||
|
/src/main/services/ConfigManager.ts @0xfullex
|
||||||
|
/packages/shared/IpcChannel.ts @0xfullex
|
||||||
|
/src/main/ipc.ts @0xfullex
|
||||||
|
|
||||||
/migrations/ @0xfullex
|
/migrations/ @0xfullex
|
||||||
/packages/shared/data/ @0xfullex
|
/packages/shared/data/ @0xfullex
|
||||||
/src/main/data/ @0xfullex
|
/src/main/data/ @0xfullex
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
out
|
out/
|
||||||
dist
|
dist/
|
||||||
pnpm-lock.yaml
|
build/
|
||||||
LICENSE.md
|
.yarn/
|
||||||
tsconfig.json
|
.github/
|
||||||
tsconfig.*.json
|
.husky/
|
||||||
CHANGELOG*.md
|
.vscode/
|
||||||
agents.json
|
*.yaml
|
||||||
src/renderer/src/integration/nutstore/sso/lib
|
*.yml
|
||||||
AGENT.md
|
*.mjs
|
||||||
|
*.cjs
|
||||||
|
*.md
|
||||||
|
*.json
|
||||||
src/main/integration/
|
src/main/integration/
|
||||||
.yarn/releases/
|
|
||||||
|
|||||||
@ -341,11 +341,12 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
|
|||||||
scrollTriggerRef.current = 'none'
|
scrollTriggerRef.current = 'none'
|
||||||
}, [index])
|
}, [index])
|
||||||
|
|
||||||
// 处理键盘事件(折叠时不拦截全局键盘)
|
// 处理键盘事件:
|
||||||
|
// - 可见且未折叠时:拦截 Enter 及其组合键(纯 Enter 选择项;带修饰键仅拦截不处理)。
|
||||||
|
// - 软隐藏/折叠时:不拦截 Enter,允许输入框处理(用于发送消息等)。
|
||||||
|
// - 不可见时:不拦截,输入框按常规处理。
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hasSearchTextFlag = searchText.replace(/^[/@]/, '').length > 0
|
if (!ctx.isVisible) return
|
||||||
const isCollapsed = hasSearchTextFlag && list.length === 0
|
|
||||||
if (!ctx.isVisible || isCollapsed) return
|
|
||||||
|
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
if (isMac ? e.metaKey : e.ctrlKey) {
|
if (isMac ? e.metaKey : e.ctrlKey) {
|
||||||
@ -438,9 +439,24 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
|
|||||||
break
|
break
|
||||||
|
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
case 'NumpadEnter':
|
case 'NumpadEnter': {
|
||||||
if (isComposing.current) return
|
if (isComposing.current) return
|
||||||
|
|
||||||
|
// 折叠/软隐藏时不拦截,让输入框处理(用于发送消息)
|
||||||
|
const hasSearch = searchText.replace(/^[/@]/, '').length > 0
|
||||||
|
const nonPinnedCount = list.filter((i) => !i.alwaysVisible).length
|
||||||
|
const isCollapsed = hasSearch && nonPinnedCount === 0
|
||||||
|
if (isCollapsed) return
|
||||||
|
|
||||||
|
// 面板可见且未折叠时:拦截所有 Enter 变体;
|
||||||
|
// 纯 Enter 选择项,带修饰键仅拦截不处理
|
||||||
|
if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
setIsMouseOver(false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if (list?.[index]) {
|
if (list?.[index]) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@ -451,6 +467,7 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
|
|||||||
handleClose('enter_empty')
|
handleClose('enter_empty')
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
}
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
handleClose('esc')
|
handleClose('esc')
|
||||||
|
|||||||
@ -406,37 +406,40 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
//other keys should be ignored
|
//other keys should be ignored
|
||||||
const isEnterPressed = event.key === 'Enter' && !event.nativeEvent.isComposing
|
const isEnterPressed = event.key === 'Enter' && !event.nativeEvent.isComposing
|
||||||
if (isEnterPressed) {
|
if (isEnterPressed) {
|
||||||
if (quickPanel.isVisible) return event.preventDefault()
|
// 1) 优先判断是否为“发送”(当前仅支持纯 Enter 发送;其余 Enter 组合键均换行)
|
||||||
|
|
||||||
if (isSendMessageKeyPressed(event, sendMessageShortcut)) {
|
if (isSendMessageKeyPressed(event, sendMessageShortcut)) {
|
||||||
sendMessage()
|
sendMessage()
|
||||||
return event.preventDefault()
|
return event.preventDefault()
|
||||||
} else {
|
}
|
||||||
//shift+enter's default behavior is to add a new line, ignore it
|
|
||||||
if (!event.shiftKey) {
|
|
||||||
event.preventDefault()
|
|
||||||
|
|
||||||
const textArea = textareaRef.current?.resizableTextArea?.textArea
|
// 2) 不再基于 quickPanel.isVisible 主动拦截。
|
||||||
if (textArea) {
|
// 纯 Enter 的处理权交由 QuickPanel 的全局捕获(其只在纯 Enter 时拦截),
|
||||||
const start = textArea.selectionStart
|
// 其它带修饰键的 Enter 则由输入框处理为换行。
|
||||||
const end = textArea.selectionEnd
|
|
||||||
const text = textArea.value
|
|
||||||
const newText = text.substring(0, start) + '\n' + text.substring(end)
|
|
||||||
|
|
||||||
// update text by setState, not directly modify textarea.value
|
if (event.shiftKey) {
|
||||||
setText(newText)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// set cursor position in the next render cycle
|
event.preventDefault()
|
||||||
setTimeoutTimer(
|
const textArea = textareaRef.current?.resizableTextArea?.textArea
|
||||||
'handleKeyDown',
|
if (textArea) {
|
||||||
() => {
|
const start = textArea.selectionStart
|
||||||
textArea.selectionStart = textArea.selectionEnd = start + 1
|
const end = textArea.selectionEnd
|
||||||
onInput() // trigger resizeTextArea
|
const text = textArea.value
|
||||||
},
|
const newText = text.substring(0, start) + '\n' + text.substring(end)
|
||||||
0
|
|
||||||
)
|
// update text by setState, not directly modify textarea.value
|
||||||
}
|
setText(newText)
|
||||||
}
|
|
||||||
|
// set cursor position in the next render cycle
|
||||||
|
setTimeoutTimer(
|
||||||
|
'handleKeyDown',
|
||||||
|
() => {
|
||||||
|
textArea.selectionStart = textArea.selectionEnd = start + 1
|
||||||
|
onInput() // trigger resizeTextArea
|
||||||
|
},
|
||||||
|
0
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user