mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 14:41:24 +08:00
feat(SelectionAssistant): open URL for search action (#11770)
* feat(SelectionAssistant): open URL for search action When selected text is a valid URI or file path, directly open it instead of searching. This enhances the search action to be smarter about handling URLs and file paths. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * fix: format * feat: increase maximum custom and enabled items in settings actions list Updated the maximum number of custom items from 8 to 10 and enabled items from 6 to 8 in the settings actions list to enhance user customization options. --------- Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
parent
600a045ff7
commit
c4fd48376d
@ -9,8 +9,8 @@ import { DEFAULT_SEARCH_ENGINES } from '../components/SelectionActionSearchModal
|
||||
|
||||
const logger = loggerService.withContext('useSettingsActionsList')
|
||||
|
||||
const MAX_CUSTOM_ITEMS = 8
|
||||
const MAX_ENABLED_ITEMS = 6
|
||||
const MAX_CUSTOM_ITEMS = 10
|
||||
const MAX_ENABLED_ITEMS = 8
|
||||
|
||||
export const useActionItems = (
|
||||
initialItems: ActionItem[] | undefined,
|
||||
|
||||
@ -202,6 +202,30 @@ const SelectionToolbar: FC<{ demo?: boolean }> = ({ demo = false }) => {
|
||||
}
|
||||
}, [customCss, demo])
|
||||
|
||||
/**
|
||||
* Check if text is a valid URI or file path
|
||||
*/
|
||||
const isUriOrFilePath = (text: string): boolean => {
|
||||
const trimmed = text.trim()
|
||||
// Must not contain newlines or whitespace
|
||||
if (/\s/.test(trimmed)) {
|
||||
return false
|
||||
}
|
||||
// URI patterns: http://, https://, ftp://, file://, etc.
|
||||
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(trimmed)) {
|
||||
return true
|
||||
}
|
||||
// Windows absolute path: C:\, D:\, etc.
|
||||
if (/^[a-zA-Z]:[/\\]/.test(trimmed)) {
|
||||
return true
|
||||
}
|
||||
// Unix absolute path: /path/to/file
|
||||
if (/^\/[^/]/.test(trimmed)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// copy selected text to clipboard
|
||||
const handleCopy = useCallback(async () => {
|
||||
if (selectedText.current) {
|
||||
@ -219,6 +243,43 @@ const SelectionToolbar: FC<{ demo?: boolean }> = ({ demo = false }) => {
|
||||
}
|
||||
}, [setTimeoutTimer])
|
||||
|
||||
const handleSearch = useCallback((action: ActionItem) => {
|
||||
if (!action.selectedText) return
|
||||
|
||||
const selectedText = action.selectedText.trim()
|
||||
|
||||
let actionString = ''
|
||||
if (isUriOrFilePath(selectedText)) {
|
||||
actionString = selectedText
|
||||
} else {
|
||||
if (!action.searchEngine) return
|
||||
|
||||
const customUrl = action.searchEngine.split('|')[1]
|
||||
if (!customUrl) return
|
||||
|
||||
actionString = customUrl.replace('{{queryString}}', encodeURIComponent(selectedText))
|
||||
}
|
||||
|
||||
window.api?.openWebsite(actionString)
|
||||
window.api?.selection.hideToolbar()
|
||||
}, [])
|
||||
|
||||
/**
|
||||
* Quote the selected text to the inputbar of the main window
|
||||
*/
|
||||
const handleQuote = (action: ActionItem) => {
|
||||
if (action.selectedText) {
|
||||
window.api?.quoteToMainWindow(action.selectedText)
|
||||
window.api?.selection.hideToolbar()
|
||||
}
|
||||
}
|
||||
|
||||
const handleDefaultAction = (action: ActionItem) => {
|
||||
// [macOS] only macOS has the available isFullscreen mode
|
||||
window.api?.selection.processAction(action, isFullScreen.current)
|
||||
window.api?.selection.hideToolbar()
|
||||
}
|
||||
|
||||
const handleAction = useCallback(
|
||||
(action: ActionItem) => {
|
||||
if (demo) return
|
||||
@ -241,36 +302,9 @@ const SelectionToolbar: FC<{ demo?: boolean }> = ({ demo = false }) => {
|
||||
break
|
||||
}
|
||||
},
|
||||
[demo, handleCopy]
|
||||
[demo, handleCopy, handleSearch]
|
||||
)
|
||||
|
||||
const handleSearch = (action: ActionItem) => {
|
||||
if (!action.searchEngine) return
|
||||
|
||||
const customUrl = action.searchEngine.split('|')[1]
|
||||
if (!customUrl) return
|
||||
|
||||
const searchUrl = customUrl.replace('{{queryString}}', encodeURIComponent(action.selectedText || ''))
|
||||
window.api?.openWebsite(searchUrl)
|
||||
window.api?.selection.hideToolbar()
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote the selected text to the inputbar of the main window
|
||||
*/
|
||||
const handleQuote = (action: ActionItem) => {
|
||||
if (action.selectedText) {
|
||||
window.api?.quoteToMainWindow(action.selectedText)
|
||||
window.api?.selection.hideToolbar()
|
||||
}
|
||||
}
|
||||
|
||||
const handleDefaultAction = (action: ActionItem) => {
|
||||
// [macOS] only macOS has the available isFullscreen mode
|
||||
window.api?.selection.processAction(action, isFullScreen.current)
|
||||
window.api?.selection.hideToolbar()
|
||||
}
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<LogoWrapper $draggable={!demo}>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user