Re-add missing changes
This commit is contained in:
parent
fff0579a25
commit
a75fb02ed8
|
@ -7,9 +7,6 @@
|
|||
"": {
|
||||
"name": "chatgpt-web",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fullhuman/postcss-purgecss": "^5.0.0",
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
|
@ -3077,11 +3074,6 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
|
|
|
@ -39,8 +39,5 @@
|
|||
"tslib": "^2.5.0",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
}
|
||||
|
|
38
src/app.scss
38
src/app.scss
|
@ -2,6 +2,7 @@
|
|||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
@ -51,7 +52,7 @@ a.is-disabled {
|
|||
}
|
||||
|
||||
/* Swap the border on user messages to the other side */
|
||||
.user-message > .message-body {
|
||||
.user-message>.message-body {
|
||||
border-width: 0 4px 0 0 !important;
|
||||
}
|
||||
|
||||
|
@ -80,25 +81,32 @@ $modal-content-width: 1000px;
|
|||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
background-color: initial; /* Default color */
|
||||
background-color: initial;
|
||||
/* Default color */
|
||||
}
|
||||
|
||||
50% {
|
||||
background-color: $danger; /* Red */
|
||||
background-color: $danger;
|
||||
/* Red */
|
||||
}
|
||||
|
||||
100% {
|
||||
background-color: initial /* Default color */
|
||||
background-color: initial
|
||||
/* Default color */
|
||||
}
|
||||
}
|
||||
|
||||
/* Support for dark mode */
|
||||
$modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove this once a new version of bulma-prefers-dark is released
|
||||
@import "/node_modules/bulma-prefers-dark/build/bulma-prefers-dark.sass";
|
||||
.modal-card-body { // remove this once https: //github.com/jloh/bulma-prefers-dark/pull/90 is merged and released
|
||||
|
||||
.modal-card-body {
|
||||
// remove this once https: //github.com/jloh/bulma-prefers-dark/pull/90 is merged and released
|
||||
background-color: $background-dark;
|
||||
}
|
||||
|
||||
/* Support for copy code button */
|
||||
.code-block > button {
|
||||
.code-block>button {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
|
@ -110,26 +118,16 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
|
|||
top: 1rem;
|
||||
}
|
||||
|
||||
/* Delete button on side menu chat name */
|
||||
.menu-list {
|
||||
a:hover {
|
||||
.delete-btn {
|
||||
display: block;
|
||||
.delete-button {
|
||||
display: block !important;
|
||||
background-color: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
transform: translateY(-50%);
|
||||
margin-right: 5px;
|
||||
|
||||
}
|
||||
|
||||
/* Loading chat messages */
|
||||
.is-loading {
|
||||
opacity: 0.5;
|
||||
|
|
|
@ -1,86 +1,91 @@
|
|||
<script lang="ts">
|
||||
import { params, replace } from 'svelte-spa-router'
|
||||
import { params, replace } from 'svelte-spa-router'
|
||||
|
||||
import { apiKeyStorage, chatsStorage, clearChats, deleteChat } from './Storage.svelte'
|
||||
import { exportAsMarkdown } from './Export.svelte'
|
||||
import _ from 'lodash'
|
||||
$: sortedChats = $chatsStorage.sort((a, b) => b.id - a.id)
|
||||
import { apiKeyStorage, chatsStorage, clearChats, deleteChat } from './Storage.svelte'
|
||||
import { exportAsMarkdown } from './Export.svelte'
|
||||
|
||||
$: activeChatId = $params && $params.chatId ? parseInt($params.chatId) : undefined
|
||||
$: sortedChats = $chatsStorage.sort((a, b) => b.id - a.id)
|
||||
|
||||
function delChat (chatId) {
|
||||
if (activeChatId === chatId) {
|
||||
// switch to another chat if deleting the active one
|
||||
const newChatId = _.maxBy($chatsStorage.filter(chat => chat.id !== chatId), 'id')?.id
|
||||
if (!newChatId) return
|
||||
replace(`/chat/:${newChatId}`).then(() => deleteChat(chatId))
|
||||
$: activeChatId = $params && $params.chatId ? parseInt($params.chatId) : undefined
|
||||
|
||||
function delChat (chatId) {
|
||||
if (activeChatId === chatId) {
|
||||
// Find the max chatId other than the current one
|
||||
const newChatId = sortedChats.reduce((maxId, chat) => {
|
||||
if (chat.id === chatId) return maxId
|
||||
return Math.max(maxId, chat.id)
|
||||
}, 0)
|
||||
|
||||
if (!newChatId) {
|
||||
// No other chats, clear all and go to home
|
||||
replace('/').then(() => { deleteChat(chatId) })
|
||||
} else {
|
||||
deleteChat(chatId)
|
||||
// Delete the current chat and go to the max chatId
|
||||
replace(`/chat/${newChatId}`).then(() => { deleteChat(chatId) })
|
||||
}
|
||||
} else {
|
||||
deleteChat(chatId)
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<aside class="menu">
|
||||
<p class="menu-label">Chats</p>
|
||||
<ul class="menu-list">
|
||||
{#if sortedChats.length === 0}
|
||||
<li><a href={'#'} class="is-disabled">No chats yet...</a></li>
|
||||
{:else}
|
||||
<p class="menu-label">Chats</p>
|
||||
<ul class="menu-list">
|
||||
{#if sortedChats.length === 0}
|
||||
<li><a href={'#'} class="is-disabled">No chats yet...</a></li>
|
||||
{:else}
|
||||
<li>
|
||||
<ul>
|
||||
{#each sortedChats as chat}
|
||||
<li>
|
||||
<ul>
|
||||
{#each sortedChats as chat}
|
||||
<li>
|
||||
<a style="position: relative" href={`#/chat/${chat.id}`} class:is-disabled={!$apiKeyStorage} class:is-active={activeChatId === chat.id}
|
||||
>{chat.name || `Chat ${chat.id}`}
|
||||
<svg on:click={() => delChat(chat.id)} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="delete-btn">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
</a
|
||||
>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<a style="position: relative" href={`#/chat/${chat.id}`} class:is-disabled={!$apiKeyStorage} class:is-active={activeChatId === chat.id}>
|
||||
<a class="is-pulled-right is-hidden px-1 py-0 greyscale has-text-weight-bold delete-button" href={'$'} on:click|preventDefault={() => delChat(chat.id)}>🗑️</a>
|
||||
{chat.name || `Chat ${chat.id}`}
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
<p class="menu-label">Actions</p>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<a href={'#/'} class="panel-block" class:is-disabled={!$apiKeyStorage} class:is-active={!activeChatId}
|
||||
><span class="greyscale mr-2">🔑</span> API key</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href={'#/chat/new'} class="panel-block" class:is-disabled={!$apiKeyStorage}
|
||||
><span class="greyscale mr-2">➕</span> New chat</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a class="panel-block"
|
||||
href="{'#/'}"
|
||||
class:is-disabled={!$apiKeyStorage}
|
||||
on:click|preventDefault={() => {
|
||||
{/each}
|
||||
</ul>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
<p class="menu-label">Actions</p>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<a href={'#/'} class="panel-block" class:is-disabled={!$apiKeyStorage} class:is-active={!activeChatId}
|
||||
><span class="greyscale mr-2">🔑</span> API key</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href={'#/chat/new'} class="panel-block" class:is-disabled={!$apiKeyStorage}
|
||||
><span class="greyscale mr-2">➕</span> New chat</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a class="panel-block"
|
||||
href="{'#/'}"
|
||||
class:is-disabled={!$apiKeyStorage}
|
||||
on:click|preventDefault={() => {
|
||||
const confirmDelete = window.confirm('Are you sure you want to delete all your chats?')
|
||||
if (confirmDelete) {
|
||||
replace('#/').then(() => clearChats())
|
||||
}
|
||||
}}><span class="greyscale mr-2">🗑️</span> Clear chats</a
|
||||
>
|
||||
</li>
|
||||
{#if activeChatId}
|
||||
<li>
|
||||
<a
|
||||
href={'#/'}
|
||||
class="panel-block"
|
||||
class:is-disabled={!apiKeyStorage}
|
||||
on:click|preventDefault={() => {
|
||||
>
|
||||
</li>
|
||||
{#if activeChatId}
|
||||
<li>
|
||||
<a
|
||||
href={'#/'}
|
||||
class="panel-block"
|
||||
class:is-disabled={!apiKeyStorage}
|
||||
on:click|preventDefault={() => {
|
||||
if (activeChatId) {
|
||||
exportAsMarkdown(activeChatId)
|
||||
}
|
||||
}}><span class="greyscale mr-2">📥</span> Export chat</a
|
||||
>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
</aside>
|
||||
|
|
Loading…
Reference in New Issue