File size: 1,924 Bytes
e7b07b3 999003d e7b07b3 8b35d5c e7b07b3 999003d e7b07b3 999003d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #!/usr/bin/env bun
/**
* Standalone visual test: display a local image or URL using ink-picture + Ink.
*
* Usage:
* bun run src/tools/ImageShowTool/standalone.tsx [path|url]
*
* Examples:
* bun run src/tools/ImageShowTool/standalone.tsx ~/Pictures/image.png
* bun run src/tools/ImageShowTool/standalone.tsx https://example.com/image.jpg
*/
import { useEffect, useState } from "react";
import { render, Box, Text, useApp } from "ink";
import {
getImagePath,
isUrl,
loadImage,
calculateDimensions,
type ImageDimensions,
} from "./ImageShowTool.ts";
import { ImageDisplay } from "./UI.js";
const args = process.argv.slice(2);
const IMAGE_PATH = getImagePath(args);
function App() {
const { exit } = useApp();
const [dimensions, setDimensions] = useState<ImageDimensions | null>(null);
const [err, setErr] = useState(false);
useEffect(() => {
(async () => {
try {
const image = await loadImage(IMAGE_PATH);
const dims = calculateDimensions(
image.bitmap.width,
image.bitmap.height,
process.stdout.rows ?? 24,
);
setDimensions(dims);
} catch (e) {
console.error(e);
setErr(true);
exit();
}
})();
}, [exit]);
useEffect(() => {
const handleSigint = () => exit();
process.on("SIGINT", handleSigint);
return () => {
process.off("SIGINT", handleSigint);
};
}, [exit]);
if (err) {
return <Text color="red">Failed to fetch: {IMAGE_PATH}</Text>;
}
if (!dimensions) {
return <Text>Loading...</Text>;
}
return (
<Box flexDirection="column">
<ImageDisplay
src={IMAGE_PATH}
width={dimensions.width}
height={dimensions.height}
pixelWidth={dimensions.pixelWidth}
pixelHeight={dimensions.pixelHeight}
/>
</Box>
);
}
const { waitUntilExit } = render(<App />);
await waitUntilExit();
|