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?")) {
 | 
				
			||||||
      chatsStorage.update((chats) => chats.filter((chat) => chat.id !== chatId));
 | 
					      replace("/").then(() => {
 | 
				
			||||||
      chatId = null;
 | 
					        chatsStorage.update((chats) => chats.filter((chat) => chat.id !== chatId));
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					            clearChats();
 | 
				
			||||||
      >
 | 
					          });
 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
    <li>
 | 
					 | 
				
			||||||
      <a
 | 
					 | 
				
			||||||
        href={"#"}
 | 
					 | 
				
			||||||
        class="panel-block"
 | 
					 | 
				
			||||||
        class:is-disabled={!apiKey}
 | 
					 | 
				
			||||||
        on:click|preventDefault={() => {
 | 
					 | 
				
			||||||
          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