refac: folders

This commit is contained in:
Timothy Jaeryang Baek 2025-09-15 18:33:57 -05:00
parent 3f27d9ada1
commit 3ec1efb6e0
6 changed files with 138 additions and 131 deletions

View file

@ -432,15 +432,17 @@
{/if} {/if}
{:else} {:else}
<div <div
class="sticky {stickyButtonsClassName} left-0 right-0 py-2 pr-3 flex items-center justify-between w-full z-10 text-xs text-black dark:text-white" class="absolute left-0 right-0 py-2.5 pr-3 text-text-300 pl-4.5 text-xs font-medium dark:text-white"
> >
<div class="text-text-300 pl-4.5 text-xs font-medium dark:text-white">
{lang} {lang}
</div> </div>
<div
class="sticky {stickyButtonsClassName} left-0 right-0 py-2 pr-3 flex items-center justify-end w-full z-10 text-xs text-black dark:text-white"
>
<div class="flex items-center gap-0.5"> <div class="flex items-center gap-0.5">
<button <button
class="flex gap-1 items-center bg-none border-none transition rounded-md px-1.5 py-0.5" class="flex gap-1 items-center bg-none border-none transition rounded-md px-1.5 py-0.5 bg-white dark:bg-black"
on:click={collapseCodeBlock} on:click={collapseCodeBlock}
> >
<div class=" -translate-y-[0.5px]"> <div class=" -translate-y-[0.5px]">
@ -454,12 +456,14 @@
{#if ($config?.features?.enable_code_execution ?? true) && (lang.toLowerCase() === 'python' || lang.toLowerCase() === 'py' || (lang === '' && checkPythonCode(code)))} {#if ($config?.features?.enable_code_execution ?? true) && (lang.toLowerCase() === 'python' || lang.toLowerCase() === 'py' || (lang === '' && checkPythonCode(code)))}
{#if executing} {#if executing}
<div class="run-code-button bg-none border-none p-0.5 cursor-not-allowed"> <div
class="run-code-button bg-none border-none p-0.5 cursor-not-allowed bg-white dark:bg-black"
>
{$i18n.t('Running')} {$i18n.t('Running')}
</div> </div>
{:else if run} {:else if run}
<button <button
class="flex gap-1 items-center run-code-button bg-none border-none transition rounded-md px-1.5 py-0.5" class="flex gap-1 items-center run-code-button bg-none border-none transition rounded-md px-1.5 py-0.5 bg-white dark:bg-black"
on:click={async () => { on:click={async () => {
code = _code; code = _code;
await tick(); await tick();
@ -475,7 +479,7 @@
{#if save} {#if save}
<button <button
class="save-code-button bg-none border-none transition rounded-md px-1.5 py-0.5" class="save-code-button bg-none border-none transition rounded-md px-1.5 py-0.5 bg-white dark:bg-black"
on:click={saveCode} on:click={saveCode}
> >
{saved ? $i18n.t('Saved') : $i18n.t('Save')} {saved ? $i18n.t('Saved') : $i18n.t('Save')}
@ -483,13 +487,13 @@
{/if} {/if}
<button <button
class="copy-code-button bg-none border-none transition rounded-md px-1.5 py-0.5" class="copy-code-button bg-none border-none transition rounded-md px-1.5 py-0.5 bg-white dark:bg-black"
on:click={copyCode}>{copied ? $i18n.t('Copied') : $i18n.t('Copy')}</button on:click={copyCode}>{copied ? $i18n.t('Copied') : $i18n.t('Copy')}</button
> >
{#if preview && ['html', 'svg'].includes(lang)} {#if preview && ['html', 'svg'].includes(lang)}
<button <button
class="flex gap-1 items-center run-code-button bg-none border-none transition rounded-md px-1.5 py-0.5" class="flex gap-1 items-center run-code-button bg-none border-none transition rounded-md px-1.5 py-0.5 bg-white dark:bg-black"
on:click={previewCode} on:click={previewCode}
> >
<div> <div>

View file

@ -109,7 +109,7 @@
{save} {save}
{preview} {preview}
edit={editCodeBlock} edit={editCodeBlock}
stickyButtonsClassName={topPadding ? 'top-6' : 'top-0'} stickyButtonsClassName={topPadding ? 'top-7' : 'top-0'}
onSave={(value) => { onSave={(value) => {
onSave({ onSave({
raw: token.raw, raw: token.raw,

View file

@ -72,7 +72,7 @@
<nav class="sticky top-0 z-30 w-full py-1 -mb-8 flex flex-col items-center drag-region"> <nav class="sticky top-0 z-30 w-full py-1 -mb-8 flex flex-col items-center drag-region">
<div class="flex items-center w-full pl-1.5 pr-1"> <div class="flex items-center w-full pl-1.5 pr-1">
<div <div
class=" bg-linear-to-b via-40% from-white via-white to-transparent dark:from-gray-900 dark:via-gray-900 dark:to-transparent pointer-events-none absolute inset-0 -bottom-7 z-[-1]" class=" bg-linear-to-b via-40% to-97% from-white via-white to-transparent dark:from-gray-900 dark:via-gray-900 dark:to-transparent pointer-events-none absolute inset-0 -bottom-7 z-[-1]"
></div> ></div>
<div class=" flex max-w-full w-full mx-auto px-1.5 md:px-2 pt-0.5 bg-transparent"> <div class=" flex max-w-full w-full mx-auto px-1.5 md:px-2 pt-0.5 bg-transparent">

View file

@ -16,14 +16,15 @@
export let name = ''; export let name = '';
export let collapsible = true; export let collapsible = true;
export let className = '';
export let buttonClassName = 'text-gray-600 dark:text-gray-400';
export let chevron = true; export let chevron = true;
export let onAddLabel: string = ''; export let onAddLabel: string = '';
export let onAdd: null | Function = null; export let onAdd: null | Function = null;
export let dragAndDrop = true; export let dragAndDrop = true;
export let className = '';
let folderElement; let folderElement;
let draggedOver = false; let draggedOver = false;
@ -138,20 +139,20 @@
> >
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div <div
class="w-full group rounded-lg relative flex items-center justify-between hover:bg-gray-100 dark:hover:bg-gray-900 text-gray-500 dark:text-gray-500 transition" class="w-full group rounded-lg relative flex items-center justify-between hover:bg-gray-100 dark:hover:bg-gray-900 transition {buttonClassName}"
> >
<button class="w-full py-1.5 pl-2 flex items-center gap-1.5 text-xs font-medium"> <button class="w-full py-1.5 pl-2 flex items-center gap-1.5 text-xs font-medium">
{#if chevron} {#if chevron}
<div class="text-gray-300 dark:text-gray-600 p-[1px]"> <div class=" p-[1px]">
{#if open} {#if open}
<ChevronDown className=" size-3.5" strokeWidth="2.5" /> <ChevronDown className=" size-3" strokeWidth="2" />
{:else} {:else}
<ChevronRight className=" size-3.5" strokeWidth="2.5" /> <ChevronRight className=" size-3" strokeWidth="2" />
{/if} {/if}
</div> </div>
{/if} {/if}
<div class="translate-y-[0.5px]"> <div class="translate-y-[0.5px] {chevron ? '' : 'pl-1'}">
{name} {name}
</div> </div>
</button> </button>

View file

@ -871,14 +871,42 @@
</Folder> </Folder>
{/if} {/if}
{#if folders}
<Folder <Folder
className="px-2 mt-0.5" className="px-2 mt-0.5"
name={$i18n.t('Chats')} name={$i18n.t('Folders')}
chevron={false} chevron={false}
dragAndDrop={false}
onAdd={() => { onAdd={() => {
showCreateFolderModal = true; showCreateFolderModal = true;
}} }}
onAddLabel={$i18n.t('New Folder')} onAddLabel={$i18n.t('New Folder')}
>
<Folders
{folders}
{shiftKey}
onDelete={(folderId) => {
selectedFolder.set(null);
initChatList();
}}
on:update={() => {
initChatList();
}}
on:import={(e) => {
const { folderId, items } = e.detail;
importChatHandler(items, false, folderId);
}}
on:change={async () => {
initChatList();
}}
/>
</Folder>
{/if}
<Folder
className="px-2 mt-0.5"
name={$i18n.t('Chats')}
chevron={false}
on:change={async (e) => { on:change={async (e) => {
selectedFolder.set(null); selectedFolder.set(null);
await goto('/'); await goto('/');
@ -940,33 +968,11 @@
} }
}} }}
> >
{#if folders || $pinnedChats.length > 0}
<div class="mb-1">
{#if folders}
<Folders
{folders}
{shiftKey}
onDelete={(folderId) => {
selectedFolder.set(null);
initChatList();
}}
on:update={() => {
initChatList();
}}
on:import={(e) => {
const { folderId, items } = e.detail;
importChatHandler(items, false, folderId);
}}
on:change={async () => {
initChatList();
}}
/>
{/if}
{#if $pinnedChats.length > 0} {#if $pinnedChats.length > 0}
<div class="mb-1">
<div class="flex flex-col space-y-1 rounded-xl"> <div class="flex flex-col space-y-1 rounded-xl">
<Folder <Folder
className="" buttonClassName=" text-gray-500"
bind:open={showPinnedChat} bind:open={showPinnedChat}
on:change={(e) => { on:change={(e) => {
localStorage.setItem('showPinnedChat', e.detail); localStorage.setItem('showPinnedChat', e.detail);
@ -1008,10 +1014,7 @@
} }
if (!chat.pinned) { if (!chat.pinned) {
const res = await toggleChatPinnedStatusById( const res = await toggleChatPinnedStatusById(localStorage.token, chat.id);
localStorage.token,
chat.id
);
} }
initChatList(); initChatList();
@ -1021,7 +1024,7 @@
name={$i18n.t('Pinned')} name={$i18n.t('Pinned')}
> >
<div <div
class="ml-3 pl-1 mt-[1px] flex flex-col overflow-y-auto scrollbar-hidden border-s border-gray-100 dark:border-gray-900" class="ml-3 pl-1 mt-[1px] flex flex-col overflow-y-auto scrollbar-hidden border-s border-gray-100 dark:border-gray-900 text-gray-900 dark:text-gray-200"
> >
{#each $pinnedChats as chat, idx (`pinned-chat-${chat?.id ?? idx}`)} {#each $pinnedChats as chat, idx (`pinned-chat-${chat?.id ?? idx}`)}
<ChatItem <ChatItem
@ -1048,7 +1051,6 @@
</div> </div>
</Folder> </Folder>
</div> </div>
{/if}
</div> </div>
{/if} {/if}

View file

@ -464,7 +464,7 @@
}} }}
> >
<button <button
class="text-gray-500 dark:text-gray-500 transition-all p-[3px] hover:bg-gray-200 dark:hover:bg-gray-850 rounded-lg" class="text-gray-500 dark:text-gray-500 transition-all p-1 hover:bg-gray-200 dark:hover:bg-gray-850 rounded-lg"
on:click={(e) => { on:click={(e) => {
e.stopPropagation(); e.stopPropagation();
open = !open; open = !open;
@ -472,22 +472,22 @@
> >
{#if folders[folderId]?.meta?.icon} {#if folders[folderId]?.meta?.icon}
<div class="flex group-hover:hidden transition-all"> <div class="flex group-hover:hidden transition-all">
<Emoji className="size-4" shortCode={folders[folderId].meta.icon} /> <Emoji className="size-3.5" shortCode={folders[folderId].meta.icon} />
</div> </div>
<div class="hidden group-hover:flex transition-all p-[1px]"> <div class="hidden group-hover:flex transition-all p-[1px]">
{#if open} {#if open}
<ChevronDown className=" size-3.5" strokeWidth="2.5" /> <ChevronDown className=" size-3" strokeWidth="2.5" />
{:else} {:else}
<ChevronRight className=" size-3.5" strokeWidth="2.5" /> <ChevronRight className=" size-3" strokeWidth="2.5" />
{/if} {/if}
</div> </div>
{:else} {:else}
<div class="p-[1px]"> <div class="p-[1px]">
{#if open} {#if open}
<ChevronDown className=" size-3.5" strokeWidth="2.5" /> <ChevronDown className=" size-3" strokeWidth="2.5" />
{:else} {:else}
<ChevronRight className=" size-3.5" strokeWidth="2.5" /> <ChevronRight className=" size-3" strokeWidth="2.5" />
{/if} {/if}
</div> </div>
{/if} {/if}