add button to to delete an individual chat.
This commit is contained in:
		
							parent
							
								
									4ee5d0e5f6
								
							
						
					
					
						commit
						8075585778
					
				| 
						 | 
					@ -7,6 +7,9 @@
 | 
				
			||||||
    "": {
 | 
					    "": {
 | 
				
			||||||
      "name": "chatgpt-web",
 | 
					      "name": "chatgpt-web",
 | 
				
			||||||
      "version": "0.0.0",
 | 
					      "version": "0.0.0",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "lodash": "^4.17.21"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "devDependencies": {
 | 
					      "devDependencies": {
 | 
				
			||||||
        "@fullhuman/postcss-purgecss": "^5.0.0",
 | 
					        "@fullhuman/postcss-purgecss": "^5.0.0",
 | 
				
			||||||
        "@microsoft/fetch-event-source": "^2.0.1",
 | 
					        "@microsoft/fetch-event-source": "^2.0.1",
 | 
				
			||||||
| 
						 | 
					@ -3074,6 +3077,11 @@
 | 
				
			||||||
        "url": "https://github.com/sponsors/sindresorhus"
 | 
					        "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": {
 | 
					    "node_modules/lodash.merge": {
 | 
				
			||||||
      "version": "4.6.2",
 | 
					      "version": "4.6.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,5 +39,8 @@
 | 
				
			||||||
    "tslib": "^2.5.0",
 | 
					    "tslib": "^2.5.0",
 | 
				
			||||||
    "typescript": "^5.0.2",
 | 
					    "typescript": "^5.0.2",
 | 
				
			||||||
    "vite": "^4.1.0"
 | 
					    "vite": "^4.1.0"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "lodash": "^4.17.21"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								src/app.scss
								
								
								
								
							
							
						
						
									
										22
									
								
								src/app.scss
								
								
								
								
							| 
						 | 
					@ -13,7 +13,7 @@
 | 
				
			||||||
  flex-grow: 1;
 | 
					  flex-grow: 1;
 | 
				
			||||||
  min-height: 100vh;
 | 
					  min-height: 100vh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  section.section{
 | 
					  section.section {
 | 
				
			||||||
    flex-grow: 1;
 | 
					    flex-grow: 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -110,6 +110,26 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
 | 
				
			||||||
  top: 1rem;
 | 
					  top: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.menu-list {
 | 
				
			||||||
 | 
					  a:hover {
 | 
				
			||||||
 | 
					    .delete-btn {
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.delete-btn {
 | 
				
			||||||
 | 
					  display: none;
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  width: 20px;
 | 
				
			||||||
 | 
					  height: 20px;
 | 
				
			||||||
 | 
					  top: 50%;
 | 
				
			||||||
 | 
					  right: 0;
 | 
				
			||||||
 | 
					  transform: translateY(-50%);
 | 
				
			||||||
 | 
					  margin-right: 5px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Loading chat messages */
 | 
					/* Loading chat messages */
 | 
				
			||||||
.is-loading {
 | 
					.is-loading {
 | 
				
			||||||
  opacity: 0.5;
 | 
					  opacity: 0.5;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,70 +1,85 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  import { params, replace } from 'svelte-spa-router'
 | 
					    import {params, replace} from 'svelte-spa-router'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  import { apiKeyStorage, chatsStorage, clearChats } from './Storage.svelte'
 | 
					    import {apiKeyStorage, chatsStorage, clearChats, deleteChat} from './Storage.svelte'
 | 
				
			||||||
  import { exportAsMarkdown } from './Export.svelte'
 | 
					    import {exportAsMarkdown} from './Export.svelte'
 | 
				
			||||||
 | 
					    import _ from 'lodash'
 | 
				
			||||||
 | 
					    $: sortedChats = $chatsStorage.sort((a, b) => b.id - a.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $: sortedChats = $chatsStorage.sort((a, b) => b.id - a.id)
 | 
					    $: activeChatId = $params && $params.chatId ? parseInt($params.chatId) : undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					        replace(`/chat/:${newChatId}`).then(() => deleteChat(chatId))
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        deleteChat(chatId)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $: activeChatId = $params && $params.chatId ? parseInt($params.chatId) : undefined
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<aside class="menu">
 | 
					<aside class="menu">
 | 
				
			||||||
  <p class="menu-label">Chats</p>
 | 
					    <p class="menu-label">Chats</p>
 | 
				
			||||||
  <ul class="menu-list">
 | 
					    <ul class="menu-list">
 | 
				
			||||||
    {#if sortedChats.length === 0}
 | 
					        {#if sortedChats.length === 0}
 | 
				
			||||||
      <li><a href={'#'} class="is-disabled">No chats yet...</a></li>
 | 
					            <li><a href={'#'} class="is-disabled">No chats yet...</a></li>
 | 
				
			||||||
    {:else}
 | 
					        {:else}
 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <ul>
 | 
					 | 
				
			||||||
          {#each sortedChats as chat}
 | 
					 | 
				
			||||||
            <li>
 | 
					            <li>
 | 
				
			||||||
              <a href={`#/chat/${chat.id}`} class:is-disabled={!$apiKeyStorage} class:is-active={activeChatId === chat.id}
 | 
					                <ul>
 | 
				
			||||||
                >{chat.name || `Chat ${chat.id}`}</a
 | 
					                    {#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>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
          {/each}
 | 
					        {/if}
 | 
				
			||||||
        </ul>
 | 
					    </ul>
 | 
				
			||||||
      </li>
 | 
					    <p class="menu-label">Actions</p>
 | 
				
			||||||
    {/if}
 | 
					    <ul class="menu-list">
 | 
				
			||||||
  </ul>
 | 
					        <li>
 | 
				
			||||||
  <p class="menu-label">Actions</p>
 | 
					            <a href={'#/'} class="panel-block" class:is-disabled={!$apiKeyStorage} class:is-active={!activeChatId}
 | 
				
			||||||
  <ul class="menu-list">
 | 
					            ><span class="greyscale mr-2">🔑</span> API key</a
 | 
				
			||||||
    <li>
 | 
					            >
 | 
				
			||||||
      <a href={'#/'} class="panel-block" class:is-disabled={!$apiKeyStorage} class:is-active={!activeChatId}
 | 
					        </li>
 | 
				
			||||||
        ><span class="greyscale mr-2">🔑</span> API key</a
 | 
					        <li>
 | 
				
			||||||
      >
 | 
					            <a href={'#/chat/new'} class="panel-block" class:is-disabled={!$apiKeyStorage}
 | 
				
			||||||
    </li>
 | 
					            ><span class="greyscale mr-2">➕</span> New chat</a
 | 
				
			||||||
    <li>
 | 
					            >
 | 
				
			||||||
      <a href={'#/chat/new'} class="panel-block" class:is-disabled={!$apiKeyStorage}
 | 
					        </li>
 | 
				
			||||||
        ><span class="greyscale mr-2">➕</span> New chat</a
 | 
					        <li>
 | 
				
			||||||
      >
 | 
					            <a class="panel-block"
 | 
				
			||||||
    </li>
 | 
					               href="{'#/'}"
 | 
				
			||||||
    <li>
 | 
					               class:is-disabled={!$apiKeyStorage}
 | 
				
			||||||
      <a class="panel-block"
 | 
					               on:click|preventDefault={() => {
 | 
				
			||||||
        href="{'#/'}"
 | 
					 | 
				
			||||||
        class:is-disabled={!$apiKeyStorage}
 | 
					 | 
				
			||||||
        on:click|preventDefault={() => {
 | 
					 | 
				
			||||||
          const confirmDelete = window.confirm('Are you sure you want to delete all your chats?')
 | 
					          const confirmDelete = window.confirm('Are you sure you want to delete all your chats?')
 | 
				
			||||||
          if (confirmDelete) {
 | 
					          if (confirmDelete) {
 | 
				
			||||||
            replace('#/').then(() => clearChats())
 | 
					            replace('#/').then(() => clearChats())
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }}><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={!apiKeyStorage}
 | 
					                        class:is-disabled={!apiKeyStorage}
 | 
				
			||||||
          on:click|preventDefault={() => {
 | 
					                        on:click|preventDefault={() => {
 | 
				
			||||||
            if (activeChatId) {
 | 
					            if (activeChatId) {
 | 
				
			||||||
              exportAsMarkdown(activeChatId)
 | 
					              exportAsMarkdown(activeChatId)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }}><span class="greyscale mr-2">📥</span> Export chat</a
 | 
					          }}><span class="greyscale mr-2">📥</span> Export chat</a
 | 
				
			||||||
        >
 | 
					                >
 | 
				
			||||||
      </li>
 | 
					            </li>
 | 
				
			||||||
    {/if}
 | 
					        {/if}
 | 
				
			||||||
  </ul>
 | 
					    </ul>
 | 
				
			||||||
</aside>
 | 
					</aside>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue