refactor(useResizable): refactor and fix useCallback dependency warning

This commit is contained in:
molvqingtai 2023-11-15 16:07:58 +08:00
parent fd0ecf579d
commit 387576c16c
7 changed files with 548 additions and 144 deletions

View file

@ -44,6 +44,7 @@
"@typescript-eslint/no-misused-promises": "off",
"@typescript-eslint/consistent-type-assertions": "off",
"import/no-absolute-path": "off",
"@typescript-eslint/no-base-to-string": "off",
"@typescript-eslint/no-unused-vars": "warn"
}
}

View file

@ -61,7 +61,7 @@
"peerjs": "^1.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-markdown": "^9.0.0",
"react-markdown": "^9.0.1",
"react-nice-avatar": "^1.4.1",
"react-use": "^17.4.0",
"remark-breaks": "^4.0.0",
@ -74,7 +74,7 @@
"type-fest": "^4.7.1"
},
"devDependencies": {
"@commitlint/cli": "^18.4.0",
"@commitlint/cli": "^18.4.1",
"@commitlint/config-conventional": "^18.4.0",
"@types/node": "^20.9.0",
"@types/react": "^18.2.37",
@ -96,13 +96,13 @@
"lint-staged": "^15.1.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.31",
"prettier": "^3.0.3",
"prettier": "^3.1.0",
"rimraf": "^5.0.5",
"tailwindcss": "^3.3.5",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.2.2",
"webext-bridge": "^6.0.1",
"wxt": "^0.9.0"
"wxt": "^0.10.0"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": "eslint --fix"

File diff suppressed because it is too large Load diff

View file

@ -12,8 +12,8 @@ export default defineContentScript({
matches: ['*://*.example.com/*', '*://*.google.com/*', '*://*.v2ex.com/*'],
async main(ctx) {
const store = Remesh.store({
externs: [StorageImpl],
inspectors: [RemeshLogger()]
externs: [StorageImpl]
// inspectors: [RemeshLogger()]
})
const ui = await createContentScriptUi(ctx, {

View file

@ -7,7 +7,7 @@ export interface AppContainerProps {
const AppContainer: FC<AppContainerProps> = ({ children }) => {
const { size, ref } = useResizable({
initSize: 375,
maxSize: 1000,
maxSize: 750,
minSize: 375,
direction: 'left'
})

View file

@ -1,4 +1,5 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import { useCallback, useRef, useState } from 'react'
import { isInRange } from '@/utils'
export interface ResizableOptions {
minSize: number
@ -12,73 +13,79 @@ const useResizable = (options: ResizableOptions) => {
const [size, setSize] = useState(initSize)
const [position, setPosition] = useState(0)
const position = useRef(0)
const [isMove, setIsMove] = useState(false)
const isMove = useRef(false)
const directionXY = direction === 'left' || direction === 'right' ? 'X' : 'Y'
const isHorizontal = direction === 'left' || direction === 'right'
const handleStart = (e: MouseEvent) => {
const { screenY, screenX } = e
setIsMove(true)
setPosition(directionXY === 'Y' ? screenY : screenX)
document.documentElement.style.userSelect = 'none'
document.documentElement.style.cursor = directionXY === 'Y' ? 'ns-resize' : 'ew-resize'
}
const handleEnd = () => {
setIsMove(false)
document.documentElement.style.cursor = ''
document.documentElement.style.userSelect = ''
}
useEffect(() => {
const handleMove = (e: MouseEvent) => {
if (isMove) {
console.log('move')
const handleMove = useCallback(
(e: MouseEvent) => {
if (isMove.current) {
const { screenY, screenX } = e
let delta = 0
switch (direction) {
case 'left':
delta = position - screenX
delta = position.current - screenX
break
case 'right':
delta = screenX - position
delta = screenX - position.current
break
case 'top':
delta = position - screenY
delta = position.current - screenY
break
case 'bottom':
delta = screenY - position
delta = screenY - position.current
break
}
const newSize = size + delta
if (size !== newSize && newSize >= minSize && newSize <= maxSize) {
setSize(newSize)
if (isInRange(newSize, minSize, maxSize)) {
position.current = isHorizontal ? screenX : screenY
}
if (newSize !== size) {
setSize(clamp(newSize, minSize, maxSize))
}
} else {
document.removeEventListener('mousemove', handleMove)
}
}
},
[direction, isHorizontal, maxSize, minSize, size]
)
document.addEventListener('mousemove', handleMove)
return () => {
document.removeEventListener('mousemove', handleMove)
}
}, [isMove])
const handleEnd = useCallback(() => {
isMove.current = false
document.documentElement.style.cursor = ''
document.documentElement.style.userSelect = ''
}, [])
const handleStart = useCallback(
(e: MouseEvent) => {
const { screenY, screenX } = e
isMove.current = true
position.current = isHorizontal ? screenX : screenY
document.documentElement.style.userSelect = 'none'
document.documentElement.style.cursor = isHorizontal ? 'ew-resize' : 'ns-resize'
},
[isHorizontal]
)
const ref = useRef<HTMLElement | null>(null)
const setRef = useCallback((node: HTMLElement | null) => {
if (ref.current) {
ref.current.removeEventListener('mousedown', handleStart)
document.removeEventListener('mouseup', handleEnd)
}
if (node) {
node.addEventListener('mousedown', handleStart)
document.addEventListener('mouseup', handleEnd)
}
ref.current = node
}, [])
// Watch ref: https://medium.com/@teh_builder/ref-objects-inside-useeffect-hooks-eb7c15198780
const setRef = useCallback(
(node: HTMLElement | null) => {
if (ref.current) {
ref.current.removeEventListener('mousedown', handleStart)
document.removeEventListener('mouseup', handleEnd)
document.removeEventListener('mousemove', handleMove)
}
if (node) {
node.addEventListener('mousedown', handleStart)
document.addEventListener('mouseup', handleEnd)
document.addEventListener('mousemove', handleMove)
}
ref.current = node
},
[handleEnd, handleMove, handleStart]
)
return { size, ref: setRef }
}

View file

@ -22,6 +22,9 @@ export const createElement = <T extends Element>(template: string) => {
export const chunk = <T = any>(array: T[], size: number) =>
Array.from({ length: Math.ceil(array.length / size) }, (_v, i) => array.slice(i * size, i * size + size))
export const clamp = (number: number, min: number, max: number) => Math.min(Math.max(number, min), max)
export const isInRange = (number: number, min: number, max: number) => number >= min && number <= max
export const getWebSiteInfo = (): WebSiteInfo => {
return {
host: document.location.host,