radames's picture
first
effb90e
raw
history blame
5.47 kB
<script lang="ts">
import { PUBLIC_BACKEND_WS_URL } from '$env/static/public';
import { onMount } from 'svelte';
import { nanoid } from 'nanoid';
import { chatsStore, selectedChatId, loadingState } from '$lib/store';
import type { Message, Chat } from '$lib/types';
import { MessageType, Sender } from '$lib/types';
import ChatInput from '$lib/ChatInput.svelte';
import ChatMessage from '$lib/ChatMessage.svelte';
import ChatNewBtn from '$lib/ChatNewBtn.svelte';
$: isLoading = false;
function clearStateMsg(t = 5000) {
setTimeout(() => {
$loadingState = '';
}, t);
}
onMount(() => {
// generateImage();
});
$: chatData = $chatsStore.find((chat) => chat.id === $selectedChatId);
$: messages = chatData?.messages || [];
$: console.log($chatsStore);
function newChat() {
const chatId = nanoid();
const chat: Chat = {
id: chatId,
blurb: `New Chat - ${chatId}`,
messages: [],
timestamp: new Date().getTime()
};
$chatsStore = [chat].concat($chatsStore);
$selectedChatId = chat.id;
}
function submitMessage(event: CustomEvent) {
const value = event.detail;
const message: Message = {
sender: Sender.USER,
id: nanoid(),
type: MessageType.TEXT,
content: value,
timestamp: new Date().getTime()
};
$chatsStore = $chatsStore.map((chat) => {
if (chat.id === $selectedChatId) {
chat.messages.push(message);
}
return chat;
});
}
const timeFormater = new Intl.DateTimeFormat('en-US', {
day: 'numeric',
month: 'short',
hour: 'numeric',
minute: 'numeric'
}).format;
async function generateImage() {
if (isLoading) return;
$loadingState = 'Pending';
const sessionHash = crypto.randomUUID();
const hashpayload = {
fn_index: 1,
session_hash: sessionHash
};
const image = '';
const datapayload = {
data: [
'make him wear shirts', // prompt
10.5, // text guidance
1.5, // image guidance
image,
15, // steps
'', // negative promtp,
512, // width
512, // height
0 // seed
]
};
const websocket = new WebSocket(PUBLIC_BACKEND_WS_URL);
// websocket.onopen = async function (event) {
// websocket.send(JSON.stringify({ hash: sessionHash }));
// };
websocket.onclose = (evt) => {
if (!evt.wasClean) {
$loadingState = 'Error';
}
};
websocket.onmessage = async function (event) {
try {
const data = JSON.parse(event.data);
$loadingState = '';
switch (data.msg) {
case 'send_hash':
websocket.send(JSON.stringify(hashpayload));
break;
case 'send_data':
$loadingState = 'Sending Data';
websocket.send(JSON.stringify({ ...hashpayload, ...datapayload }));
break;
case 'queue_full':
$loadingState = 'Queue full';
websocket.close();
return;
case 'estimation':
const { rank, queue_size } = data;
$loadingState = `On queue ${rank}/${queue_size}`;
break;
case 'process_generating':
$loadingState = data.success ? 'Generating' : 'Error';
break;
case 'process_completed':
try {
console.log(data);
// const params = data.output.data[0] as {
// is_nsfw: boolean;
// image: {
// url: string;
// filename: string;
// };
// };
// const isNSWF = params.is_nsfw;
// if (isNSWF) {
// throw new Error('NFSW');
// }
// // const imgBlob = await base64ToBlob(imgBase64);
// const promptImgParams = {
// imgURL: params.image.filename
// };
// // const imgURL = await uploadImage(imgBlob, promptImgParams);
// // $promptImgStorage.set(imageKey, promptImgParams);
// console.log(params.image.url);
$loadingState = data.success ? 'Complete' : 'Error';
clearStateMsg();
} catch (err) {
const tError = err as Error;
$loadingState = tError?.message;
clearStateMsg(10000);
}
websocket.close();
return;
case 'process_starts':
$loadingState = 'Processing';
break;
}
} catch (e) {
console.error(e);
$loadingState = 'Error';
}
};
}
</script>
<div>
<h1 class="text-2xl">CHATS</h1>
<div class="grid min-h-[40rem] grid-cols-4">
<div class="col-span-1 flex flex-col border-r p-4">
<ChatNewBtn on:click={newChat} />
<div class="max-h-[40rem] flex flex-col gap-2 overflow-y-scroll">
{#if $chatsStore.length}
{#each $chatsStore as chat}
<button on:click={() => ($selectedChatId = chat.id)}>
<div
class="flex h-16 flex-col items-start justify-center rounded-xl bg-gray-100 px-4 text-gray-900
{chat.id === $selectedChatId ? 'bg-gray-400' : ''}"
>
<h3 class="w-full truncate font-semibold">{chat.blurb}</h3>
<p class="w-full truncate text-sm text-gray-500">
{timeFormater(new Date(chat.timestamp))}
</p>
</div>
</button>
{/each}
{:else}
<div
class="flex h-16 flex-col items-start justify-center rounded-xl bg-gray-100 px-4 text-gray-900"
>
<h3 class="w-full truncate font-semibold">No chats</h3>
<p class="w-full truncate text-sm text-gray-500">Start a new Chat!</p>
</div>
{/if}
</div>
</div>
<div class="col-span-3 flex flex-col">
{#each messages as message}
<ChatMessage {message} />
{/each}
<ChatInput on:submitMessage={submitMessage} />
</div>
</div>
</div>
<style lang="postcss" scoped>
</style>