Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add page title #108

Merged
merged 9 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
11 changes: 11 additions & 0 deletions src/lib/components/PageTitle.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
export let title: string | string[] | undefined;
const SEPARATOR = ' • ';
$: formattedTitle = title
? (Array.isArray(title) ? title.join(SEPARATOR) : title) + SEPARATOR + 'Hollama'
: 'Hollama';
</script>

<svelte:element this={'title'}>
{formattedTitle}
</svelte:element>
5 changes: 5 additions & 0 deletions src/lib/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,8 @@ export function formatSessionMetadata(session: Session) {
subtitles.push(session.model);
return subtitles.join(' • ');
}

export function getSessionTitle(session: Session) {
const hasKnowledge = session.messages[0]?.knowledge;
return hasKnowledge ? session.messages[1]?.content : session.messages[0]?.content;
}
9 changes: 9 additions & 0 deletions src/lib/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,21 @@ export function deleteStoreItem<T extends { id: string }>(store: T[], id: string
return store.filter((s) => s.id !== id);
}

export function updatePageTitle(title: string | string[]) {
settingsStore.update((settings) => {
if (!settings) return settings;
settings.pageTitle = title;
return settings;
});
}

export const LOCAL_STORAGE_PREFIX = 'hollama';

export interface Settings {
ollamaServer: string | null;
ollamaModel: string | null;
ollamaModels: OllamaModel[];
pageTitle?: string | string[];
}

export enum StorageKey {
Expand Down
5 changes: 4 additions & 1 deletion src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import { Brain, MessageSquareText, Settings2, Sun, Moon } from 'lucide-svelte';

import '../app.pcss';
import { settingsStore } from '$lib/store';
import PageTitle from '$lib/components/PageTitle.svelte';

$: pathname = $page.url.pathname;
const SITEMAP = [
Expand All @@ -13,6 +15,7 @@
['/settings', 'Settings']
];

$: pageTitle = $settingsStore?.pageTitle;
let theme = 'light';

function toggleTheme() {
Expand All @@ -38,7 +41,7 @@
></script>
{/if}

<title>Hollama</title>
<PageTitle title={pageTitle} />
</svelte:head>

<div class="layout">
Expand Down
6 changes: 5 additions & 1 deletion src/routes/knowledge/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
import Section from '$lib/components/Section.svelte';
import EmptyMessage from '$lib/components/EmptyMessage.svelte';
import SectionListItem from '$lib/components/SectionListItem.svelte';
import { knowledgeStore } from '$lib/store';
import { knowledgeStore, updatePageTitle } from '$lib/store';
import { Sitemap } from '$lib/sitemap';
import RobotsNoIndex from '$lib/components/RobotsNoIndex.svelte';
import { formatTimestampToNow } from '$lib/utils';
import { page } from '$app/stores';

// This is necessary for the case in which user is viewing a knowledge and then clicks the Knowledge link at the sidebar
$: if ($page.url.pathname === '/knowledge') updatePageTitle('Knowledge');
</script>

<RobotsNoIndex />
Expand Down
2 changes: 2 additions & 0 deletions src/routes/knowledge/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import FieldInput from '$lib/components/FieldInput.svelte';
import ButtonDelete from '$lib/components/ButtonDelete.svelte';
import Metadata from '$lib/components/Metadata.svelte';
import { updatePageTitle } from '$lib/store';

export let data: PageData;

Expand All @@ -34,6 +35,7 @@
knowledge = loadKnowledge(data.id);
name = knowledge.name;
content = knowledge.content;
updatePageTitle([knowledge.name ? knowledge.name : 'New knowledge', 'Knowledge']);
});
</script>

Expand Down
11 changes: 7 additions & 4 deletions src/routes/sessions/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<script lang="ts">
import { sessionsStore } from '$lib/store';
import { sessionsStore, updatePageTitle } from '$lib/store';
import { Sitemap } from '$lib/sitemap';
import EmptyMessage from '$lib/components/EmptyMessage.svelte';
import Section from '$lib/components/Section.svelte';
import SectionListItem from '$lib/components/SectionListItem.svelte';
import RobotsNoIndex from '$lib/components/RobotsNoIndex.svelte';
import { formatSessionMetadata } from '$lib/sessions';
import { formatSessionMetadata, getSessionTitle } from '$lib/sessions';
import { page } from '$app/stores';

// This is necessary for the case in which user is viewing a session and then clicks the Sessions link at the sidebar
$: if ($page.url.pathname === '/sessions') updatePageTitle('Sessions');
</script>

<RobotsNoIndex />
Expand All @@ -14,11 +18,10 @@
<svelte:fragment slot="list-items">
{#if $sessionsStore && $sessionsStore.length > 0}
{#each $sessionsStore as session}
{@const hasKnowledge = session.messages[0].knowledge}
<SectionListItem
sitemap={Sitemap.SESSIONS}
id={session.id}
title={hasKnowledge ? session.messages[1].content : session.messages[0].content}
title={getSessionTitle(session)}
subtitle={formatSessionMetadata(session)}
/>
{/each}
Expand Down
15 changes: 10 additions & 5 deletions src/routes/sessions/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import { Brain, StopCircle, UnfoldVertical } from 'lucide-svelte';

import { loadKnowledge, type Knowledge } from '$lib/knowledge';
import { settingsStore, knowledgeStore } from '$lib/store';
import { settingsStore, knowledgeStore, updatePageTitle } from '$lib/store';
import { ollamaGenerate, type OllamaCompletionResponse } from '$lib/ollama';
import {
saveSession,
type Message,
type Session,
loadSession,
formatSessionMetadata
formatSessionMetadata,
getSessionTitle
} from '$lib/sessions';
import { generateNewUrl } from '$lib/components/ButtonNew';
import { Sitemap } from '$lib/sitemap';
Expand All @@ -30,13 +30,14 @@
import ButtonCopy from '$lib/components/ButtonCopy.svelte';
import ButtonDelete from '$lib/components/ButtonDelete.svelte';
import Metadata from '$lib/components/Metadata.svelte';
import { afterNavigate } from '$app/navigation';

export let data: PageData;

let messageWindow: HTMLElement;
let knowledgeId: string;
let knowledge: Knowledge | null;
let session: Session;
let session = loadSession(data.id);
let completion: string;
let abortController: AbortController;
let prompt: string;
Expand All @@ -47,7 +48,6 @@

const shouldConfirmDeletion = writable(false);

$: session = loadSession(data.id);
$: isNewSession = !session?.messages.length;
$: isLastMessageFromUser = session?.messages[session.messages.length - 1]?.role === 'user';
$: session && scrollToBottom();
Expand All @@ -62,6 +62,11 @@
}
});

afterNavigate(() => {
session = loadSession(data.id);
updatePageTitle(!session?.messages.length ? 'New session' : getSessionTitle(session));
});

async function scrollToBottom() {
if (!messageWindow) return;
await tick();
Expand Down
9 changes: 6 additions & 3 deletions src/routes/settings/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import FieldInput from '$lib/components/FieldInput.svelte';

import type { OllamaTagResponse } from '$lib/ollama';
import { LOCAL_STORAGE_PREFIX, settingsStore, StorageKey } from '$lib/store';
import { LOCAL_STORAGE_PREFIX, settingsStore, StorageKey, updatePageTitle } from '$lib/store';

export let ollamaURL: URL | null = null;

Expand All @@ -20,11 +20,12 @@
let ollamaModel = $settingsStore?.ollamaModel || '';
let ollamaTagResponse: OllamaTagResponse | null = null;

$: settingsStore.set({
$: settingsStore.update((settings) => ({
...settings,
ollamaServer,
ollamaModels: ollamaTagResponse?.models || [],
ollamaModel
});
}));
GregoMac1 marked this conversation as resolved.
Show resolved Hide resolved

async function getModelsList(): Promise<void> {
try {
Expand Down Expand Up @@ -52,6 +53,8 @@
}

onMount(async () => {
updatePageTitle('Settings');

// Get the current URL and set the default server
ollamaURL = new URL(window.location.href);
if (ollamaURL.port) {
Expand Down