mirror of
https://github.com/wassname/chatGPTBox.git
synced 2026-07-12 14:37:23 +08:00
feat: make the floating selectionTools follow the scrolling, while the result window remains fixed (#40)
This commit is contained in:
@@ -213,7 +213,6 @@ function ConversationCard(props) {
|
||||
<FloatingToolbar
|
||||
session={session}
|
||||
selection=""
|
||||
position={position}
|
||||
container={toolbarContainer}
|
||||
closeable={true}
|
||||
triggered={true}
|
||||
|
||||
@@ -4,7 +4,7 @@ import ConversationCard from '../ConversationCard'
|
||||
import PropTypes from 'prop-types'
|
||||
import { defaultConfig, getUserConfig } from '../../config/index.mjs'
|
||||
import { config as toolsConfig } from '../../content-script/selection-tools'
|
||||
import { isMobile, setElementPositionInViewport } from '../../utils'
|
||||
import { getClientPosition, isMobile, setElementPositionInViewport } from '../../utils'
|
||||
import Draggable from 'react-draggable'
|
||||
import { useClampWindowSize } from '../../hooks/use-clamp-window-size'
|
||||
|
||||
@@ -16,8 +16,8 @@ function FloatingToolbar(props) {
|
||||
const [triggered, setTriggered] = useState(props.triggered)
|
||||
const [config, setConfig] = useState(defaultConfig)
|
||||
const [render, setRender] = useState(false)
|
||||
const [position, setPosition] = useState(props.position)
|
||||
const [closeable, setCloseable] = useState(props.closeable)
|
||||
const [position, setPosition] = useState(getClientPosition(props.container))
|
||||
const [virtualPosition, setVirtualPosition] = useState({ x: 0, y: 0 })
|
||||
const windowSize = useClampWindowSize([750, 1500], [0, Infinity])
|
||||
|
||||
@@ -25,6 +25,8 @@ function FloatingToolbar(props) {
|
||||
getUserConfig().then((config) => {
|
||||
setConfig(config)
|
||||
setRender(true)
|
||||
|
||||
if (!triggered) props.container.style.position = 'absolute'
|
||||
})
|
||||
}, [])
|
||||
|
||||
@@ -127,6 +129,9 @@ function FloatingToolbar(props) {
|
||||
className: 'chatgptbox-selection-toolbar-button',
|
||||
title: toolConfig.label,
|
||||
onClick: async () => {
|
||||
const p = getClientPosition(props.container)
|
||||
props.container.style.position = 'fixed'
|
||||
setPosition(p)
|
||||
setPrompt(await toolConfig.genPrompt(selection))
|
||||
setTriggered(true)
|
||||
},
|
||||
@@ -149,7 +154,6 @@ function FloatingToolbar(props) {
|
||||
FloatingToolbar.propTypes = {
|
||||
session: PropTypes.object.isRequired,
|
||||
selection: PropTypes.string.isRequired,
|
||||
position: PropTypes.object.isRequired,
|
||||
container: PropTypes.object.isRequired,
|
||||
triggered: PropTypes.bool,
|
||||
closeable: PropTypes.bool,
|
||||
|
||||
@@ -121,14 +121,12 @@ async function prepareForSelectionTools() {
|
||||
setTimeout(() => {
|
||||
const selection = window.getSelection()?.toString()
|
||||
if (selection) {
|
||||
const position = { x: e.clientX + 15, y: e.clientY - 15 }
|
||||
toolbarContainer = createElementAtPosition(position.x, position.y)
|
||||
toolbarContainer = createElementAtPosition(e.pageX + 15, e.pageY - 15)
|
||||
toolbarContainer.className = 'chatgptbox-toolbar-container'
|
||||
render(
|
||||
<FloatingToolbar
|
||||
session={initSession()}
|
||||
selection={selection}
|
||||
position={position}
|
||||
container={toolbarContainer}
|
||||
dockable={true}
|
||||
/>,
|
||||
@@ -169,17 +167,15 @@ async function prepareForSelectionToolsTouch() {
|
||||
setTimeout(() => {
|
||||
const selection = window.getSelection()?.toString()
|
||||
if (selection) {
|
||||
const position = {
|
||||
x: e.changedTouches[0].clientX + 15,
|
||||
y: e.changedTouches[0].clientY - 15,
|
||||
}
|
||||
toolbarContainer = createElementAtPosition(position.x, position.y)
|
||||
toolbarContainer = createElementAtPosition(
|
||||
e.changedTouches[0].pageX + 15,
|
||||
e.changedTouches[0].pageY - 15,
|
||||
)
|
||||
toolbarContainer.className = 'chatgptbox-toolbar-container'
|
||||
render(
|
||||
<FloatingToolbar
|
||||
session={initSession()}
|
||||
selection={selection}
|
||||
position={position}
|
||||
container={toolbarContainer}
|
||||
dockable={true}
|
||||
/>,
|
||||
@@ -214,7 +210,6 @@ async function prepareForRightClickMenu() {
|
||||
<FloatingToolbar
|
||||
session={initSession()}
|
||||
selection=""
|
||||
position={position}
|
||||
container={container}
|
||||
triggered={true}
|
||||
closeable={true}
|
||||
@@ -229,7 +224,6 @@ async function prepareForRightClickMenu() {
|
||||
<FloatingToolbar
|
||||
session={initSession()}
|
||||
selection={data.selectionText}
|
||||
position={position}
|
||||
container={container}
|
||||
triggered={true}
|
||||
closeable={true}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export function getClientPosition(e) {
|
||||
const rect = e.getBoundingClientRect()
|
||||
return { x: rect.left, y: rect.top }
|
||||
}
|
||||
@@ -2,6 +2,7 @@ export * from './create-element-at-position'
|
||||
export * from './crop-text'
|
||||
export * from './ends-with-question-mark'
|
||||
export * from './fetch-sse'
|
||||
export * from './get-client-position'
|
||||
export * from './get-conversation-pairs'
|
||||
export * from './get-possible-element-by-query-selector'
|
||||
export * from './init-session'
|
||||
|
||||
Reference in New Issue
Block a user