feat: dynamic max-height and width (#1)

This commit is contained in:
josc146
2023-03-16 10:18:13 +08:00
parent 804d21a006
commit 91d47a2970
6 changed files with 33 additions and 7 deletions
+3 -1
View File
@@ -9,6 +9,7 @@ import { WindowDesktop, XLg } from 'react-bootstrap-icons'
import FileSaver from 'file-saver'
import { render } from 'preact'
import FloatingToolbar from '../FloatingToolbar'
import { useClampWindowSize } from '../../hooks/use-clamp-window-size'
const logo = Browser.runtime.getURL('logo.png')
@@ -32,6 +33,7 @@ function ConversationCard(props) {
const [isReady, setIsReady] = useState(!props.question)
const [port, setPort] = useState(() => Browser.runtime.connect())
const [session, setSession] = useState(props.session)
const windowSize = useClampWindowSize([0, Infinity], [250, 1100])
/**
* @type {[ConversationItemData[], (conversationItemData: ConversationItemData[]) => void]}
*/
@@ -213,7 +215,7 @@ function ConversationCard(props) {
</span>
</div>
<hr />
<div className="markdown-body">
<div className="markdown-body" style={{ maxHeight: windowSize[1] * 0.75 + 'px' }}>
{conversationItemData.map((data, idx) => (
<ConversationItem
content={data.content}
+3 -1
View File
@@ -6,6 +6,7 @@ import { defaultConfig, getUserConfig } from '../../config.mjs'
import { config as toolsConfig } from '../../content-script/selection-tools'
import { setElementPositionInViewport } from '../../utils'
import Draggable from 'react-draggable'
import { useClampWindowSize } from '../../hooks/use-clamp-window-size'
const logo = Browser.runtime.getURL('logo.png')
@@ -16,6 +17,7 @@ function FloatingToolbar(props) {
const [render, setRender] = useState(false)
const [position, setPosition] = useState(props.position)
const [virtualPosition, setVirtualPosition] = useState({ x: 0, y: 0 })
const windowSize = useClampWindowSize([750, 1500], [0, Infinity])
useEffect(() => {
getUserConfig()
@@ -68,7 +70,7 @@ function FloatingToolbar(props) {
onStop={dragEvent.onStop}
position={virtualPosition}
>
<div className="gpt-selection-window">
<div className="gpt-selection-window" style={{ width: windowSize[0] * 0.4 + 'px' }}>
<div className="chat-gpt-container">
<ConversationCard
session={props.session}
+1 -3
View File
@@ -65,7 +65,6 @@
padding: 5px 15px 10px;
background-color: var(--theme-color);
color: var(--font-color);
max-height: 800px;
resize: vertical;
overflow-y: auto;
@@ -188,7 +187,7 @@
.dragbar {
cursor: move;
width: 250px;
width: 42%;
height: 12px;
border-radius: 10px;
background-color: var(--dragbar-color);
@@ -229,7 +228,6 @@
}
.gpt-selection-window {
width: 600px;
height: auto;
border-radius: 8px;
background-color: var(--theme-color);
+8
View File
@@ -0,0 +1,8 @@
import { useWindowSize } from './use-window-size.mjs'
export function useClampWindowSize(widthRange = [0, Infinity], heightRange = [0, Infinity]) {
const windowSize = useWindowSize()
windowSize[0] = Math.min(widthRange[1], Math.max(windowSize[0], widthRange[0]))
windowSize[1] = Math.min(heightRange[1], Math.max(windowSize[1], heightRange[0]))
return windowSize
}
+16
View File
@@ -0,0 +1,16 @@
// https://stackoverflow.com/questions/19014250/rerender-view-on-browser-resize-with-react
import { useLayoutEffect, useState } from 'react'
export function useWindowSize() {
const [size, setSize] = useState([0, 0])
useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight])
}
window.addEventListener('resize', updateSize)
updateSize()
return () => window.removeEventListener('resize', updateSize)
}, [])
return size
}
@@ -1,6 +1,6 @@
export function setElementPositionInViewport(element, x = 0, y = 0) {
const retX = Math.min(window.innerWidth - element.offsetWidth, Math.max(0, x))
const retY = Math.min(window.innerHeight - element.offsetHeight, Math.max(0, y))
const retX = Math.min(Math.max(0, window.innerWidth - element.offsetWidth), Math.max(0, x))
const retY = Math.min(Math.max(0, window.innerHeight - element.offsetHeight), Math.max(0, y))
element.style.left = retX + 'px'
element.style.top = retY + 'px'
return { x: retX, y: retY }