Skip to content

Commit d835ef9

Browse files
committed
feat: enhance Terminal component with loading state and styles
- Updated Terminal component to include a loading state while the iframe is being rendered. - Added new styles for loading animation and logo in Terminal.scss. - Implemented a delay for iframe rendering to improve user experience during loading.
1 parent ce3c3b8 commit d835ef9

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

src/frontend/src/pad/containers/Terminal.scss

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,46 @@
88

99
.terminal-iframe {
1010
flex: 1;
11-
background-color: #1e1e1e;
11+
background-color: #000000;
1212
height: 100%;
1313
width: 100%;
1414
border: 0px !important;
1515
overflow: hidden;
1616
border-bottom-left-radius: var(--embeddable-radius);
1717
border-bottom-right-radius: var(--embeddable-radius);
18+
19+
&--loading {
20+
display: flex;
21+
align-items: center;
22+
justify-content: center;
23+
position: relative;
24+
}
25+
}
26+
27+
.terminal-loading-animation {
28+
position: absolute;
29+
width: 100%;
30+
height: 100%;
31+
display: flex;
32+
align-items: center;
33+
justify-content: center;
34+
}
35+
36+
.terminal-loading-logo {
37+
width: 60px;
38+
height: 60px;
39+
object-fit: contain;
40+
animation: terminal-logo-slide 300ms cubic-bezier(0.00, 1.26, 0.64, 0.95) forwards;
41+
position: relative;
42+
}
43+
44+
@keyframes terminal-logo-slide {
45+
from {
46+
transform: translateX(-100px);
47+
opacity: 0;
48+
}
49+
to {
50+
transform: translateX(0);
51+
opacity: 1;
52+
}
1853
}

src/frontend/src/pad/containers/Terminal.tsx

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export const Terminal: React.FC<TerminalProps> = ({
2626
}) => {
2727
const { data: workspaceState } = useWorkspaceState();
2828
const [terminalId, setTerminalId] = useState<string | null>(null);
29+
const [iframeLoaded, setIframeLoaded] = useState(false);
30+
const [shouldRenderIframe, setShouldRenderIframe] = useState(false);
2931
const elementIdRef = useRef(element?.id);
3032
const isInitializedRef = useRef(false);
3133

@@ -172,13 +174,42 @@ export const Terminal: React.FC<TerminalProps> = ({
172174

173175
const terminalUrl = getTerminalUrl();
174176

177+
// Effect to delay loading the iframe
178+
useEffect(() => {
179+
// Set a small timeout to allow the scrolling to complete first
180+
const timer = setTimeout(() => {
181+
setShouldRenderIframe(true);
182+
}, 500); // 300ms delay should be enough for the scroll animation to start
183+
184+
return () => clearTimeout(timer);
185+
}, []);
186+
187+
// Handle iframe load event
188+
const handleIframeLoad = () => {
189+
setIframeLoaded(true);
190+
console.debug('[pad.ws] Terminal iframe loaded');
191+
};
192+
175193
return (
176194
<div className="terminal-container">
177-
<iframe
178-
className="terminal-iframe"
179-
src={terminalUrl}
180-
title="Terminal"
181-
/>
195+
{shouldRenderIframe ? (
196+
<iframe
197+
className="terminal-iframe"
198+
src={terminalUrl}
199+
title="Terminal"
200+
onLoad={handleIframeLoad}
201+
/>
202+
) : (
203+
<div className="terminal-iframe terminal-iframe--loading">
204+
<div className="terminal-loading-animation">
205+
<img
206+
src="/assets/images/favicon.png"
207+
alt="pad.ws logo"
208+
className="terminal-loading-logo"
209+
/>
210+
</div>
211+
</div>
212+
)}
182213
</div>
183214
);
184215
};

0 commit comments

Comments
 (0)