Skip to content

Commit

Permalink
fix: add auto scroll on sessions (#119)
Browse files Browse the repository at this point in the history
Closes #13 
- As long as the AI model generates the reply, the screen scrolls
automatically.
- If the user scrolls up, then the auto scroll stops.
- If the user scrolls to the bottom of the screen, it starts scrolling
automatically again.

---------

Co-authored-by: Fernando Maclen <[email protected]>
  • Loading branch information
GregoMac1 and fmaclen authored Jul 29, 2024
1 parent 59e9eb6 commit 6d7e352
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/routes/sessions/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
let promptTextarea: HTMLTextAreaElement;
let isPromptFullscreen = false;
let shouldFocusTextarea = false;
let userScrolledUp = false;
const shouldConfirmDeletion = writable(false);
const currentSessionId = writable(data.id);
Expand All @@ -59,6 +60,8 @@
$: if ($settingsStore?.ollamaModel) session.model = $settingsStore.ollamaModel;
$: knowledge = knowledgeId ? loadKnowledge(knowledgeId) : null;
$: shouldFocusTextarea = !isPromptFullscreen;
$: if (messageWindow) messageWindow.addEventListener('scroll', handleScroll);
$: {
if (session?.id !== $currentSessionId) {
getModelsList();
Expand All @@ -75,6 +78,11 @@
}
}
function handleScroll() {
const { scrollTop, scrollHeight, clientHeight } = messageWindow;
userScrolledUp = scrollTop + clientHeight < scrollHeight;
}
async function handleSubmit() {
if (!prompt) return;
Expand Down Expand Up @@ -140,6 +148,7 @@
for await (const part of response) {
completion += part.message.content;
await scrollToBottom();
}
// After the completion save the session
Expand All @@ -158,6 +167,7 @@
completion = '';
promptCached = '';
shouldFocusTextarea = true;
await scrollToBottom();
} catch (error) {
const typedError = error instanceof Error ? error : new Error(String(error));
if (typedError.name === 'AbortError') return; // User aborted the request
Expand All @@ -181,7 +191,7 @@
}
async function scrollToBottom() {
if (!messageWindow) return;
if (!messageWindow || userScrolledUp) return;
await tick();
messageWindow.scrollTop = messageWindow.scrollHeight;
}
Expand Down
30 changes: 30 additions & 0 deletions tests/session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,36 @@ test.describe('Session', () => {
).not.toBeVisible();
});

test('auto scrolls to the bottom when a new message is received', async ({ page }) => {
const newSessionButton = page.getByTestId('new-session');
const articleLocator = page.locator('article');
const sessionHistory = page.locator('.session__history');

await page.goto('/');
await page.getByText('Sessions', { exact: true }).click();
await newSessionButton.click();
await expect(articleLocator).toHaveCount(0);

const initialScrollHeight = await sessionHistory.evaluate((el) => el.scrollHeight);
const initialClientHeight = await sessionHistory.evaluate((el) => el.clientHeight);
const initialScrollTop = await sessionHistory.evaluate((el) => el.scrollTop);

await page.getByLabel('Model').selectOption(MOCK_API_TAGS_RESPONSE.models[0].name);
await promptTextarea.fill('Who would win in a fight between Emma Watson and Jessica Alba?');
await mockCompletionResponse(page, MOCK_SESSION_1_RESPONSE_3);
await page.getByText('Run').click();

const finalScrollTop = await sessionHistory.evaluate((el) => el.scrollTop);
const finalScrollHeight = await sessionHistory.evaluate((el) => el.scrollHeight);
const finalClientHeight = await sessionHistory.evaluate((el) => el.clientHeight);

expect(finalScrollHeight).toBeGreaterThan(initialScrollHeight);
expect(finalClientHeight).toBe(initialClientHeight);
expect(finalScrollTop).toBeGreaterThan(initialScrollTop);

// TODO: Add assertions for the `userScrolledUp` behavior
});

test('handles errors when fetching models', async ({ page }) => {
await page.goto('/');
await page.getByText('Sessions', { exact: true }).click();
Expand Down

0 comments on commit 6d7e352

Please sign in to comment.