fix: resize handle text selection + add homelab-frontend CI badge
Build & Push Portfolio Image / build-push (push) Successful in 3m24s
Build & Push Portfolio Image / build-push (push) Successful in 3m24s
This commit is contained in:
@@ -31,6 +31,7 @@ export default function Home() {
|
|||||||
articleUrl: index === 4 ? 'https://lnkd.in/p/gm2PZkWw' : '#',
|
articleUrl: index === 4 ? 'https://lnkd.in/p/gm2PZkWw' : '#',
|
||||||
ciRepos: index === 0 ? [
|
ciRepos: index === 0 ? [
|
||||||
{ label: 'portfolio', repo: 'rock/riotpiao.com', forgejoBase: 'https://forgejo.riotpiao.com/rock/riotpiao.com' },
|
{ label: 'portfolio', repo: 'rock/riotpiao.com', forgejoBase: 'https://forgejo.riotpiao.com/rock/riotpiao.com' },
|
||||||
|
{ label: 'homelab-frontend', repo: 'rock/homelab-frontend', forgejoBase: 'https://forgejo.riotpiao.com/rock/homelab-frontend' },
|
||||||
{ label: 'kmsvc', repo: 'rock/kmsvc-manage', forgejoBase: 'https://forgejo.riotpiao.com/rock/kmsvc-manage' },
|
{ label: 'kmsvc', repo: 'rock/kmsvc-manage', forgejoBase: 'https://forgejo.riotpiao.com/rock/kmsvc-manage' },
|
||||||
] : index === 1 ? [
|
] : index === 1 ? [
|
||||||
{ label: 'poimen-mem', repo: 'rock/poimen-memory', forgejoBase: 'https://forgejo.riotpiao.com/rock/poimen-memory' },
|
{ label: 'poimen-mem', repo: 'rock/poimen-memory', forgejoBase: 'https://forgejo.riotpiao.com/rock/poimen-memory' },
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ export function InteractiveTerminal() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleMouseMove = (e: MouseEvent) => {
|
const handleMouseMove = (e: MouseEvent) => {
|
||||||
if (!isResizing) return
|
if (!isResizing) return
|
||||||
|
e.preventDefault()
|
||||||
const container = containerRef.current
|
const container = containerRef.current
|
||||||
if (!container) return
|
if (!container) return
|
||||||
|
|
||||||
@@ -129,10 +130,14 @@ export function InteractiveTerminal() {
|
|||||||
|
|
||||||
const handleMouseUp = () => {
|
const handleMouseUp = () => {
|
||||||
setIsResizing(false)
|
setIsResizing(false)
|
||||||
|
document.body.style.cursor = 'auto'
|
||||||
|
document.body.style.userSelect = 'auto'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isResizing) {
|
if (isResizing) {
|
||||||
document.addEventListener('mousemove', handleMouseMove)
|
document.body.style.userSelect = 'none'
|
||||||
|
document.body.style.cursor = 'nw-resize'
|
||||||
|
document.addEventListener('mousemove', handleMouseMove, { passive: false })
|
||||||
document.addEventListener('mouseup', handleMouseUp)
|
document.addEventListener('mouseup', handleMouseUp)
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener('mousemove', handleMouseMove)
|
document.removeEventListener('mousemove', handleMouseMove)
|
||||||
@@ -255,11 +260,18 @@ export function InteractiveTerminal() {
|
|||||||
exit={{ opacity: 0, y: 20, scale: 0.95 }}
|
exit={{ opacity: 0, y: 20, scale: 0.95 }}
|
||||||
transition={{ duration: 0.25, ease: 'easeInOut' }}
|
transition={{ duration: 0.25, ease: 'easeInOut' }}
|
||||||
style={{ width: `${width}px`, height: `${height}px` }}
|
style={{ width: `${width}px`, height: `${height}px` }}
|
||||||
className={`rounded-lg shadow-2xl flex flex-col border relative ${
|
className={`rounded-lg shadow-2xl flex flex-col border relative user-select-none ${
|
||||||
isDark
|
isDark
|
||||||
? 'bg-gray-950 border-gray-700'
|
? 'bg-gray-950 border-gray-700'
|
||||||
: 'bg-white border-gray-300'
|
: 'bg-white border-gray-300'
|
||||||
}`}
|
}`}
|
||||||
|
tabIndex={-1}
|
||||||
|
onMouseDown={(e) => {
|
||||||
|
// Ensure terminal stays focused during interaction
|
||||||
|
if (e.target === containerRef.current) {
|
||||||
|
inputRef.current?.focus()
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className={`border-b px-4 py-3 flex justify-between items-center ${
|
<div className={`border-b px-4 py-3 flex justify-between items-center ${
|
||||||
isDark
|
isDark
|
||||||
@@ -346,16 +358,20 @@ export function InteractiveTerminal() {
|
|||||||
{/* Resize handle — top-left corner */}
|
{/* Resize handle — top-left corner */}
|
||||||
<div
|
<div
|
||||||
ref={resizeHandleRef}
|
ref={resizeHandleRef}
|
||||||
onMouseDown={() => setIsResizing(true)}
|
onMouseDown={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
setIsResizing(true)
|
||||||
|
}}
|
||||||
className={`absolute top-0 left-0 w-4 h-4 cursor-nw-resize ${
|
className={`absolute top-0 left-0 w-4 h-4 cursor-nw-resize ${
|
||||||
isDark ? 'hover:bg-gray-600' : 'hover:bg-gray-400'
|
isDark ? 'hover:bg-gray-600' : 'hover:bg-gray-400'
|
||||||
} transition-colors z-10`}
|
} transition-colors z-10 select-none`}
|
||||||
style={{
|
style={{
|
||||||
borderTopLeftRadius: 'inherit',
|
borderTopLeftRadius: 'inherit',
|
||||||
opacity: isResizing ? 1 : 0.5,
|
opacity: isResizing ? 1 : 0.5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg width="10" height="10" viewBox="0 0 10 10" className="m-0.5 opacity-40">
|
<svg width="10" height="10" viewBox="0 0 10 10" className="m-0.5 opacity-40 pointer-events-none">
|
||||||
<line x1="0" y1="10" x2="10" y2="0" stroke="currentColor" strokeWidth="1.5" />
|
<line x1="0" y1="10" x2="10" y2="0" stroke="currentColor" strokeWidth="1.5" />
|
||||||
<line x1="0" y1="6" x2="6" y2="0" stroke="currentColor" strokeWidth="1.5" />
|
<line x1="0" y1="6" x2="6" y2="0" stroke="currentColor" strokeWidth="1.5" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user