diff --git a/libs/remix-ui/terminal/src/lib/custom-hooks/useDragTerminal.tsx b/libs/remix-ui/terminal/src/lib/custom-hooks/useDragTerminal.tsx new file mode 100644 index 0000000000..cdd4f6dc6a --- /dev/null +++ b/libs/remix-ui/terminal/src/lib/custom-hooks/useDragTerminal.tsx @@ -0,0 +1,77 @@ +import { useEffect, useState } from 'react' + +export const useDragTerminal = (minHeight: number, defaultPosition: number) => { + const [isOpen, setIsOpen] = useState(defaultPosition > minHeight) + const [lastYPosition, setLastYPosition] = useState(0) + const [terminalPosition, setTerminalPosition] = useState(defaultPosition) + // Used to save position of the terminal when it is closed + const [lastTerminalPosition, setLastTerminalPosition] = useState(defaultPosition) + const [isDragging, setIsDragging] = useState(false) + + const handleDraggingStart = (event: React.MouseEvent) => { + setLastYPosition(event.clientY) + setIsDragging(true) + } + + const handleDragging = (event: MouseEvent) => { + event.preventDefault() + + if (isDragging) { + const mouseYPosition = event.clientY + const difference = lastYPosition - mouseYPosition + const newTerminalPosition = terminalPosition + difference + setTerminalPosition(newTerminalPosition) + setLastYPosition(mouseYPosition) + } + } + + const handleDraggingEnd = () => { + if(!isDragging) return + + setIsDragging(false) + + // Check terminal position to determine if it should be open or closed + setIsOpen(terminalPosition > minHeight) + } + + const handleToggleTerminal = (event: React.MouseEvent) => { + event.preventDefault() + event.stopPropagation() + + if(isOpen) { + setLastTerminalPosition(terminalPosition) + setLastYPosition(0) + setTerminalPosition(minHeight) + } else { + setTerminalPosition(lastTerminalPosition <= minHeight ? 323 : lastTerminalPosition) + } + + setIsOpen(!isOpen) + } + + // Add event listeners for dragging + useEffect(() => { + document.addEventListener('mousemove', handleDragging) + document.addEventListener('mouseup', handleDraggingEnd) + + return () => { + document.removeEventListener('mousemove', handleDragging) + document.removeEventListener('mouseup', handleDraggingEnd) + } + }, [handleDragging, handleDraggingEnd]) + + // Reset terminal position + useEffect(() => { + if(!terminalPosition){ + setTerminalPosition(defaultPosition) + } + }, [terminalPosition, setTerminalPosition]) + + return { + isOpen, + terminalPosition, + isDragging, + handleDraggingStart, + handleToggleTerminal, + } +} \ No newline at end of file diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css index ca50eee4dc..74b88d8b76 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.css @@ -151,6 +151,11 @@ element.style { cursor : row-resize; z-index : 999; } + + .dragbarDragging { + background-color: var(--primary); + border: 2px solid var(--primary); + } .console { cursor : pointer; diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx index 270f4a6593..de6de4eb23 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -17,6 +17,7 @@ import RenderKnownTransactions from './components/RenderKnownTransactions' // es import parse from 'html-react-parser' import { EMPTY_BLOCK, KNOWN_TRANSACTION, RemixUiTerminalProps, UNKNOWN_TRANSACTION } from './types/terminalTypes' import { wrapScript } from './utils/wrapScript' +import { useDragTerminal } from './custom-hooks/useDragTerminal' /* eslint-disable-next-line */ export interface ClipboardEvent extends SyntheticEvent { @@ -25,13 +26,8 @@ export interface ClipboardEvent extends SyntheticEvent { export const RemixUiTerminal = (props: RemixUiTerminalProps) => { const { call, _deps, on, config, event, gistHandler, version } = props.plugin - const [toggleDownUp, setToggleDownUp] = useState('fa-angle-double-down') const [_cmdIndex, setCmdIndex] = useState(-1) const [_cmdTemp, setCmdTemp] = useState('') - // dragable state - const [leftHeight, setLeftHeight] = useState(undefined) - const [separatorYPosition, setSeparatorYPosition] = useState(undefined) - const [dragging, setDragging] = useState(false) const [newstate, dispatch] = useReducer(registerCommandReducer, initialState) const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) @@ -78,6 +74,28 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { // terminal dragable const leftRef = useRef(null) const panelRef = useRef(null) + const terminalMenu = useRef(null) + + const terminalMenuOffsetHeight = (terminalMenu.current && terminalMenu.current.offsetHeight) || 35 + const terminalDefaultPosition = config.get('terminal-top-offset') + + const { + isOpen, + isDragging, + terminalPosition, + handleDraggingStart, + handleToggleTerminal + } = useDragTerminal(terminalMenuOffsetHeight, terminalDefaultPosition) + + // Check open state + useEffect(() => { + const resizeValue = isOpen ? [config.get('terminal-top-offset')] : [] + event.trigger('resize', resizeValue) + }, [isOpen]) + + useEffect(() => { + event.trigger('resize', [terminalPosition]) + } , [terminalPosition]) const scrollToBottom = () => { messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }) @@ -193,18 +211,8 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - const handleMinimizeTerminal = (e) => { - e.preventDefault() - e.stopPropagation() - if (toggleDownUp === 'fa-angle-double-down') { - setToggleDownUp('fa-angle-double-up') - event.trigger('resize', []) - } else { - const terminalTopOffset = config.get('terminal-top-offset') - event.trigger('resize', [terminalTopOffset]) - setToggleDownUp('fa-angle-double-down') - } - } + + const focusinput = () => { inputEl.current.focus() @@ -277,51 +285,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { } } - /* start of mouse events */ - - const mousedown = (event: MouseEvent) => { - setSeparatorYPosition(event.clientY) - setDragging(true) - } - - const onMouseMove: any = (e: MouseEvent) => { - e.preventDefault() - if (dragging && leftHeight && separatorYPosition) { - const newLeftHeight = leftHeight + separatorYPosition - e.clientY - setSeparatorYPosition(e.clientY) - setLeftHeight(newLeftHeight) - event.trigger('resize', [newLeftHeight + 32]) - } - } - - const onMouseUp = () => { - leftRef.current.style.backgroundColor = '' - leftRef.current.style.border = '' - setDragging(false) - } - - /* end of mouse event */ - - useEffect(() => { - document.addEventListener('mousemove', onMouseMove) - document.addEventListener('mouseup', onMouseUp) - - return () => { - document.removeEventListener('mousemove', onMouseMove) - document.removeEventListener('mouseup', onMouseUp) - } - }, [onMouseMove, onMouseUp]) - - React.useEffect(() => { - if (panelRef) { - if (!leftHeight) { - setLeftHeight(panelRef.current.offsetHeight) - return - } - panelRef.current.style.height = `${leftHeight}px` - } - }, [leftHeight, setLeftHeight, panelRef]) - /* block contents that gets rendered from scriptRunner */ const _blocksRenderer = (mode) => { @@ -463,9 +426,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { return (
-
-
- +
+
+