Added dynamic component rendering attached to message with the
@app: command
This commit is contained in:
		| @@ -11,7 +11,7 @@ | |||||||
| 	} | 	} | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <div class="grid h-full w-full" style="display: grid; {componentsData.layout || ''}"> | <div class="grid w-full h-full" style="display: grid; {componentsData.layout || ''}"> | ||||||
| 	{#each componentsData.children as component (component.id)} | 	{#each componentsData.children as component (component.id)} | ||||||
| 		{#await getComponent(component.componentName) then Component} | 		{#await getComponent(component.componentName) then Component} | ||||||
| 			{#if Component} | 			{#if Component} | ||||||
|   | |||||||
| @@ -1,47 +1,76 @@ | |||||||
| <script> | <script> | ||||||
| 	import { createMessage, clearMessages } from '$lib/services/messages'; | 	import { createMessage, clearMessages } from '$lib/services/messages'; | ||||||
|  |  | ||||||
| 	createMessage({ |  | ||||||
| 		text: 'Component loaded', |  | ||||||
| 		sender: '$lib/components/MessageInput.svelte', |  | ||||||
| 		type: 'SYSTEM' |  | ||||||
| 	}); |  | ||||||
|  |  | ||||||
| 	let newMessageText = ''; | 	let newMessageText = ''; | ||||||
|  |  | ||||||
|  | 	// Default message composite structure | ||||||
|  | 	const messageComposite = { | ||||||
|  | 		layout: '', | ||||||
|  | 		children: [ | ||||||
|  | 			{ | ||||||
|  | 				componentName: 'HelloEarth', | ||||||
|  | 				props: {} | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	function handleSend() { | 	function handleSend() { | ||||||
| 		if (newMessageText.trim() !== '') { | 		if (newMessageText.trim() !== '') { | ||||||
| 			// Create a new message with the default sender and type using an object | 			// Default message without composite | ||||||
| 			createMessage({ text: newMessageText, sender: 'user', type: 'chat' }); | 			const message = { | ||||||
|  | 				text: newMessageText, | ||||||
|  | 				sender: 'user', | ||||||
|  | 				type: 'chat' | ||||||
|  | 			}; | ||||||
|  |  | ||||||
|  | 			// Check if text contains @app:command and add the composite accordingly | ||||||
|  | 			const appCommandPattern = /@app:(\w+)/; | ||||||
|  | 			const match = newMessageText.match(appCommandPattern); | ||||||
|  | 			if (match && match[1]) { | ||||||
|  | 				message.composite = { | ||||||
|  | 					layout: '', | ||||||
|  | 					children: [ | ||||||
|  | 						{ | ||||||
|  | 							componentName: match[1], // Matched component name | ||||||
|  | 							props: {} | ||||||
|  | 						} | ||||||
|  | 					] | ||||||
|  | 				}; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			createMessage(message); | ||||||
|  |  | ||||||
|  | 			// Store the last message that was sent | ||||||
|  | 			lastMessageSent = newMessageText; | ||||||
| 			newMessageText = ''; | 			newMessageText = ''; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function handleClear() { | 	function handleClear() { | ||||||
| 		clearMessages(); // Call the clearMessages function to clear all messages. | 		clearMessages(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function handleKeyDown(event) { | 	function handleKeyDown(event) { | ||||||
| 		if (event.key === 'Enter') { | 		if (event.key === 'Enter') { | ||||||
| 			handleSend(); | 			handleSend(); | ||||||
| 			event.preventDefault(); // Prevents a newline being added to the input field | 			event.preventDefault(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <footer class="bg-white p-4 flex justify-end"> | <footer class="flex justify-end p-4 bg-white"> | ||||||
| 	<input | 	<input | ||||||
| 		type="text" | 		type="text" | ||||||
| 		class="flex-grow border rounded px-3 py-2 mr-2" | 		class="flex-grow px-3 py-2 mr-2 border rounded" | ||||||
| 		placeholder="Type your message..." | 		placeholder="Type your message..." | ||||||
| 		bind:value={newMessageText} | 		bind:value={newMessageText} | ||||||
| 		on:keydown={handleKeyDown} | 		on:keydown={handleKeyDown} | ||||||
| 	/> | 	/> | ||||||
| 	<button class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded" on:click={handleSend}> | 	<button class="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-600" on:click={handleSend}> | ||||||
| 		Send Message | 		Send Message | ||||||
| 	</button> | 	</button> | ||||||
| 	<button | 	<button | ||||||
| 		class="bg-red-500 hover:bg-red-600 text-white py-2 px-4 rounded ml-2" | 		class="px-4 py-2 ml-2 text-white bg-red-500 rounded hover:bg-red-600" | ||||||
| 		on:click={handleClear} | 		on:click={handleClear} | ||||||
| 	> | 	> | ||||||
| 		Clear | 		Clear | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| <script> | <script> | ||||||
| 	import { messages, createMessage } from '$lib/services/messages'; | 	import { messages, createMessage } from '$lib/services/messages'; | ||||||
| 	import { onMount, afterUpdate } from 'svelte'; | 	import { onMount } from 'svelte'; | ||||||
|  | 	import Composite from './Composite.svelte'; | ||||||
|  |  | ||||||
| 	let latestMessages = []; | 	let latestMessages = []; | ||||||
|  |  | ||||||
| @@ -16,20 +17,32 @@ | |||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	// Watch for changes in latestMessages | ||||||
|  | 	$: { | ||||||
|  | 		// Use setTimeout to give the DOM some time to update | ||||||
|  | 		setTimeout(scrollToBottom, 50); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	onMount(scrollToBottom); | 	onMount(scrollToBottom); | ||||||
| 	afterUpdate(scrollToBottom); |  | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <main bind:this={messagesContainer} class="p-4 overflow-y-auto h-full w-full"> | <main bind:this={messagesContainer} class="w-full h-full p-4 overflow-y-auto"> | ||||||
| 	{#each latestMessages as message} | 	{#each latestMessages as message} | ||||||
| 		<div class="bg-white p-3 rounded-lg shadow-lg mb-2 border-b border-gray-300"> | 		<div class="p-3 mb-2 bg-white border-b border-gray-300 rounded-lg shadow-lg"> | ||||||
| 			<div class="flex items-center justify-between"> | 			<div class="flex items-center justify-between"> | ||||||
| 				<p class="text-sm text-gray-600"> | 				<p class="text-sm text-gray-600"> | ||||||
| 					{message.type} | {message.sender} | 					{message.type} | {message.sender} | ||||||
| 				</p> | 				</p> | ||||||
| 				<p class="text-xs text-gray-600">{message.timestamp}</p> | 				<p class="text-xs text-gray-600">{message.timestamp}</p> | ||||||
| 			</div> | 			</div> | ||||||
| 			<p class="text-base text-gray-800 mt-2">{message.text}</p> | 			<p class="mt-2 text-base text-gray-800">{message.text}</p> | ||||||
|  |  | ||||||
|  | 			<!-- Render Composite Component --> | ||||||
|  | 			{#if message.composite} | ||||||
|  | 				<div class="mt-2 overflow-y-auto max-h-500"> | ||||||
|  | 					<Composite componentsData={message.composite} /> | ||||||
|  | 				</div> | ||||||
|  | 			{/if} | ||||||
| 		</div> | 		</div> | ||||||
| 	{/each} | 	{/each} | ||||||
| </main> | </main> | ||||||
|   | |||||||
| @@ -28,8 +28,10 @@ export interface Message { | |||||||
|   timestamp: string; |   timestamp: string; | ||||||
|   sender: string; |   sender: string; | ||||||
|   type: string; |   type: string; | ||||||
|  |   composite?: object | null; // New field | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // Load messages from localStorage or set an empty array if not available | // Load messages from localStorage or set an empty array if not available | ||||||
| const initialMessages = getFromLocalStorage('chat-messages', []); | const initialMessages = getFromLocalStorage('chat-messages', []); | ||||||
|  |  | ||||||
| @@ -48,11 +50,11 @@ export function createMessage(messageData) { | |||||||
|     text: messageData.text, |     text: messageData.text, | ||||||
|     timestamp: currentDate, |     timestamp: currentDate, | ||||||
|     sender: messageData.sender, |     sender: messageData.sender, | ||||||
|     type: messageData.type |     type: messageData.type, | ||||||
|  |     composite: messageData.composite || null // New field | ||||||
|   }; |   }; | ||||||
|   messages.update(oldMessages => [...oldMessages, newMessageObj]); |   messages.update(oldMessages => [...oldMessages, newMessageObj]); | ||||||
| } | } | ||||||
|  |  | ||||||
| export function clearMessages() { | export function clearMessages() { | ||||||
|   messages.set([]); |   messages.set([]); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user