diff --git a/src/lib/SideBars/SideChatList.svelte b/src/lib/SideBars/SideChatList.svelte index 3c2a454e..76dd6b57 100644 --- a/src/lib/SideBars/SideChatList.svelte +++ b/src/lib/SideBars/SideChatList.svelte @@ -1,55 +1,116 @@
- -
- {#key sorted} - {#each chara.chats as chat, i} - + +
+ {#if chara.chats.filter(chat => chat.folderId == chara.chatFolders[i].id).length == 0} + Empty +
+ {:else} + {#each chara.chats.filter(chat => chat.folderId == chara.chatFolders[i].id) as chat} +
-
{ - if(e.key === 'Enter'){ - e.currentTarget.click() - } - }} class="text-textcolor2 hover:text-green-500 mr-1 cursor-pointer" onclick={() => { - editMode = !editMode - }}> - -
-
{ - if(e.key === 'Enter'){ - e.currentTarget.click() - } - }} class="text-textcolor2 hover:text-green-500 mr-1 cursor-pointer" onclick={async (e) => { - e.stopPropagation() - exportChat(i) - }}> - -
-
{ - if(e.key === 'Enter'){ - e.currentTarget.click() - } - }} class="text-textcolor2 hover:text-green-500 cursor-pointer" onclick={async (e) => { - e.stopPropagation() - if(chara.chats.length === 1){ - alertError(language.errors.onlyOneChat) - return - } - const d = await alertConfirm(`${language.removeConfirm}${chat.name}`) - if(d){ - chara.chatPage = 0 - $ReloadGUIPointer += 1 - let chats = chara.chats - chats.splice(i, 1) - chara.chats = chats - } - }}> - + }} class="risu-chats flex items-center text-textcolor border-solid border-0 border-darkborderc p-2 cursor-pointer rounded-md"class:bg-selected={chara.chats.indexOf(chat) === chara.chatPage}> + {#if editMode} + + {:else} + {chat.name} + {/if} +
+
{ + if(e.key === 'Enter'){ + e.currentTarget.click() + } + }} class="text-textcolor2 hover:text-green-500 mr-1 cursor-pointer" onclick={async () => { + const option = await alertChatOptions() + switch(option){ + case 0:{ + const newChat = safeStructuredClone($state.snapshot(chara.chats[chara.chats.indexOf(chat)])) + newChat.name = `Copy of ${newChat.name}` + chara.chats.unshift(newChat) + chara.chatPage = 0 + chara.chats = chara.chats + break + } + case 1:{ + if(chat.bindedPersona){ + const confirm = await alertConfirm(language.doYouWantToUnbindCurrentPersona) + if(confirm){ + chat.bindedPersona = '' + alertNormal(language.personaUnbindedSuccess) + } + } + else{ + const confirm = await alertConfirm(language.doYouWantToBindCurrentPersona) + if(confirm){ + if(!DBState.db.personas[DBState.db.selectedPersona].id){ + DBState.db.personas[DBState.db.selectedPersona].id = v4() + } + chat.bindedPersona = DBState.db.personas[DBState.db.selectedPersona].id + console.log(DBState.db.personas[DBState.db.selectedPersona]) + alertNormal(language.personaBindedSuccess) + } + } + break + } + case 2:{ + chara.chatPage = chara.chats.indexOf(chat) + createMultiuserRoom() + } + } + }}> + +
+
{ + if(e.key === 'Enter'){ + e.currentTarget.click() + } + }} class="text-textcolor2 hover:text-green-500 mr-1 cursor-pointer" onclick={() => { + editMode = !editMode + }}> + +
+
{ + if(e.key === 'Enter'){ + e.currentTarget.click() + } + }} class="text-textcolor2 hover:text-green-500 mr-1 cursor-pointer" onclick={async (e) => { + e.stopPropagation() + exportChat(chara.chats.indexOf(chat)) + }}> + +
+
{ + if(e.key === 'Enter'){ + e.currentTarget.click() + } + }} class="text-textcolor2 hover:text-green-500 cursor-pointer" onclick={async (e) => { + e.stopPropagation() + if(chara.chats.length === 1){ + alertError(language.errors.onlyOneChat) + return + } + const d = await alertConfirm(`${language.removeConfirm}${chat.name}`) + if(d){ + chara.chatPage = 0 + $ReloadGUIPointer += 1 + let chats = chara.chats + chats.splice(chara.chats.indexOf(chat), 1) + chara.chats = chats + } + }}> + +
+
+ + {/each} + {/if}
- - {/each} - {/key} + {/each} +
+ +
+ {#each chara.chats as chat, i} + {#if chat.folderId == null} + + {/if} + {/each} +
- + {/key} +
+
- {#if DBState.db.characters[$selectedCharID]?.chaId !== '§playground'} - - + {#if DBState.db.characters[$selectedCharID]?.chaId !== '§playground'} {#if parseKeyValue(DBState.db.customPromptTemplateToggle + getModuleToggles()).length > 4}
@@ -268,10 +540,9 @@ {/if} {/if}
- {#if chara.type === 'group'} -
- -
+
+ +
{/if}
\ No newline at end of file diff --git a/src/ts/characters.ts b/src/ts/characters.ts index 8f68dc2d..30425706 100644 --- a/src/ts/characters.ts +++ b/src/ts/characters.ts @@ -32,7 +32,9 @@ export function createNewGroup(){ note: '', name: 'Chat 1', localLore: [] - }], chatPage: 0, + }], + chatFolders: [], + chatPage: 0, viewScreen: 'none', globalLore: [], characters: [], @@ -402,6 +404,11 @@ export async function importChat(){ return } + if(db.characters[selectedID].chatFolders + .filter(folder => folder.id === newChat.folderId).length === 0) { + newChat.folderId = null + } + db.characters[selectedID].chats.unshift(newChat) setDatabase(db) alertNormal(language.successImport) @@ -585,6 +592,7 @@ export function createBlankChar():character{ name: 'Chat 1', localLore: [] }], + chatFolders: [], chatPage: 0, emotionImages: [], bias: [], diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts index cb9846a4..ce509d4b 100644 --- a/src/ts/storage/database.svelte.ts +++ b/src/ts/storage/database.svelte.ts @@ -979,6 +979,7 @@ export interface character{ desc:string notes:string chats:Chat[] + chatFolders: ChatFolder[] chatPage: number viewScreen: 'emotion'|'none'|'imggen'|'vn', bias: [string, number][] @@ -1117,6 +1118,7 @@ export interface groupChat{ image?:string firstMessage:string chats:Chat[] + chatFolders: ChatFolder[] chatPage: number name:string viewScreen: 'single'|'multiple'|'none'|'emp', @@ -1324,6 +1326,14 @@ export interface Chat{ bindedPersona?:string fmIndex?:number hypaV3Data?:SerializableHypaV3Data + folderId?:string +} + +export interface ChatFolder{ + id:string + name?:string + color?:string + folded:boolean } export interface Message{ diff --git a/src/ts/util.ts b/src/ts/util.ts index 865fdfde..fc5267f6 100644 --- a/src/ts/util.ts +++ b/src/ts/util.ts @@ -1015,4 +1015,7 @@ export const sortableOptions = { delay: 300, // time in milliseconds to define when the sorting should start delayOnTouchOnly: true, filter: '.no-sort', + onMove: (event) => { + return event.related.className.indexOf('no-sort') === -1 + } } as const \ No newline at end of file