Merge pull request #46 from ssddanbrown/main

Added hash-based routing using svelte-spa-router
This commit is contained in:
Niek van der Maas 2023-03-17 14:35:30 +01:00 committed by GitHub
commit 377272b89e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 78 additions and 52 deletions

22
package-lock.json generated
View File

@ -23,6 +23,7 @@
"svelte-highlight": "^7.2.0", "svelte-highlight": "^7.2.0",
"svelte-local-storage-store": "^0.4.0", "svelte-local-storage-store": "^0.4.0",
"svelte-markdown": "^0.2.3", "svelte-markdown": "^0.2.3",
"svelte-spa-router": "^3.3.0",
"tslib": "^2.5.0", "tslib": "^2.5.0",
"typescript": "^4.9.3", "typescript": "^4.9.3",
"vite": "^4.1.0" "vite": "^4.1.0"
@ -1211,6 +1212,15 @@
"node": ">=8.10.0" "node": ">=8.10.0"
} }
}, },
"node_modules/regexparam": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.1.tgz",
"integrity": "sha512-zRgSaYemnNYxUv+/5SeoHI0eJIgTL/A2pUtXUPLHQxUldagouJ9p+K6IbIZ/JiQuCEv2E2B1O11SjVQy3aMCkw==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.1", "version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@ -1581,6 +1591,18 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/svelte-spa-router": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/svelte-spa-router/-/svelte-spa-router-3.3.0.tgz",
"integrity": "sha512-cwRNe7cxD43sCvSfEeaKiNZg3FCizGxeMcf7CPiWRP3jKXjEma3vxyyuDtPOam6nWbVxl9TNM3hlE/i87ZlqcQ==",
"dev": true,
"dependencies": {
"regexparam": "2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/ItalyPaleAle"
}
},
"node_modules/to-regex-range": { "node_modules/to-regex-range": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",

View File

@ -26,6 +26,7 @@
"svelte-highlight": "^7.2.0", "svelte-highlight": "^7.2.0",
"svelte-local-storage-store": "^0.4.0", "svelte-local-storage-store": "^0.4.0",
"svelte-markdown": "^0.2.3", "svelte-markdown": "^0.2.3",
"svelte-spa-router": "^3.3.0",
"tslib": "^2.5.0", "tslib": "^2.5.0",
"typescript": "^4.9.3", "typescript": "^4.9.3",
"vite": "^4.1.0" "vite": "^4.1.0"

View File

@ -1,8 +1,9 @@
<script lang="ts"> <script lang="ts">
import Router, { location } from "svelte-spa-router";
import routes from "./routes";
import Navbar from "./lib/Navbar.svelte"; import Navbar from "./lib/Navbar.svelte";
import Sidebar from "./lib/Sidebar.svelte"; import Sidebar from "./lib/Sidebar.svelte";
import Home from "./lib/Home.svelte";
import Chat from "./lib/Chat.svelte";
import Footer from "./lib/Footer.svelte"; import Footer from "./lib/Footer.svelte";
import { apiKeyStorage, chatsStorage } from "./lib/Storage.svelte"; import { apiKeyStorage, chatsStorage } from "./lib/Storage.svelte";
@ -15,8 +16,6 @@
if (urlParams.has("key")) { if (urlParams.has("key")) {
apiKeyStorage.set(urlParams.get("key")!); apiKeyStorage.set(urlParams.get("key")!);
} }
let activeChatId: number;
</script> </script>
<Navbar /> <Navbar />
@ -25,14 +24,12 @@
<div class="container is-fullhd"> <div class="container is-fullhd">
<div class="columns"> <div class="columns">
<div class="column is-one-fifth"> <div class="column is-one-fifth">
<Sidebar bind:apiKey bind:sortedChats bind:activeChatId /> <Sidebar bind:apiKey bind:sortedChats />
</div> </div>
<div class="column is-four-fifths"> <div class="column is-four-fifths">
{#if activeChatId} {#key $location}
<Chat bind:chatId={activeChatId} /> <Router {routes} />
{:else} {/key}
<Home bind:activeChatId />
{/if}
</div> </div>
</div> </div>
</div> </div>

View File

@ -6,9 +6,11 @@
import Code from "./Code.svelte"; import Code from "./Code.svelte";
import { afterUpdate, onMount } from "svelte"; import { afterUpdate, onMount } from "svelte";
import { replace } from "svelte-spa-router";
import SvelteMarkdown from "svelte-markdown"; import SvelteMarkdown from "svelte-markdown";
export let chatId: number; export let params = { chatId: undefined };
let chatId: number = parseInt(params.chatId);
let updating: boolean = false; let updating: boolean = false;
let input: HTMLTextAreaElement; let input: HTMLTextAreaElement;
@ -229,8 +231,9 @@
const deleteChat = () => { const deleteChat = () => {
if (confirm("Are you sure you want to delete this chat?")) { if (confirm("Are you sure you want to delete this chat?")) {
replace("/").then(() => {
chatsStorage.update((chats) => chats.filter((chat) => chat.id !== chatId)); chatsStorage.update((chats) => chats.filter((chat) => chat.id !== chatId));
chatId = null; });
} }
}; };

View File

@ -2,8 +2,6 @@
import { addChat, apiKeyStorage } from "./Storage.svelte"; import { addChat, apiKeyStorage } from "./Storage.svelte";
$: apiKey = $apiKeyStorage; $: apiKey = $apiKeyStorage;
export let activeChatId: number;
</script> </script>
<article class="message"> <article class="message">
@ -54,12 +52,7 @@
<article class="message is-info"> <article class="message is-info">
<div class="message-body"> <div class="message-body">
Select an existing chat on the sidebar, or Select an existing chat on the sidebar, or
<a <a href={"#/chat/new"}>create a new chat</a>
href={"#"}
on:click|preventDefault={() => {
activeChatId = addChat();
}}>create a new chat</a
>
</div> </div>
</article> </article>
{/if} {/if}

View File

@ -4,7 +4,7 @@
<nav class="navbar" aria-label="main navigation"> <nav class="navbar" aria-label="main navigation">
<div class="navbar-brand"> <div class="navbar-brand">
<a class="navbar-item" href={"#"} on:click|preventDefault={() => (window.location = window.location)}> <a class="navbar-item" href={"#/"}>
<img src={logo} alt="ChatGPT-web" width="28" height="28" /> <img src={logo} alt="ChatGPT-web" width="28" height="28" />
<p class="ml-2 is-size-4 has-text-weight-bold">ChatGPT-web</p> <p class="ml-2 is-size-4 has-text-weight-bold">ChatGPT-web</p>
</a> </a>

8
src/lib/NewChat.svelte Normal file
View File

@ -0,0 +1,8 @@
<script lang="ts">
import { addChat } from "./Storage.svelte";
import { replace } from 'svelte-spa-router'
// Create the new chat instance then redirect to it
const chatId = addChat();
replace(`/chat/${chatId}`);
</script>

View File

@ -1,11 +1,14 @@
<script lang="ts"> <script lang="ts">
import { addChat, clearChats } from "./Storage.svelte"; import { params, replace } from "svelte-spa-router";
import { clearChats } from "./Storage.svelte";
import { exportAsMarkdown } from "./Export.svelte"; import { exportAsMarkdown } from "./Export.svelte";
import type { Chat } from "./Types.svelte"; import type { Chat } from "./Types.svelte";
export let activeChatId: number;
export let sortedChats: Chat[]; export let sortedChats: Chat[];
export let apiKey: string; export let apiKey: string;
$: activeChatId = $params && $params.chatId ? parseInt($params.chatId) : undefined;
</script> </script>
<aside class="menu"> <aside class="menu">
@ -18,11 +21,8 @@
<ul> <ul>
{#each sortedChats as chat} {#each sortedChats as chat}
<li> <li>
<a <a href={`#/chat/${chat.id}`} class:is-disabled={!apiKey} class:is-active={activeChatId === chat.id}
href={"#"} >{chat.name || `Chat ${chat.id}`}</a
class:is-disabled={!apiKey}
class:is-active={activeChatId === chat.id}
on:click|preventDefault={() => (activeChatId = chat.id)}>{chat.name || `Chat ${chat.id}`}</a
> >
</li> </li>
{/each} {/each}
@ -33,41 +33,31 @@
<p class="menu-label">Actions</p> <p class="menu-label">Actions</p>
<ul class="menu-list"> <ul class="menu-list">
<li> <li>
<a <a href={"#/"} class="panel-block" class:is-disabled={!apiKey} class:is-active={!activeChatId}
href={"#"} ><span class="greyscale mr-2">🔑</span> API key</a
class="panel-block" >
class:is-disabled={!apiKey} </li>
class:is-active={!activeChatId} <li>
on:click|preventDefault={() => { <a href={"#/chat/new"} class="panel-block" class:is-disabled={!apiKey}
activeChatId = null; ><span class="greyscale mr-2"></span> New chat</a
}}><span class="greyscale mr-2">🔑</span> API key</a
> >
</li> </li>
<li> <li>
<a <a
href={"#"} href={"#/"}
class="panel-block" class="panel-block"
class:is-disabled={!apiKey} class:is-disabled={!apiKey}
on:click|preventDefault={() => { on:click={() => {
activeChatId = addChat(); replace("#/").then(() => {
}}><span class="greyscale mr-2"></span> New chat</a
>
</li>
<li>
<a
href={"#"}
class="panel-block"
class:is-disabled={!apiKey}
on:click|preventDefault={() => {
clearChats(); clearChats();
activeChatId = null; });
}}><span class="greyscale mr-2">🗑️</span> Clear chats</a }}><span class="greyscale mr-2">🗑️</span> Clear chats</a
> >
</li> </li>
{#if activeChatId} {#if activeChatId}
<li> <li>
<a <a
href={"#"} href={"#/"}
class="panel-block" class="panel-block"
class:is-disabled={!apiKey} class:is-disabled={!apiKey}
on:click|preventDefault={() => { on:click|preventDefault={() => {

12
src/routes.ts Normal file
View File

@ -0,0 +1,12 @@
import Home from "./lib/Home.svelte";
import Chat from "./lib/Chat.svelte";
import NewChat from "./lib/NewChat.svelte";
export default {
'/': Home,
'/chat/new': NewChat,
'/chat/:chatId': Chat,
'*': Home,
};