Merge pull request #46 from ssddanbrown/main
Added hash-based routing using svelte-spa-router
This commit is contained in:
commit
377272b89e
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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={() => {
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
Loading…
Reference in New Issue