File size: 1,953 Bytes
f672a5d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useState, useEffect } from "react";
import { Loader2 } from "lucide-react";

import { useLLM } from "../hooks/useLLM";
import { ChatApp } from "./ChatApp";

export function AppShell() {
  const { status } = useLLM();
  const isReady = status.state === "ready";
  const [showChat, setShowChat] = useState(false);

  useEffect(() => {
    if (isReady) {
      const timeoutId = setTimeout(() => setShowChat(true), 300);
      return () => clearTimeout(timeoutId);
    }
  }, [isReady]);

  return (
    <>
      <div
        className={`absolute inset-0 z-20 flex flex-col items-center justify-center transition-opacity duration-1000 ease-in-out ${
          showChat ? "opacity-0 pointer-events-none" : "opacity-100"
        }`}
      >
        <Loader2 className="h-10 w-10 animate-spin text-[#76b900]" />
        <p className="mt-4 text-base text-white/80">
          {status.state === "loading"
            ? (status.message ?? "Loading model…")
            : status.state === "error"
              ? "Error"
              : "Preparing Nemotron-3-Nano…"}
        </p>
        <div className="mt-3 h-1.5 w-72 overflow-hidden rounded-full bg-white/20">
          <div
            className="h-full rounded-full bg-[#76b900] transition-[width] duration-300 ease-out"
            style={{
              width: `${
                status.state === "ready"
                  ? 100
                  : status.state === "loading"
                    ? (status.progress ?? 0)
                    : 0
              }%`,
            }}
          />
        </div>
        {status.state === "error" && (
          <p className="mt-2 text-sm text-red-300">{status.error}</p>
        )}
      </div>

      <div
        className={`absolute inset-0 z-30 bg-[#0a0a0a] transition-opacity duration-1000 ease-in-out ${
          showChat ? "opacity-100" : "opacity-0 pointer-events-none"
        }`}
      >
        <ChatApp />
      </div>
    </>
  );
}