feat(ai): generate with Enter shortcut (#236)
This commit is contained in:
1 parent
db58da7c3e
commit
798628f0b5
2 files changed
+44
-4
No files matched your search
@@ -491,7 +491,11 @@ export const AiAssistantDialog = ({
|
||||
</Button>
|
||||
) : (
|
||||
<Button type="button" variant="solid" className="h-10 min-w-0 w-full gap-1.5 whitespace-nowrap px-3 text-sm font-semibold" disabled={generateDisabled} onClick={() => void generate()}>
|
||||
<Sparkles className="h-4 w-4 shrink-0" />{t("aiAssistant.generate")}
|
||||
<Sparkles className="h-4 w-4 shrink-0" />
|
||||
{t("aiAssistant.generate")}
|
||||
<kbd aria-hidden="true" className="ml-0.5 rounded border border-emerald-300/60 bg-emerald-600/35 px-1 py-0.5 text-[10px] font-medium leading-none text-emerald-50">
|
||||
Enter
|
||||
</kbd>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@@ -562,6 +566,19 @@ export const AiAssistantDialog = ({
|
||||
setCustomInstruction(event.currentTarget.value);
|
||||
clearResult();
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (
|
||||
event.key !== "Enter"
|
||||
|| event.shiftKey
|
||||
|| event.nativeEvent.isComposing
|
||||
|| isGenerating
|
||||
|| isReadingAttachments
|
||||
) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
void generate();
|
||||
}}
|
||||
placeholder={t("aiAssistant.customInstructionPlaceholder")}
|
||||
maxLength={2_000}
|
||||
/>
|
||||
|
||||
@@ -27,9 +27,11 @@ const mockAiGeneration = async (
|
||||
page: Page,
|
||||
replacement: string,
|
||||
onRequest?: (body: Record<string, unknown>) => void,
|
||||
delayMs = 0,
|
||||
) => {
|
||||
await page.route("**/api/v1/ai/generate", async (route) => {
|
||||
onRequest?.(route.request().postDataJSON() as Record<string, unknown>);
|
||||
if (delayMs > 0) await new Promise((resolve) => setTimeout(resolve, delayMs));
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: "text/event-stream; charset=utf-8",
|
||||
@@ -338,13 +340,15 @@ test.describe("AI custom prompts", () => {
|
||||
test("keeps a Chinese custom instruction usable while prompts initialize", async ({ page }) => {
|
||||
const memo = await createMemo(page, `e2e-ai-ime-${Date.now()}`, "中文输入状态测试");
|
||||
let submittedBody: Record<string, unknown> | null = null;
|
||||
let generationRequestCount = 0;
|
||||
await page.route("**/api/v1/ai/prompts*", async (route) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 800));
|
||||
await route.continue();
|
||||
});
|
||||
await mockAiGeneration(page, "宋词结果", (body) => {
|
||||
generationRequestCount += 1;
|
||||
submittedBody = body;
|
||||
});
|
||||
}, 300);
|
||||
await ensureAuthenticatedPage(page);
|
||||
await page.getByRole("button", { name: new RegExp(notebookName) }).click();
|
||||
await page.locator(`[data-memo-id="${memo.id}"]`).locator("button").first().click();
|
||||
@@ -355,12 +359,31 @@ test.describe("AI custom prompts", () => {
|
||||
await textarea.fill("写个宋词");
|
||||
const generateButton = dialog.getByRole("button", { name: "生成", exact: true });
|
||||
await expect(generateButton).toBeEnabled();
|
||||
await generateButton.click();
|
||||
await expect(generateButton.locator("kbd")).toHaveText("Enter");
|
||||
|
||||
await textarea.press("Shift+Enter");
|
||||
await textarea.pressSequentially("不要参考原笔记");
|
||||
await expect(textarea).toHaveValue("写个宋词\n不要参考原笔记");
|
||||
|
||||
await textarea.evaluate((element) => {
|
||||
element.dispatchEvent(new KeyboardEvent("keydown", {
|
||||
bubbles: true,
|
||||
isComposing: true,
|
||||
key: "Enter",
|
||||
}));
|
||||
});
|
||||
expect(submittedBody).toBeNull();
|
||||
|
||||
await textarea.press("Enter");
|
||||
await expect.poll(() => generationRequestCount).toBe(1);
|
||||
await textarea.press("Enter");
|
||||
await page.waitForTimeout(50);
|
||||
expect(generationRequestCount).toBe(1);
|
||||
|
||||
await expect(dialog.getByText("宋词结果", { exact: true })).toBeVisible();
|
||||
expect(submittedBody).toMatchObject({
|
||||
action: "custom",
|
||||
instruction: "写个宋词",
|
||||
instruction: "写个宋词\n不要参考原笔记",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user