mirror of https://github.com/coder/coder.git
refactor(site): Add press any key option to reconnect on terminal screen (#5969)
This commit is contained in:
parent
7b49517c18
commit
4df1031f8b
|
@ -1,5 +1,6 @@
|
||||||
import { makeStyles } from "@material-ui/core/styles"
|
import { makeStyles } from "@material-ui/core/styles"
|
||||||
import { useMachine } from "@xstate/react"
|
import { useMachine } from "@xstate/react"
|
||||||
|
import { Stack } from "components/Stack/Stack"
|
||||||
import { FC, useEffect, useRef, useState } from "react"
|
import { FC, useEffect, useRef, useState } from "react"
|
||||||
import { Helmet } from "react-helmet-async"
|
import { Helmet } from "react-helmet-async"
|
||||||
import { useNavigate, useParams, useSearchParams } from "react-router-dom"
|
import { useNavigate, useParams, useSearchParams } from "react-router-dom"
|
||||||
|
@ -19,6 +20,34 @@ export const Language = {
|
||||||
websocketErrorMessagePrefix: "WebSocket failed: ",
|
websocketErrorMessagePrefix: "WebSocket failed: ",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useReloading = (isDisconnected: boolean) => {
|
||||||
|
const [status, setStatus] = useState<"reloading" | "notReloading">(
|
||||||
|
"notReloading",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Retry connection on key press when it is disconnected
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isDisconnected) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyDownHandler = () => {
|
||||||
|
setStatus("reloading")
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("keydown", keyDownHandler)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("keydown", keyDownHandler)
|
||||||
|
}
|
||||||
|
}, [isDisconnected])
|
||||||
|
|
||||||
|
return {
|
||||||
|
status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const TerminalPage: FC<
|
const TerminalPage: FC<
|
||||||
React.PropsWithChildren<{
|
React.PropsWithChildren<{
|
||||||
readonly renderer?: XTerm.RendererType
|
readonly renderer?: XTerm.RendererType
|
||||||
|
@ -67,6 +96,7 @@ const TerminalPage: FC<
|
||||||
workspaceAgent,
|
workspaceAgent,
|
||||||
websocketError,
|
websocketError,
|
||||||
} = terminalState.context
|
} = terminalState.context
|
||||||
|
const reloading = useReloading(isDisconnected)
|
||||||
|
|
||||||
// Create the terminal!
|
// Create the terminal!
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -216,7 +246,16 @@ const TerminalPage: FC<
|
||||||
{/* This overlay makes it more obvious that the terminal is disconnected. */}
|
{/* This overlay makes it more obvious that the terminal is disconnected. */}
|
||||||
{/* It's nice for situations where Coder restarts, and they are temporarily disconnected. */}
|
{/* It's nice for situations where Coder restarts, and they are temporarily disconnected. */}
|
||||||
<div className={`${styles.overlay} ${isDisconnected ? "" : "connected"}`}>
|
<div className={`${styles.overlay} ${isDisconnected ? "" : "connected"}`}>
|
||||||
<span className={styles.overlayText}>Disconnected</span>
|
{reloading.status === "reloading" ? (
|
||||||
|
<span className={styles.overlayText}>Reloading...</span>
|
||||||
|
) : (
|
||||||
|
<Stack spacing={0.5} alignItems="center">
|
||||||
|
<span className={styles.overlayText}>Disconnected</span>
|
||||||
|
<span className={styles.overlaySubtext}>
|
||||||
|
Press any key to retry
|
||||||
|
</span>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.terminal} ref={xtermRef} data-testid="terminal" />
|
<div className={styles.terminal} ref={xtermRef} data-testid="terminal" />
|
||||||
</>
|
</>
|
||||||
|
@ -225,7 +264,7 @@ const TerminalPage: FC<
|
||||||
|
|
||||||
export default TerminalPage
|
export default TerminalPage
|
||||||
|
|
||||||
const useStyles = makeStyles(() => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
overlay: {
|
overlay: {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
pointerEvents: "none",
|
pointerEvents: "none",
|
||||||
|
@ -238,17 +277,20 @@ const useStyles = makeStyles(() => ({
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
color: "white",
|
color: "white",
|
||||||
fontFamily: MONOSPACE_FONT_FAMILY,
|
fontSize: 16,
|
||||||
fontSize: 18,
|
|
||||||
backgroundColor: "rgba(0, 0, 0, 0.6)",
|
backgroundColor: "rgba(0, 0, 0, 0.6)",
|
||||||
|
backdropFilter: "blur(4px)",
|
||||||
"&.connected": {
|
"&.connected": {
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
overlayText: {
|
overlayText: {
|
||||||
padding: 32,
|
fontSize: 16,
|
||||||
fontSize: 24,
|
fontWeight: 600,
|
||||||
backgroundColor: "#000",
|
},
|
||||||
|
overlaySubtext: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: theme.palette.text.secondary,
|
||||||
},
|
},
|
||||||
terminal: {
|
terminal: {
|
||||||
width: "100vw",
|
width: "100vw",
|
||||||
|
|
Loading…
Reference in New Issue