Spaces:
Sleeping
Sleeping
File size: 4,522 Bytes
59b210a |
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 151 152 153 154 155 156 157 |
'use client'
import { useState, useEffect, useRef } from 'react'
import { useTheme } from 'next-themes'
import Header from '@/components/Header'
import ChatArea from '@/components/ChatArea'
import InputArea from '@/components/InputArea'
import Footer from '@/components/Footer'
import CookieConsent from '@/components/CookieConsent'
import { v4 as uuidv4 } from 'uuid'
export default function KarmaPollinations() {
const [messages, setMessages] = useState([])
const [textModels, setTextModels] = useState([])
const [imageModels, setImageModels] = useState([])
const { setTheme } = useTheme()
const chatAreaRef = useRef(null)
const [showCookieConsent, setShowCookieConsent] = useState(true)
useEffect(() => {
setTheme('dark')
fetchModels()
loadMessagesFromLocalStorage()
const consent = localStorage.getItem('cookieConsent')
if (consent === 'accepted') {
setShowCookieConsent(false)
}
}, [setTheme])
useEffect(() => {
fetchModels()
}, [])
useEffect(() => {
scrollToBottom()
}, [messages])
const fetchModels = async () => {
try {
const textResponse = await fetch('https://text.pollinations.ai/models')
const textData = await textResponse.json()
setTextModels(textData.map(model => ({ ...model, id: `text-${model.name}` })))
const imageResponse = await fetch('https://image.pollinations.ai/models')
const imageData = await imageResponse.json()
setImageModels(imageData.map((model, index) => ({ id: `image-${model}-${index}`, name: model, description: model })))
} catch (error) {
console.error('Error fetching models:', error)
}
}
const handleSendMessage = async (message, type, model, file) => {
const newMessage = {
id: uuidv4(),
content: message,
sender: 'user',
timestamp: new Date().toISOString(),
type,
model,
}
const updatedMessages = [...messages, newMessage]
setMessages(updatedMessages)
saveMessagesToLocalStorage(updatedMessages)
try {
const formData = new FormData()
formData.append('message', message)
formData.append('type', type)
formData.append('model', JSON.stringify(model))
if (file) {
formData.append('image', file)
}
const response = await fetch('/api/messages', {
method: 'POST',
body: formData,
})
if (!response.ok) {
throw new Error('Failed to process message')
}
const data = await response.json()
const assistantMessage = {
id: uuidv4(),
content: data.content,
sender: 'assistant',
timestamp: new Date().toISOString(),
type: data.type,
model: data.model,
}
if (data.imageUrl) {
assistantMessage.imageUrl = data.imageUrl
assistantMessage.imageText = data.imageText
}
const finalMessages = [...updatedMessages, assistantMessage]
setMessages(finalMessages)
saveMessagesToLocalStorage(finalMessages)
} catch (error) {
console.error('Error processing message:', error)
}
}
const scrollToBottom = () => {
if (chatAreaRef.current) {
chatAreaRef.current.scrollTo({
top: chatAreaRef.current.scrollHeight,
behavior: 'smooth',
})
}
}
const handleReset = () => {
localStorage.removeItem('chatMessages')
setMessages([])
}
const loadMessagesFromLocalStorage = () => {
const storedMessages = localStorage.getItem('chatMessages')
if (storedMessages) {
setMessages(JSON.parse(storedMessages))
}
}
const saveMessagesToLocalStorage = (messages) => {
localStorage.setItem('chatMessages', JSON.stringify(messages))
}
const handleAcceptCookies = () => {
setShowCookieConsent(false)
localStorage.setItem('cookieConsent', 'accepted')
}
return (
<div className="flex flex-col h-screen bg-background text-foreground">
{/* Fixed Header */}
<Header onReset={handleReset} className="fixed top-0 w-full z-10 shadow-md bg-primary text-white" />
{/* Main Content with Scrollable Center */}
<div className="flex-1 overflow-y-auto pt-16 pb-16">
<ChatArea messages={messages} chatAreaRef={chatAreaRef} />
</div>
{/* Fixed Footer */}
<InputArea
onSendMessage={handleSendMessage}
textModels={textModels}
imageModels={imageModels}
className="fixed bottom-0 w-full z-10 shadow-md bg-secondary text-white"
/>
</div>
)
}
|