Skip to content

Commit 28ae1ae

Browse files
RocketGod-gitjLynx
andauthored
Dynamic console screen for PortaRF (#97)
* Enhance IScreen interface with screenDimensions Added screenDimensions property to IScreen interface and updated canvas dimensions accordingly. * Implement upload progress for file manager Added upload progress handling for file manager and improved user feedback during uploads. * Enhance IScreen interface with screenDimensions Added screenDimensions property to IScreen interface and updated canvas dimensions accordingly. * Update useScreenFrame.ts --------- Co-authored-by: jLynx <admin@jlynx.net>
1 parent 6ec5984 commit 28ae1ae

File tree

3 files changed

+64
-10
lines changed

3 files changed

+64
-10
lines changed

src/components/Controller/Controller.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const Controller = () => {
7070
setDirStructure,
7171
setLatestVersion,
7272
});
73-
const { canvasRef, renderFrame } = useScreenFrame();
73+
const { canvasRef, renderFrame, screenDimensions, needsRefresh, setNeedsRefresh } = useScreenFrame();
7474
const { UIConfig, setUiConfig, handleUpdateUiHide } = useUIConfig();
7575

7676
const sendCommand = async () => {
@@ -287,6 +287,14 @@ const Controller = () => {
287287
setAutoUpdateFrame(!shouldUpdate);
288288
};
289289

290+
useEffect(() => {
291+
if (needsRefresh && !disableTransmitAction) {
292+
console.log("Executing refresh");
293+
write("screenframeshort", false);
294+
setNeedsRefresh(false);
295+
}
296+
}, [needsRefresh]);
297+
290298
useEffect(() => {
291299
// We dont add this to the console as its not needed. This may change in the future
292300
if (consoleMessage.startsWith("screenframe")) {
@@ -343,6 +351,7 @@ const Controller = () => {
343351
disableTransmitAction={disableTransmitAction}
344352
autoUpdateFrame={autoUpdateFrame}
345353
write={write}
354+
screenDimensions={screenDimensions}
346355
/>
347356

348357
<div className="flex flex-col items-center justify-center rounded-md bg-opacity-20 bg-slate-600 p-3 backdrop-blur-sm">

src/components/Screen/Screen.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ interface IScreen {
33
disableTransmitAction: boolean;
44
autoUpdateFrame: boolean;
55
write: any;
6+
screenDimensions: { width: number; height: number };
67
}
78

89
export const Screen: React.FC<IScreen> = ({
910
canvasRef,
1011
disableTransmitAction,
1112
autoUpdateFrame,
1213
write,
14+
screenDimensions,
1315
}) => {
1416
return (
1517
<canvas
1618
ref={canvasRef}
17-
width={241}
18-
height={321}
19+
width={screenDimensions.width}
20+
height={screenDimensions.height}
1921
className={`${
2022
!disableTransmitAction && "cursor-pointer"
2123
} shadow-glow shadow-neutral-500 outline-none focus:ring-0`}

src/hooks/useScreenFrame.ts

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { useRef } from "react";
1+
import { useRef, useState } from "react";
22

33
export const useScreenFrame = () => {
44
const canvasRef = useRef<HTMLCanvasElement>(null);
5+
const [screenDimensions, setScreenDimensions] = useState({ width: 240, height: 320 });
6+
const [needsRefresh, setNeedsRefresh] = useState(false);
7+
const lastWidth = useRef(240);
58

69
const renderFrame = (consoleMessage: string) => {
710
if (!consoleMessage.includes("screenframe")) return;
@@ -11,24 +14,64 @@ export const useScreenFrame = () => {
1114

1215
if (!ctx) return false;
1316

14-
for (let y = 0; y < lines.length; y++) {
15-
let line = lines[y];
17+
// Find first data line
18+
let dataLineIndex = 0;
19+
for (let i = 0; i < lines.length; i++) {
20+
if (!lines[i].startsWith("screenframe") && lines[i].length > 0) {
21+
dataLineIndex = i;
22+
break;
23+
}
24+
}
25+
26+
const firstDataLine = lines[dataLineIndex];
27+
if (!firstDataLine) return;
28+
29+
// Determine required dimensions based on line length
30+
const requiredWidth = firstDataLine.length >= 320 ? 320 : 240;
31+
const requiredHeight = firstDataLine.length >= 320 ? 480 : 320;
32+
33+
// Check if dimensions need to change
34+
if (lastWidth.current !== requiredWidth) {
35+
console.log(`Dimension change: ${lastWidth.current} -> ${requiredWidth}`);
36+
lastWidth.current = requiredWidth;
37+
setScreenDimensions({ width: requiredWidth, height: requiredHeight });
38+
39+
if (canvasRef.current) {
40+
canvasRef.current.width = requiredWidth;
41+
canvasRef.current.height = requiredHeight;
42+
}
43+
44+
// Set flag for refresh with a delay
45+
setTimeout(() => {
46+
setNeedsRefresh(true);
47+
}, 500); // Give time for current operations to complete
48+
49+
return; // Don't render this frame
50+
}
51+
52+
// Render the frame
53+
let y = 0;
54+
for (let lineIndex = dataLineIndex; lineIndex < lines.length; lineIndex++) {
55+
let line = lines[lineIndex];
1656
if (line.startsWith("screenframe")) continue;
17-
for (let o = 0, x = 0; o < line.length && x < 240; o++, x++) {
57+
58+
for (let x = 0; x < line.length; x++) {
1859
try {
19-
let by = line.charCodeAt(o) - 32;
60+
let by = line.charCodeAt(x) - 32;
61+
2062
let r = ((by >> 4) & 3) << 6;
2163
let g = ((by >> 2) & 3) << 6;
2264
let b = (by & 3) << 6;
2365

2466
ctx.fillStyle = `rgb(${r},${g},${b})`;
25-
ctx?.fillRect(x, y, 1, 1);
67+
ctx.fillRect(x, y, 1, 1);
2668
} catch (err) {
2769
console.error(err);
2870
}
2971
}
72+
y++;
3073
}
3174
};
3275

33-
return { canvasRef, renderFrame };
76+
return { canvasRef, renderFrame, screenDimensions, needsRefresh, setNeedsRefresh };
3477
};

0 commit comments

Comments
 (0)