File size: 4,461 Bytes
b9ee0e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use client";

import React, { useState, useEffect, useRef } from 'react';
import Image from 'next/image';
import ChatMessage from './ChatMessage';
import ChatInput from './ChatInput';

type Message = {
  role: 'user' | 'assistant';
  content: string;
};

// Function to generate a random number of "meow"s
const generateMeowCount = () => {
  // Random number between 1 and 30
  return Math.floor(Math.random() * 30) + 1;
};

const Chat: React.FC = () => {
  const [messages, setMessages] = useState<Message[]>([
    {
      role: 'assistant',
      content: 'meow',
    },
  ]);
  const [isTyping, setIsTyping] = useState(false);
  const [streamingContent, setStreamingContent] = useState('');
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const streamIntervalRef = useRef<NodeJS.Timeout | null>(null);

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  useEffect(() => {
    scrollToBottom();
  }, [messages, isTyping, streamingContent]);

  // Clean up interval on unmount
  useEffect(() => {
    return () => {
      if (streamIntervalRef.current) {
        clearInterval(streamIntervalRef.current);
      }
    };
  }, []);

  const handleSendMessage = (content: string) => {
    // Clear any existing interval
    if (streamIntervalRef.current) {
      clearInterval(streamIntervalRef.current);
      streamIntervalRef.current = null;
    }

    // Add user message
    setMessages((prev) => [...prev, { role: 'user', content }]);
    
    // Simulate typing
    setIsTyping(true);
    setStreamingContent('');
    
    // Simulate response delay (between 0.5-1 seconds)
    setTimeout(() => {
      const meowCount = generateMeowCount();
      let currentMeows = 0;
      const meowArray = Array(meowCount).fill("meow");
      
      // Start streaming the meows
      streamIntervalRef.current = setInterval(() => {
        if (currentMeows < meowCount) {
          currentMeows++;
          setStreamingContent(meowArray.slice(0, currentMeows).join(" "));
        } else {
          // Finished streaming
          if (streamIntervalRef.current) {
            clearInterval(streamIntervalRef.current);
            streamIntervalRef.current = null;
          }
          
          // Add the complete message
          setMessages((prev) => [...prev, { 
            role: 'assistant', 
            content: meowArray.join(" ") 
          }]);
          
          setIsTyping(false);
          setStreamingContent('');
        }
      }, 100); // Add a new meow every 100ms
    }, 500 + Math.random() * 500);
  };

  return (
    <div className="flex flex-col h-full bg-white">
      <div className="flex-1 overflow-y-auto pb-4">
        <div>
          {messages.map((message, index) => (
            <ChatMessage key={index} role={message.role} content={message.content} />
          ))}
          {isTyping && (
            <div className="py-6 bg-white">
              <div className="max-w-3xl mx-auto flex items-start gap-4 px-4 sm:px-6 md:px-8">
                <div className="flex-shrink-0 w-8 h-8">
                  <div className="w-8 h-8 flex items-center justify-center overflow-hidden">
                    <Image src="/cat.png" alt="CatGPT Logo" width={32} height={32} />
                  </div>
                </div>
                <div className="flex-1 min-w-0">
                  <p className="font-medium text-sm mb-2 text-gray-800">CatGPT</p>
                  {streamingContent ? (
                    <div className="prose max-w-none text-gray-800">
                      <p className="whitespace-pre-wrap">{streamingContent}</p>
                    </div>
                  ) : (
                    <div className="flex space-x-2 items-center">
                      <span className="w-2 h-2 rounded-full bg-gray-400 animate-pulse"></span>
                      <span className="w-2 h-2 rounded-full bg-gray-400 animate-pulse" style={{ animationDelay: '0.2s' }}></span>
                      <span className="w-2 h-2 rounded-full bg-gray-400 animate-pulse" style={{ animationDelay: '0.4s' }}></span>
                    </div>
                  )}
                </div>
              </div>
            </div>
          )}
          <div ref={messagesEndRef} />
        </div>
      </div>
      <div className="mt-auto">
        <ChatInput onSendMessage={handleSendMessage} disabled={isTyping} />
      </div>
    </div>
  );
};

export default Chat;