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();