File size: 3,131 Bytes
cbb996c fe2328e 831f161 5da61b4 fe2328e 9405a81 831f161 fe2328e b7167b0 4dae10f fe2328e 4dae10f 1b66f8d 4dae10f fe2328e fc15a4c 1a14c61 67867a9 5da61b4 1a14c61 5da61b4 1a14c61 fe2328e 1a14c61 831f161 1a14c61 1bba900 1a14c61 fe2328e 1a14c61 fe2328e cbb996c cbe1258 1b66f8d 1c8195c 1b66f8d 4dae10f f91689a 4dae10f 1b66f8d fe2328e 1b66f8d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
<script lang="ts">
import { onDestroy } from "svelte";
import { goto, invalidate } from "$app/navigation";
import { page } from "$app/stores";
import "../styles/main.css";
import type { LayoutData } from "./$types";
import { base } from "$app/paths";
import { PUBLIC_ORIGIN } from "$env/static/public";
import { shareConversation } from "$lib/shareConversation";
import { UrlDependency } from "$lib/types/UrlDependency";
import { error } from "$lib/stores/errors";
import MobileNav from "$lib/components/MobileNav.svelte";
import NavMenu from "$lib/components/NavMenu.svelte";
import Toast from "$lib/components/Toast.svelte";
export let data: LayoutData;
let isNavOpen = false;
let errorToastTimeout: NodeJS.Timeout;
let currentError: string | null;
async function onError() {
// If a new different error comes, wait for the current error to hide first
if ($error && currentError && $error !== currentError) {
clearTimeout(errorToastTimeout);
currentError = null;
await new Promise((resolve) => setTimeout(resolve, 300));
}
currentError = $error;
errorToastTimeout = setTimeout(() => {
$error = null;
currentError = null;
}, 3000);
}
async function deleteConversation(id: string) {
try {
const res = await fetch(`${base}/conversation/${id}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
});
if (!res.ok) {
$error = "Error while deleting conversation, try again.";
return;
}
if ($page.params.id !== id) {
await invalidate(UrlDependency.ConversationList);
} else {
await goto(base || "/", { invalidateAll: true });
}
} catch (err) {
console.error(err);
$error = String(err);
}
}
onDestroy(() => {
clearTimeout(errorToastTimeout);
});
$: if ($error) onError();
</script>
<svelte:head>
<meta name="description" content="The first open source alternative to ChatGPT. 💪" />
<meta property="og:title" content="HuggingChat" />
<meta property="og:type" content="website" />
<meta property="og:url" content="{PUBLIC_ORIGIN || $page.url.origin}{base}" />
<meta property="og:image" content="{PUBLIC_ORIGIN || $page.url.origin}{base}/thumbnail.png" />
</svelte:head>
<div
class="grid h-full w-screen grid-cols-1 grid-rows-[auto,1fr] md:grid-rows-[1fr] md:grid-cols-[280px,1fr] overflow-hidden text-smd dark:text-gray-300"
>
<MobileNav
isOpen={isNavOpen}
on:toggle={(ev) => (isNavOpen = ev.detail)}
title={data.conversations.find((conv) => conv.id === $page.params.id)?.title}
>
<NavMenu
conversations={data.conversations}
on:shareConversation={(ev) => shareConversation(ev.detail.id, ev.detail.title)}
on:deleteConversation={(ev) => deleteConversation(ev.detail)}
/>
</MobileNav>
<nav class="max-md:hidden grid grid-rows-[auto,1fr,auto] grid-cols-1 max-h-screen">
<NavMenu
conversations={data.conversations}
on:shareConversation={(ev) => shareConversation(ev.detail.id, ev.detail.title)}
on:deleteConversation={(ev) => deleteConversation(ev.detail)}
/>
</nav>
{#if currentError}
<Toast message={currentError} />
{/if}
<slot />
</div>
|