Taobin-Recipe-Manager/client-electron/src/pages/android/components/shell-tab.tsx

82 lines
2.4 KiB
TypeScript

import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import useShellAndroid from '@/hooks/shell-android'
import { type Adb } from '@yume-chan/adb'
import { memo, useEffect, useRef } from 'react'
import { type Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import 'xterm/css/xterm.css'
import { useShallow } from 'zustand/react/shallow'
interface ShellTabProps {
adb: Adb | undefined
}
export const ShellTab: React.FC<ShellTabProps> = memo(({ adb }) => {
const { terminal, startTerminal, killTerminal } = useShellAndroid(
useShallow(state => ({
terminal: state.terminal,
startTerminal: state.startTerminal,
killTerminal: state.killTerminal
}))
)
return (
<Card>
<CardHeader>
<CardTitle>Shell</CardTitle>
<CardDescription>Access your device's shell using a terminal emulator</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center justify-end py-3 w-full">
<div className="space-x-5">
{terminal ? (
<Button variant={'destructive'} onClick={killTerminal}>
Terminate
</Button>
) : (
<Button variant={'default'} onClick={() => startTerminal(adb)}>
Start
</Button>
)}
</div>
</div>
{terminal ? (
<ShellTerminal terminal={terminal} />
) : (
<div className="w-full h-[800px] bg-slate-700 flex justify-center items-center">
<h1>No Connection ADB</h1>
</div>
)}
</CardContent>
</Card>
)
})
interface ShellTerminalProps {
terminal: Terminal
}
const ShellTerminal: React.FC<ShellTerminalProps> = ({ terminal }) => {
const shellRef = useRef<HTMLDivElement>(null)
useEffect(() => {
// check if shellRef is have child remove all
if (shellRef.current && shellRef.current.children.length > 0) {
for (const child of shellRef.current.children) {
shellRef.current.removeChild(child)
}
}
if (terminal && shellRef.current) {
const addon = new FitAddon()
terminal.loadAddon(addon)
terminal.open(shellRef.current)
addon.fit()
}
}, [terminal])
return <div className="w-full h-[800px] bg-slate-700" ref={shellRef}></div>
}