mirror of
https://github.com/wassname/chatGPTBox.git
synced 2026-07-07 18:19:43 +08:00
feat: make floating window of selectionTools dockable
This commit is contained in:
@@ -5,7 +5,7 @@ import InputBox from '../InputBox'
|
||||
import ConversationItem from '../ConversationItem'
|
||||
import { createElementAtPosition, initSession, isSafari } from '../../utils'
|
||||
import { DownloadIcon } from '@primer/octicons-react'
|
||||
import { WindowDesktop, XLg } from 'react-bootstrap-icons'
|
||||
import { WindowDesktop, XLg, Pin } from 'react-bootstrap-icons'
|
||||
import FileSaver from 'file-saver'
|
||||
import { render } from 'preact'
|
||||
import FloatingToolbar from '../FloatingToolbar'
|
||||
@@ -175,9 +175,7 @@ function ConversationCard(props) {
|
||||
return (
|
||||
<div className="gpt-inner">
|
||||
<div className="gpt-header">
|
||||
{!props.closeable ? (
|
||||
<img src={logo} width="20" height="20" style="margin:5px 15px 0px;user-select:none;" />
|
||||
) : (
|
||||
{props.closeable ? (
|
||||
<XLg
|
||||
className="gpt-util-icon"
|
||||
style="margin:5px 15px 0px;"
|
||||
@@ -187,6 +185,18 @@ function ConversationCard(props) {
|
||||
if (props.onClose) props.onClose()
|
||||
}}
|
||||
/>
|
||||
) : props.dockable ? (
|
||||
<Pin
|
||||
className="gpt-util-icon"
|
||||
style="margin:5px 15px 0px;"
|
||||
title="Pin the Window"
|
||||
size={16}
|
||||
onClick={() => {
|
||||
if (props.onDock) props.onDock()
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<img src={logo} width="20" height="20" style="margin:5px 15px 0px;user-select:none;" />
|
||||
)}
|
||||
{props.draggable ? (
|
||||
<div className="dragbar" />
|
||||
@@ -207,7 +217,6 @@ function ConversationCard(props) {
|
||||
container={toolbarContainer}
|
||||
closeable={true}
|
||||
triggered={true}
|
||||
onClose={() => toolbarContainer.remove()}
|
||||
/>,
|
||||
toolbarContainer,
|
||||
)
|
||||
@@ -278,6 +287,8 @@ ConversationCard.propTypes = {
|
||||
draggable: PropTypes.bool,
|
||||
closeable: PropTypes.bool,
|
||||
onClose: PropTypes.func,
|
||||
dockable: PropTypes.bool,
|
||||
onDock: PropTypes.func,
|
||||
}
|
||||
|
||||
export default memo(ConversationCard)
|
||||
|
||||
@@ -17,6 +17,7 @@ function FloatingToolbar(props) {
|
||||
const [config, setConfig] = useState(defaultConfig)
|
||||
const [render, setRender] = useState(false)
|
||||
const [position, setPosition] = useState(props.position)
|
||||
const [closeable, setCloseable] = useState(props.closeable)
|
||||
const [virtualPosition, setVirtualPosition] = useState({ x: 0, y: 0 })
|
||||
const windowSize = useClampWindowSize([750, 1500], [0, Infinity])
|
||||
|
||||
@@ -94,8 +95,15 @@ function FloatingToolbar(props) {
|
||||
session={props.session}
|
||||
question={prompt}
|
||||
draggable={true}
|
||||
closeable={props.closeable}
|
||||
onClose={props.onClose}
|
||||
closeable={closeable}
|
||||
onClose={() => {
|
||||
props.container.remove()
|
||||
}}
|
||||
dockable={props.dockable}
|
||||
onDock={() => {
|
||||
props.container.className = 'chatgptbox-toolbar-container-not-queryable'
|
||||
setCloseable(true)
|
||||
}}
|
||||
onUpdate={() => {
|
||||
updatePosition()
|
||||
}}
|
||||
@@ -145,7 +153,7 @@ FloatingToolbar.propTypes = {
|
||||
container: PropTypes.object.isRequired,
|
||||
triggered: PropTypes.bool,
|
||||
closeable: PropTypes.bool,
|
||||
onClose: PropTypes.func,
|
||||
dockable: PropTypes.bool,
|
||||
prompt: PropTypes.string,
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,10 @@ async function prepareForSafari() {
|
||||
}
|
||||
|
||||
let toolbarContainer
|
||||
const deleteToolbar = () => {
|
||||
if (toolbarContainer && toolbarContainer.className === 'chatgptbox-toolbar-container')
|
||||
toolbarContainer.remove()
|
||||
}
|
||||
|
||||
async function prepareForSelectionTools() {
|
||||
document.addEventListener('mouseup', (e) => {
|
||||
@@ -113,7 +117,7 @@ async function prepareForSelectionTools() {
|
||||
)
|
||||
return
|
||||
|
||||
if (toolbarContainer) toolbarContainer.remove()
|
||||
deleteToolbar()
|
||||
setTimeout(() => {
|
||||
const selection = window.getSelection()?.toString()
|
||||
if (selection) {
|
||||
@@ -126,6 +130,7 @@ async function prepareForSelectionTools() {
|
||||
selection={selection}
|
||||
position={position}
|
||||
container={toolbarContainer}
|
||||
dockable={true}
|
||||
/>,
|
||||
toolbarContainer,
|
||||
)
|
||||
@@ -144,7 +149,7 @@ async function prepareForSelectionTools() {
|
||||
(e.target.nodeName === 'INPUT' || e.target.nodeName === 'TEXTAREA')
|
||||
) {
|
||||
setTimeout(() => {
|
||||
if (!window.getSelection()?.toString()) toolbarContainer.remove()
|
||||
if (!window.getSelection()?.toString()) deleteToolbar()
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -160,7 +165,7 @@ async function prepareForSelectionToolsTouch() {
|
||||
)
|
||||
return
|
||||
|
||||
if (toolbarContainer) toolbarContainer.remove()
|
||||
deleteToolbar()
|
||||
setTimeout(() => {
|
||||
const selection = window.getSelection()?.toString()
|
||||
if (selection) {
|
||||
@@ -176,6 +181,7 @@ async function prepareForSelectionToolsTouch() {
|
||||
selection={selection}
|
||||
position={position}
|
||||
container={toolbarContainer}
|
||||
dockable={true}
|
||||
/>,
|
||||
toolbarContainer,
|
||||
)
|
||||
@@ -212,7 +218,6 @@ async function prepareForRightClickMenu() {
|
||||
container={container}
|
||||
triggered={true}
|
||||
closeable={true}
|
||||
onClose={() => container.remove()}
|
||||
/>,
|
||||
container,
|
||||
)
|
||||
@@ -228,7 +233,6 @@ async function prepareForRightClickMenu() {
|
||||
container={container}
|
||||
triggered={true}
|
||||
closeable={true}
|
||||
onClose={() => container.remove()}
|
||||
prompt={await toolsConfig[data.itemId].genPrompt(data.selectionText)}
|
||||
/>,
|
||||
container,
|
||||
|
||||
Reference in New Issue
Block a user