feat: chat history ui

This commit is contained in:
Shibo Lyu 2024-08-31 04:49:26 +08:00
parent 0582dffa1c
commit aebe100799
16 changed files with 325 additions and 8 deletions

View file

@ -23,7 +23,7 @@
<p>{placeholder}</p>
</div>
{:then Input}
<svelte:component this={Input} bind:delta class={className} {placeholder}>
<svelte:component this={Input} bind:delta {placeholder}>
<slot />
</svelte:component>
{/await}

View file

@ -1,10 +1,28 @@
<script lang="ts">
import { Delta, Editor, asRoot } from 'typewriter-editor';
import { Delta, Editor, asRoot, h } from 'typewriter-editor';
export let delta: Delta = new Delta();
export let placeholder: string = '';
const editor = new Editor();
editor.typeset.formats.add({
name: 'underline',
selector: 'span[data-weblah-brt=underline]',
styleSelector: '[style*="text-decoration:underline"], [style*="text-decoration: underline"]',
commands: (editor) => () => editor.toggleTextFormat({ underline: true }),
shortcuts: 'Mod+U',
render: (attributes, children) => h('span', { 'data-weblah-brt': 'underline' }, children)
});
editor.typeset.formats.add({
name: 'strikethrough',
selector: 's',
styleSelector:
'[style*="text-decoration:line-through"], [style*="text-decoration: line-through"]',
commands: (editor) => () => editor.toggleTextFormat({ strikethrough: true }),
shortcuts: 'Mod+Shift+X',
render: (attributes, children) => h('s', null, children)
});
delta = editor.getDelta();
editor.on('change', () => {
delta = editor.getDelta();

View file

@ -0,0 +1,28 @@
<script lang="ts">
import type { BlahRichText } from '$lib/richText';
import { tw } from '$lib/tw';
import RichTextSpan from './RichTextRenderer/RichTextSpan.svelte';
export let content: BlahRichText;
let className = '';
export { className as class };
</script>
<div class={tw('rich-text', className)}>
{#each content as block}
<p>
{#each block as span}
{#if typeof span === 'string'}
{#if span === ''}
<br />
{:else}
{span}
{/if}
{:else}
{@const [text, attributes] = span}
<RichTextSpan {text} {attributes} />
{/if}
{/each}
</p>
{/each}
</div>

View file

@ -0,0 +1,53 @@
<script lang="ts">
import type { BlahRichTextSpanAttributes } from '$lib/richText';
// From outside to inside, better align this with the RichTextInput
const renderOrder: (keyof BlahRichTextSpanAttributes)[] = [
'link',
'hashtag',
'b',
'i',
'm',
'u',
's'
];
const tagMap: Partial<Record<keyof BlahRichTextSpanAttributes, string>> = {
s: 's',
b: 'strong',
i: 'em',
m: 'code'
};
const dataAttributeBrtMap: Partial<Record<keyof BlahRichTextSpanAttributes, string>> = {
u: 'underline'
};
export let text: string;
export let attributes: BlahRichTextSpanAttributes;
export let attribute: keyof BlahRichTextSpanAttributes | '' = renderOrder[0];
const nextAttribute = attribute ? (renderOrder[renderOrder.indexOf(attribute) + 1] ?? '') : null;
</script>
{#if attribute === '' || !attributes[attribute]}
{text}
{:else if attribute === 'link'}
<a href={attributes.link} target="_blank">
<svelte:self {...$$props} attribute={nextAttribute} />
</a>
{:else if attribute === 'hashtag'}
<a href={`/search?q=${encodeURIComponent(text)}`}>
<svelte:self {...$$props} attribute={nextAttribute} />
</a>
{:else if tagMap[attribute]}
<svelte:element this={tagMap[attribute]}>
<svelte:self {...$$props} attribute={nextAttribute} />
</svelte:element>
{:else if dataAttributeBrtMap[attribute]}
<span data-weblah-brt={dataAttributeBrtMap[attribute]}>
<svelte:self {...$$props} attribute={nextAttribute} />
</span>
{:else}
<svelte:self {...$$props} attribute={nextAttribute} />
{/if}