MAC / frontend /src /lib /components /ChatMessage.svelte
Aaryan17's picture
chore: upload MAC codebase to HF Space
0e76632 verified
<script>
import { renderMarkdown, copyToClipboard } from '$lib/utils.js';
import { showToast } from '$lib/stores.js';
export let message = { role: 'user', content: '', model: '', ts: null };
export let streaming = false;
$: isUser = message.role === 'user';
$: html = isUser ? null : renderMarkdown(message.content);
async function copy() {
await copyToClipboard(message.content);
showToast('Copied to clipboard', 'success', 2000);
}
</script>
<div class="flex {isUser ? 'justify-end' : 'justify-start'} gap-3 group animate-fade-in">
{#if !isUser}
<div class="w-7 h-7 rounded-full bg-mac-800 border border-mac-700 flex items-center justify-center flex-shrink-0 mt-1">
<span class="text-xs font-bold text-mac-300">M</span>
</div>
{/if}
<div class="max-w-[85%] min-w-0">
<!-- Message bubble -->
{#if isUser}
<div class="message-user">
<p class="text-sm text-gray-100 whitespace-pre-wrap break-words">{message.content}</p>
</div>
{:else}
<div class="message-assistant">
{#if streaming && !message.content}
<!-- Typing indicator -->
<div class="flex gap-1 py-1">
<div class="typing-dot"></div>
<div class="typing-dot" style="animation-delay:150ms"></div>
<div class="typing-dot" style="animation-delay:300ms"></div>
</div>
{:else}
<div class="prose-sm text-gray-200 text-sm leading-relaxed break-words [&_pre]:mt-2 [&_code]:text-mac-300 [&_pre_code]:text-gray-200 [&_h1]:text-gray-100 [&_h2]:text-gray-100 [&_h3]:text-gray-200 [&_strong]:text-gray-100 [&_ul]:list-disc [&_ul]:pl-4 [&_ol]:list-decimal [&_ol]:pl-4">
{@html html}
</div>
{/if}
</div>
{/if}
<!-- Meta row -->
<div class="flex items-center gap-2 mt-1 px-1 opacity-0 group-hover:opacity-100 transition-opacity">
{#if message.model}
<span class="text-xs text-gray-600">{message.model}</span>
{/if}
{#if message.ts}
<span class="text-xs text-gray-600">
{new Date(message.ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
</span>
{/if}
{#if !isUser && message.content}
<button
on:click={copy}
class="text-xs text-gray-600 hover:text-gray-300 transition-colors ml-auto"
title="Copy"
>
📋
</button>
{/if}
</div>
</div>
{#if isUser}
<div class="w-7 h-7 rounded-full bg-dark-600 border border-dark-500 flex items-center justify-center flex-shrink-0 mt-1">
<span class="text-xs text-gray-400">You</span>
</div>
{/if}
</div>