File size: 4,864 Bytes
4af6326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae074fc
4af6326
 
 
 
 
 
ae074fc
 
 
 
 
4af6326
 
 
 
 
 
 
 
 
 
 
 
 
 
ae074fc
4af6326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae074fc
4af6326
 
ae074fc
 
 
 
 
 
 
 
4af6326
ae074fc
4af6326
 
ae074fc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4af6326
 
 
 
 
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import React from 'react';

import { ChunkBody, CodeResult, formatStreamLogs } from '@/lib/utils/content';
import { CodeBlock } from './ui/CodeBlock';
import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from './ui/Dialog';
import { Button } from './ui/Button';
import { IconLog, IconTerminalWindow } from './ui/Icons';
import { Separator } from './ui/Separator';
import { ResultPayload } from '@/lib/types';
import Img from './ui/Img';

export interface CodeResultDisplayProps {}

const CodeResultDisplay: React.FC<{
  codeResult: CodeResult;
}> = ({ codeResult }) => {
  const { code, test, result } = codeResult;
  const getDetail = () => {
    if (!result) return {};
    try {
      const detail = JSON.parse(result) as ResultPayload;
      return {
        results: detail.results,
        stderr: detail.logs.stderr,
        stdout: detail.logs.stdout,
        error: detail.error,
      };
    } catch {
      return {};
    }
  };

  const { results = [], stderr, stdout, error } = getDetail();

  const imageResults = results?.filter(_ => !!_.png).map(_ => _.png);
  const videoResults = results?.filter(_ => !!_.mp4).map(_ => _.mp4);
  const finalResult = results?.find(_ => _.is_main_result)?.text;

  return (
    <div className="rounded-lg overflow-hidden relative max-w-5xl">
      <CodeBlock language="python" value={code} />
      <div className="rounded-lg relative">
        <div className="absolute left-1/2 -translate-x-1/2 -top-4 z-10">
          <Dialog>
            <DialogTrigger asChild>
              <Button variant="ghost" size="icon" className="size-8">
                <IconTerminalWindow className="text-teal-500 size-4" />
              </Button>
            </DialogTrigger>
            <DialogContent className="max-w-5xl">
              <DialogHeader>
                <DialogTitle>Test code</DialogTitle>
              </DialogHeader>
              <CodeBlock language="python" value={test} />
            </DialogContent>
          </Dialog>
          {Array.isArray(stderr) && !!stderr.join('').trim() && (
            <Dialog>
              <DialogTrigger asChild>
                <Button variant="ghost" size="icon" className="size-8">
                  <IconLog className="text-gray-500 size-4" />
                </Button>
              </DialogTrigger>
              <DialogContent className="max-w-5xl">
                <CodeBlock language="vim" value={stderr.join('').trim()} />
              </DialogContent>
            </Dialog>
          )}
        </div>
      </div>
      {Array.isArray(stdout) && !!stdout.join('').trim() && (
        <>
          <Separator />
          <CodeBlock language="print" value={stdout.join('').trim()} />
        </>
      )}
      {!!error && (
        <>
          <Separator />
          <CodeBlock
            language="error"
            value={
              error.name +
              '\n' +
              error.value +
              '\n' +
              error.traceback_raw.join('\n')
            }
          />
        </>
      )}
      {!!imageResults.length && (
        <div className="p-4 text-xs lowercase bg-zinc-900 space-y-4 border-t border-muted">
          <p>image output</p>
          <div className="flex flex-row space-x-4 overflow-auto">
            {imageResults.map((png, index) => (
              <Dialog key={'png' + index}>
                <DialogTrigger asChild>
                  <Img
                    key={'png' + index}
                    src={png!}
                    width={200}
                    alt="result-image"
                    className="cursor-zoom-in"
                  />
                </DialogTrigger>
                <DialogContent className="max-w-5xl">
                  <Img
                    src={png!}
                    width={1200}
                    height={800}
                    alt="result-image"
                    quality={100}
                  />
                </DialogContent>
              </Dialog>
            ))}
          </div>
        </div>
      )}
      {!!videoResults.length && (
        <div className="p-4 text-xs lowercase bg-zinc-900 space-y-4">
          <p>video output</p>
          <div className="flex flex-row space-x-4 overflow-auto">
            {videoResults.map((mp4, index) => (
              <Dialog key={'png' + index}>
                <DialogTrigger asChild>
                  <video src={mp4} controls width={400} height={400} />
                </DialogTrigger>
                <DialogContent className="max-w-5xl">
                  <video src={mp4} controls width={400} height={400} />
                </DialogContent>
              </Dialog>
            ))}
          </div>
        </div>
      )}
      {!!finalResult && <CodeBlock language="output" value={finalResult} />}
    </div>
  );
};

export default CodeResultDisplay;