major ui overhaul adding skeletonlabs design system

This commit is contained in:
Samuel Andert
2023-07-27 09:30:30 +02:00
parent 371e42e4ee
commit 460deb3be1
30 changed files with 994 additions and 1050 deletions

View File

@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -1,9 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="dark">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#603cba">
<meta name="apple-mobile-web-app-title" content="Nova Ai">
<meta name="application-name" content="Nova Ai">
<meta name="msapplication-TileColor" content="#603cba">
<meta name="theme-color" content="#ffffff">
%sveltekit.head%
</head>
<script>
@ -15,7 +23,7 @@
}
}
</script>
<body data-sveltekit-preload-data="hover">
<body data-theme="skeleton" data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@ -0,0 +1,12 @@
<script>
import { AppBar } from '@skeletonlabs/skeleton';
import { Avatar } from '@skeletonlabs/skeleton';
</script>
<AppBar>
<svelte:fragment slot="lead"
><Avatar src="logo.png" width="w-8" rounded="rounded-full" /></svelte:fragment
>
<h1 class="h4">Nova</h1>
<!-- <svelte:fragment slot="trail">(actions)</svelte:fragment> -->
</AppBar>

View File

@ -0,0 +1,17 @@
<script>
const routes = [
{ path: '/', name: 'Home', icon: '🏠' },
{ path: '/wallet', name: 'Wallet', icon: '💼' },
{ path: '/helloearth', name: 'Hello Earth', icon: '🌍' },
{ path: '/login', name: 'Login', icon: '🔑' }
];
</script>
<div class="logo-cloud grid-cols-1 lg:!grid-cols-4 gap-1">
{#each routes as route, index}
<a class="logo-item" href={route.path}>
<span>{route.icon}</span>
<span>{route.name}</span>
</a>
{/each}
</div>

View File

@ -1,14 +0,0 @@
<script>
import { clearMessages } from '$lib/services/messages/messages';
function handleClear() {
clearMessages();
}
</script>
<button
class="px-4 py-2 ml-2 text-white bg-red-500 rounded hover:bg-red-600"
on:click={handleClear}
>
Clear
</button>

View File

@ -6,7 +6,7 @@
import { createMessage } from '$lib/services/messages/messages';
import { createLitSession } from '$lib/services/createLitSession/createLitSession';
const redirectUri = 'http://localhost:5173/';
const redirectUri = 'http://localhost:5173/login';
export let services;
@ -31,6 +31,7 @@
onMount(async () => {
try {
provider = await services.setupLit.connectProvider();
console.log('Provider: ' + provider);
logMessage('Component mounted.');

View File

@ -1,6 +1,7 @@
<script>
import { onMount, afterUpdate } from 'svelte';
import Composite from '$lib/core/Composite.svelte';
import { Avatar } from '@skeletonlabs/skeleton';
export let store;
@ -27,22 +28,22 @@
{#if isStoreLoaded}
{#if $store.messages}
<main bind:this={messagesContainer} class="w-full h-full p-4 overflow-y-auto">
{#each $store.messages as message}
<div class="p-3 mb-2 bg-white border-b border-gray-300 rounded-lg shadow-lg">
<div class="flex items-center justify-between">
<p class="text-sm text-gray-600">
{message.type} | {message.sender}
</p>
<p class="text-xs text-gray-600">{message.timestamp}</p>
<div class="grid gap-2">
{#each $store.messages as message}
<div class="p-4 space-y-2 rounded-tl-none card variant-soft">
<header class="flex items-center justify-between">
<p class="font-bold">{message.type} | {message.sender}</p>
<small class="opacity-50">{message.timestamp}</small>
</header>
<p>{message.text}</p>
</div>
<p class="mt-2 text-base text-gray-800">{message.text}</p>
</div>
{#if message.composite}
<div class="overflow-y-auto max-h-80vh">
<Composite composite={message.composite} />
</div>
{/if}
{/each}
{#if message.composite}
<div class="overflow-y-auto max-h-80vh">
<Composite composite={message.composite} />
</div>
{/if}
{/each}
</div>
</main>
{/if}
{:else}

View File

@ -1,33 +0,0 @@
<script>
import { createMessage } from '$lib/services/messages/messages';
export function sendMessage(text) {
if (text && text.trim() !== '') {
const message = {
text: text,
sender: 'user',
type: 'chat'
};
const appCommandPattern = /@(\w+)/;
const match = text.match(appCommandPattern);
if (match && match[1]) {
message.composite = {
id: match[1],
component: match[1]
};
}
console.log(message);
createMessage(message);
}
}
function handleSend() {
sendMessage(text);
}
</script>
<button class="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-600" on:click={handleSend}>
Send
</button>

View File

@ -1,34 +1,69 @@
<script>
import { getContextStore } from '$lib/stores/contextStore.ts';
import ClearMessages from './ClearMessages.svelte';
import SendMessage from './SendMessage.svelte';
<!-- TerminalComponent.svelte -->
<script lang="ts">
import { createMessage, clearMessages } from '$lib/services/messages/messages';
import { drawerStore } from '@skeletonlabs/skeleton';
import type { DrawerSettings } from '@skeletonlabs/skeleton';
const drawerSettings: DrawerSettings = {
position: 'bottom',
id: 'drawer',
meta: { id: 'apps', component: 'Apps' }
};
const openDrawer = () => {
drawerStore.open(drawerSettings);
};
const store = getContextStore('MessageInput');
let newMessageText = '';
let sendFunction; // To hold the sendMessage function from SendMessage component
function handleKeyDown(event) {
if (event.key === 'Enter') {
sendFunction(newMessageText);
sendMessage(newMessageText);
newMessageText = '';
store.set({ newMessageText }); // Update the store directly
event.preventDefault();
}
}
// Reactive assignment to store when newMessageText changes
$: store.set({ newMessageText });
// Sending message logic
function sendMessage(text) {
if (text && text.trim() !== '') {
const message = {
text: text,
sender: 'user',
type: 'chat'
};
const appCommandPattern = /@(\w+)/;
const match = text.match(appCommandPattern);
if (match && match[1]) {
message.composite = {
id: match[1],
component: match[1]
};
}
createMessage(message);
}
}
// Clear messages logic
function handleClear() {
clearMessages();
}
</script>
<footer class="flex justify-end p-4 bg-white">
<input
type="text"
class="flex-grow px-3 py-2 mr-2 border rounded"
placeholder="Type your message..."
<div class="input-group input-group-divider grid-cols-[auto_1fr_auto] rounded-container-token h-12">
<button class="input-group-shim" on:click={openDrawer}>+</button>
<textarea
class="bg-transparent border-0 ring-0"
name="prompt"
id="prompt"
placeholder="Write a message..."
rows="1"
bind:value={newMessageText}
on:keydown={handleKeyDown}
/>
<SendMessage bind:sendMessage={sendFunction} />
<ClearMessages />
</footer>
<button class="variant-filled-primary" on:click={() => sendMessage(newMessageText)}>Send</button>
<!-- <button class="variant-filled-primary" on:click={handleClear}>clear</button> -->
</div>

View File

@ -1,18 +1,24 @@
<script>
<script lang="ts">
import '@skeletonlabs/skeleton/themes/theme-skeleton.css';
import '@skeletonlabs/skeleton/styles/skeleton.css';
import '../app.css';
import { initChainProvider } from '$lib/services/provider/setupChainProvider';
import { onMount } from 'svelte';
/** @type {import('$lib/services/provider/setupChainProvider').ProviderData} */
const providerData = {
walletConnectId: import.meta.env.VITE_WALLETCONNECT_ID
};
import { Modal, modalStore } from '@skeletonlabs/skeleton';
import { Drawer, drawerStore } from '@skeletonlabs/skeleton';
import Composite from '$lib/core/Composite.svelte';
onMount(() => {
initChainProvider(providerData);
});
</script>
<Modal />
<Drawer>
<Composite composite={$drawerStore.meta} />
</Drawer>
<div class="relative w-screen h-screen overflow-hidden">
<slot />
</div>

View File

@ -8,37 +8,15 @@
id: 'composite',
layout: {
areas: `
"top main"
"aside main"
"footer footer ";
"top top"
"main main"
"footer footer";
`,
columns: '1fr 1fr ',
rows: '1fr 1fr auto'
columns: '1fr 300px',
rows: 'auto 1fr auto'
},
children: [
{
id: 'w',
component: 'Wallet',
slot: 'aside',
store: {
pkpWallet: '',
rpcURL: 'https://rpc.gnosischain.com/',
pkpPubKey:
'046da3ba67065fd1e2726242ca01cd4601524893f4aa4b0042578fa6cbec28fa8c9a28eb9f7893932fc09717edc9e1db57e157a21eed346247c1db5a722a01f571'
}
},
{
id: 'hello',
component: 'HelloEarth',
slot: 'top',
map: {
pkpWallet: 'w.pkpWallet',
rpcURL: 'w.rpcURL',
messages: 'data.queryMessages',
todos: 'data.queryTodos'
},
services: ['helloEarthAlert']
},
{ id: 'appbar', component: 'AppBar', slot: 'top' },
{
id: 'me',
component: 'Messages',

View File

@ -0,0 +1,35 @@
<script>
import Composite from '$lib/core/Composite.svelte';
let composite = {
id: 'composite',
layout: {
areas: `
"main"
"footer";
`,
rows: '1fr auto'
},
children: [
{
id: 'hello',
component: 'HelloEarth',
slot: 'main',
map: {
pkpWallet: 'w.pkpWallet',
rpcURL: 'w.rpcURL',
messages: 'data.queryMessages',
todos: 'data.queryTodos'
},
services: ['helloEarthAlert']
},
{
id: 'terminal',
component: 'Terminal',
slot: 'footer'
}
]
};
</script>
<Composite {composite} />

View File

@ -0,0 +1,17 @@
<script>
import Composite from '$lib/core/Composite.svelte';
let composite = {
id: 'login',
children: [
{
id: 'google',
component: 'GoogleAuth',
slot: 'main',
services: ['setupLit']
}
]
};
</script>
<Composite {composite} />

View File

@ -0,0 +1,40 @@
<script>
import Composite from '$lib/core/Composite.svelte';
let composite = {
id: 'composite',
layout: {
areas: `
"top"
"main"
"footer";
`,
rows: 'auto 1fr auto'
},
children: [
{
id: 'authsig',
component: 'AuthSig',
slot: 'top'
},
{
id: 'wallet',
component: 'Wallet',
slot: 'main',
store: {
pkpWallet: '',
rpcURL: 'https://rpc.gnosischain.com/',
pkpPubKey:
'046da3ba67065fd1e2726242ca01cd4601524893f4aa4b0042578fa6cbec28fa8c9a28eb9f7893932fc09717edc9e1db57e157a21eed346247c1db5a722a01f571'
}
},
{
id: 'terminal',
component: 'Terminal',
slot: 'footer'
}
]
};
</script>
<Composite {composite} />