Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 32 additions & 32 deletions apps/desktop/src/components/codegen/CodegenInput.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { Tooltip, Textarea, AsyncButton } from '@gitbutler/ui';
import { Tooltip, RichTextEditor, AsyncButton } from '@gitbutler/ui';
import { fade } from 'svelte/transition';
import type { Snippet } from 'svelte';

Expand All @@ -24,22 +24,19 @@
sessionKey
}: Props = $props();

let textareaRef = $state<HTMLTextAreaElement>();
let editorRef = $state<ReturnType<typeof RichTextEditor>>();

// Focus when component mounts or when session changes
$effect(() => {
if (textareaRef && sessionKey) {
if (editorRef && sessionKey) {
// Additional focus with longer delay to handle parent component timing
setTimeout(() => {
textareaRef?.focus();
// editorRef?.focus();
console.log('blah');

Check failure on line 35 in apps/desktop/src/components/codegen/CodegenInput.svelte

View workflow job for this annotation

GitHub Actions / lint-node

Unexpected console statement. Only these console methods are allowed: warn, error
}, 0);
}
});

$effect(() => {
onChange(value);
});

let showAbortButton = $state(false);

$effect(() => {
Expand All @@ -59,43 +56,46 @@
});

async function handleSubmit() {
const text = await editorRef?.getPlaintext();
if (!text || text.trim().length === 0) return;
await onsubmit();
}

async function handleKeypress(e: KeyboardEvent) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
function handleEditorKeyDown(event: KeyboardEvent | null): boolean {
if (!event) return false;

if (value.trim().length === 0) return;
// Handle Ctrl+C to abort
if (event.key === 'c' && event.ctrlKey && onAbort) {
event.preventDefault();
onAbort();
return true;
}

await handleSubmit();
// Handle Enter to submit
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
handleSubmit();
return true;
}
}

function handleDialogClick(e: MouseEvent) {
// Don't focus if clicking on buttons or other interactive elements
if (e.target !== e.currentTarget) return;
textareaRef?.focus();
return false;
}
</script>

<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="dialog-wrapper">
<div class="text-input dialog-input" onkeypress={handleKeypress} onclick={handleDialogClick}>
<Textarea
bind:textBoxEl={textareaRef}
<div class="text-input dialog-input">
<RichTextEditor
bind:this={editorRef}
bind:value
namespace="codegen-input"
markdown={false}
styleContext="chat-input"
placeholder="What would you like to make..."
borderless
maxRows={10}
minRows={2}
onkeydown={(e) => {
// Global gotakey on the button doesn't work inside textarea, so we handle it here
if (e.key === 'c' && e.ctrlKey && onAbort) {
e.preventDefault();
onAbort();
}
}}
minHeight="4rem"
onError={(e: unknown) => console.warn('Editor error', e)}
initialText={value}
{onChange}
onKeyDown={handleEditorKeyDown}
/>

<div class="dialog-input__actions">
Expand Down
32 changes: 17 additions & 15 deletions packages/ui/src/lib/richText/RichTextEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
placeholder?: string;
minHeight?: string;
onFocus?: () => void;
value?: string;
onBlur?: () => void;
onChange?: OnChangeCallback;
onInput?: OnInputCallback;
Expand All @@ -56,7 +57,7 @@
wrapCountValue?: number;
};

const {
let {
disabled,
namespace,
markdown,
Expand All @@ -66,6 +67,7 @@
plugins,
placeholder,
onFocus,
value = $bindable(''),
onBlur,
onChange,
onInput,
Expand Down Expand Up @@ -165,18 +167,14 @@
// Initial text is available asynchronously so we need to be able to
// insert initial text after first render.
$effect(() => {
updateInitialtext(initialText);
updateInitialtext(initialText || '');
});

async function updateInitialtext(initialText: string | undefined) {
if (initialText) {
const currentText = await getPlaintext();
if (currentText?.trim() === '') {
setText(initialText);
if (wrapCountValue !== undefined) {
wrapAll();
}
}
async function updateInitialtext(initialText: string) {
console.log('setting text');

Check failure on line 174 in packages/ui/src/lib/richText/RichTextEditor.svelte

View workflow job for this annotation

GitHub Actions / lint-node

Unexpected console statement. Only these console methods are allowed: warn, error
setText(initialText);
if (wrapCountValue !== undefined) {
wrapAll();
}
}

Expand Down Expand Up @@ -253,10 +251,14 @@
</div>

<EmojiPlugin bind:this={emojiPlugin} />

{#if onChange}
<OnChangePlugin {markdown} {onChange} maxLength={wrapCountValue} />
{/if}
<OnChangePlugin
{markdown}
onChange={(newValue, changeUpToAnchor, textAfterAnchor) => {
value = newValue;
onChange?.(newValue, changeUpToAnchor, textAfterAnchor);
}}
maxLength={wrapCountValue}
/>

{#if onInput}
<OnInput {markdown} {onInput} maxLength={wrapCountValue} />
Expand Down
Loading