diff --git a/src/lang/en.ts b/src/lang/en.ts
index e775744f..edb42f29 100644
--- a/src/lang/en.ts
+++ b/src/lang/en.ts
@@ -1131,4 +1131,6 @@ export const languageEnglish = {
escapeOutput: "Escape Output",
claudeBatching: "Claude Batching",
claude1HourCaching: "Claude 1 Hour Caching",
+ folderNameInput: "Please input the new folder name",
+ folderRemoveLengthError: "To remove a folder, it must not contain any entries.",
}
diff --git a/src/lang/ko.ts b/src/lang/ko.ts
index 9bb8216f..560a5182 100644
--- a/src/lang/ko.ts
+++ b/src/lang/ko.ts
@@ -997,4 +997,6 @@ export const languageKorean = {
"promptInfoEmptyText": "저장된 프롬프트 텍스트가 없습니다.",
"escapeOutput": "출력 이스케이프",
"claudeBatching": "Claude 배칭",
+ "folderNameInput": "새 폴더 이름을 입력해주세요",
+ "folderRemoveLengthError": "폴더를 제거하려면 폴더가 비어 있어야 합니다.",
}
diff --git a/src/lib/Others/ChatList.svelte b/src/lib/Others/ChatList.svelte
index 9f27ac5a..e94bf26f 100644
--- a/src/lib/Others/ChatList.svelte
+++ b/src/lib/Others/ChatList.svelte
@@ -4,7 +4,7 @@
import { DBState } from 'src/ts/stores.svelte';
import { ReloadGUIPointer, selectedCharID } from "../../ts/stores.svelte";
- import { DownloadIcon, EditIcon, FolderUpIcon, PlusIcon, TrashIcon, XIcon } from "lucide-svelte";
+ import { DownloadIcon, EditIcon, HardDriveUploadIcon, PlusIcon, TrashIcon, XIcon } from "lucide-svelte";
import { exportChat, importChat } from "../../ts/characters";
import { findCharacterbyId } from "../../ts/util";
import TextInput from "../UI/GUI/TextInput.svelte";
@@ -93,7 +93,7 @@
+ }}>
diff --git a/src/lib/Setting/Pages/DisplaySettings.svelte b/src/lib/Setting/Pages/DisplaySettings.svelte
index 5d3ec6c1..50960cce 100644
--- a/src/lib/Setting/Pages/DisplaySettings.svelte
+++ b/src/lib/Setting/Pages/DisplaySettings.svelte
@@ -10,7 +10,7 @@
import OptionInput from "src/lib/UI/GUI/OptionInput.svelte";
import { updateAnimationSpeed } from "src/ts/gui/animation";
import { changeColorScheme, colorSchemeList, exportColorScheme, importColorScheme, updateColorScheme, updateTextThemeAndCSS } from "src/ts/gui/colorscheme";
- import { DownloadIcon, FolderUpIcon } from "lucide-svelte";
+ import { DownloadIcon, HardDriveUploadIcon } from "lucide-svelte";
import { guiSizeText, updateGuisize } from "src/ts/gui/guisize";
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
import ColorInput from "src/lib/UI/GUI/ColorInput.svelte";
@@ -143,7 +143,7 @@
diff --git a/src/lib/Setting/Pages/GlobalRegex.svelte b/src/lib/Setting/Pages/GlobalRegex.svelte
index 19fba73a..b63afc05 100644
--- a/src/lib/Setting/Pages/GlobalRegex.svelte
+++ b/src/lib/Setting/Pages/GlobalRegex.svelte
@@ -1,5 +1,5 @@
-
+
+
{#if value.mode !== 'child'}
-
{#if open}
+ {#if value.mode === 'folder'}
+
+
+
+
{
+ externalLoreBooks.push({
+ key: '',
+ comment: '',
+ content: '',
+ mode: 'normal',
+ insertorder: 100,
+ alwaysActive: true,
+ secondkey: '',
+ selective: false,
+ folder: value.key,
+ })
+ }}>
+
+
+
{
+ const name = await alertInput(language.folderNameInput)
+ value.comment = name ?? ''
+ }}>
+
+
+
+
+
+ {:else}
{language.name}
@@ -204,6 +265,7 @@
{/if}
+ {/if}
{/if}
diff --git a/src/lib/SideBars/LoreBook/LoreBookList.svelte b/src/lib/SideBars/LoreBook/LoreBookList.svelte
index f8417e73..0dde6eec 100644
--- a/src/lib/SideBars/LoreBook/LoreBookList.svelte
+++ b/src/lib/SideBars/LoreBook/LoreBookList.svelte
@@ -6,23 +6,26 @@
import Sortable from 'sortablejs/modular/sortable.core.esm.js';
import { onDestroy, onMount } from "svelte";
import { sleep, sortableOptions } from "src/ts/util";
+ import { v4 } from "uuid";
interface Props {
globalMode?: boolean;
submenu?: number;
lorePlus?: boolean;
externalLoreBooks?: loreBook[];
+ showFolder?: string
}
- let { globalMode = false, submenu = 0, lorePlus = false, externalLoreBooks = null }: Props = $props();
+ let { globalMode = false, submenu = 0, lorePlus = false, externalLoreBooks = null, showFolder = '' }: Props = $props();
let stb: Sortable = null
let ele: HTMLDivElement = $state()
let sorted = $state(0)
+ let idgroup = 'a' + v4() //make should it starts with alphabetic character
const createStb = () => {
stb = Sortable.create(ele, {
onEnd: async () => {
let idx:number[] = []
- ele.querySelectorAll('[data-risu-idx]').forEach((e, i) => {
+ ele.querySelectorAll(`[data-risu-idx][data-risu-idgroup=${idgroup}]`).forEach((e, i) => {
idx.push(parseInt(e.getAttribute('data-risu-idx')))
})
if(globalMode){
@@ -60,7 +63,7 @@
await sleep(1)
createStb()
},
- ...sortableOptions
+ ...sortableOptions,
})
}
onMount(createStb)
@@ -94,27 +97,23 @@
{#key sorted}
{#if globalMode}
- {#if DBState.db.loreBook[DBState.db.loreBookPage].data.length === 0}
-
No Lorebook
- {:else}
- {#each DBState.db.loreBook[DBState.db.loreBookPage].data as book, i}
-
{
- let lore = DBState.db.loreBook[DBState.db.loreBookPage].data
- lore.splice(i, 1)
- DBState.db.loreBook[DBState.db.loreBookPage].data = lore
- }} onOpen={onOpen} onClose={onClose}/>
- {/each}
- {/if}
+
{:else if externalLoreBooks}
{#if externalLoreBooks.length === 0}
No Lorebook
{:else}
{#each externalLoreBooks as book, i}
- {
- let lore = externalLoreBooks
- lore.splice(i, 1)
- externalLoreBooks = lore
- }} onOpen={onOpen} onClose={onClose}/>
+ {#if (!showFolder && !book.folder) || (showFolder === book.folder)}
+ {
+ let lore = externalLoreBooks
+ lore.splice(i, 1)
+ externalLoreBooks = lore
+ }} onOpen={onOpen} onClose={onClose} bind:externalLoreBooks={externalLoreBooks} />
+ {:else}
+
+ {/if}
{/each}
{/if}
{:else if submenu === 0}
@@ -122,11 +121,15 @@
No Lorebook
{:else}
{#each DBState.db.characters[$selectedCharID].globalLore as book, i}
- {
- let lore = DBState.db.characters[$selectedCharID].globalLore
- lore.splice(i, 1)
- DBState.db.characters[$selectedCharID].globalLore = lore
- }} onOpen={onOpen} onClose={onClose} lorePlus={lorePlus}/>
+ {#if (!showFolder && !book.folder) || (showFolder === book.folder)}
+ {
+ let lore = DBState.db.characters[$selectedCharID].globalLore
+ lore.splice(i, 1)
+ DBState.db.characters[$selectedCharID].globalLore = lore
+ }} onOpen={onOpen} onClose={onClose} lorePlus={lorePlus} bind:externalLoreBooks={DBState.db.characters[$selectedCharID].globalLore}/>
+ {:else}
+
+ {/if}
{/each}
{/if}
{:else if submenu === 1}
@@ -134,11 +137,15 @@
No Lorebook
{:else}
{#each DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].localLore as book, i}
- {
- let lore = DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].localLore
- lore.splice(i, 1)
- DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].localLore = lore
- }} onOpen={onOpen} onClose={onClose} lorePlus={lorePlus}/>
+ {#if (!showFolder && !book.folder) || (showFolder === book.folder)}
+ {
+ let lore = DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].localLore
+ lore.splice(i, 1)
+ DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].localLore = lore
+ }} onOpen={onOpen} onClose={onClose} lorePlus={lorePlus} bind:externalLoreBooks={DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].localLore}/>
+ {:else}
+
+ {/if}
{/each}
{/if}
{/if}
diff --git a/src/lib/SideBars/LoreBook/LoreBookSetting.svelte b/src/lib/SideBars/LoreBook/LoreBookSetting.svelte
index 3e5699d2..511bcc68 100644
--- a/src/lib/SideBars/LoreBook/LoreBookSetting.svelte
+++ b/src/lib/SideBars/LoreBook/LoreBookSetting.svelte
@@ -2,8 +2,8 @@
import { DBState } from 'src/ts/stores.svelte';
import { language } from "../../../lang";
- import { DownloadIcon, FolderUpIcon, ImportIcon, PlusIcon, SunIcon, LinkIcon } from "lucide-svelte";
- import { addLorebook, exportLoreBook, importLoreBook } from "../../../ts/process/lorebook.svelte";
+ import { DownloadIcon, HardDriveUploadIcon, ImportIcon, PlusIcon, SunIcon, LinkIcon, FolderPlusIcon } from "lucide-svelte";
+ import { addLorebook, addLorebookFolder, exportLoreBook, importLoreBook } from "../../../ts/process/lorebook.svelte";
import Check from "../../UI/GUI/CheckInput.svelte";
import NumberInput from "../../UI/GUI/NumberInput.svelte";
import LoreBookList from "./LoreBookList.svelte";
@@ -128,10 +128,15 @@
}} class="hover:text-textcolor ml-1 cursor-pointer">
+ {
+ addLorebookFolder(globalMode ? -1 : submenu)
+ }} class="hover:text-textcolor ml-2 cursor-pointer">
+
+
{
importLoreBook(globalMode ? 'sglobal' : submenu === 0 ? 'global' : 'local')
}} class="hover:text-textcolor ml-2 cursor-pointer">
-
+
{#if DBState.db.bulkEnabling}
{
diff --git a/src/lib/SideBars/Scripts/RegexList.svelte b/src/lib/SideBars/Scripts/RegexList.svelte
index 9ae67f8b..df854e53 100644
--- a/src/lib/SideBars/Scripts/RegexList.svelte
+++ b/src/lib/SideBars/Scripts/RegexList.svelte
@@ -4,7 +4,7 @@
import Sortable from "sortablejs";
import { sleep, sortableOptions } from "src/ts/util";
import { onDestroy, onMount } from "svelte";
- import { DownloadIcon, FolderUpIcon, PlusIcon } from "lucide-svelte";
+ import { DownloadIcon, HardDriveUploadIcon, PlusIcon } from "lucide-svelte";
import { exportRegex, importRegex } from "src/ts/process/scripts";
interface Props {
value?: customscript[];
@@ -95,6 +95,6 @@
}}>
{
value = await importRegex(value)
- }}>
+ }}>
{/if}
\ No newline at end of file
diff --git a/src/lib/SideBars/SideChatList.svelte b/src/lib/SideBars/SideChatList.svelte
index f3359c00..c2b671a2 100644
--- a/src/lib/SideBars/SideChatList.svelte
+++ b/src/lib/SideBars/SideChatList.svelte
@@ -2,7 +2,7 @@
import { onDestroy, onMount } from "svelte";
import { v4 } from "uuid";
import Sortable from 'sortablejs/modular/sortable.core.esm.js';
- import { DownloadIcon, PencilIcon, FolderUpIcon, MenuIcon, TrashIcon, GitBranchIcon, SplitIcon, FolderPlusIcon } from "lucide-svelte";
+ import { DownloadIcon, PencilIcon, HardDriveUploadIcon, MenuIcon, TrashIcon, GitBranchIcon, SplitIcon, FolderPlusIcon } from "lucide-svelte";
import type { Chat, ChatFolder, character, groupChat } from "src/ts/storage/database.svelte";
import { DBState } from 'src/ts/stores.svelte';
@@ -464,7 +464,7 @@
{
importChat()
}}>
-
+
{
editMode = !editMode
diff --git a/src/ts/process/lorebook.svelte.ts b/src/ts/process/lorebook.svelte.ts
index bbaf38bd..68ed8a38 100644
--- a/src/ts/process/lorebook.svelte.ts
+++ b/src/ts/process/lorebook.svelte.ts
@@ -10,6 +10,7 @@ import { downloadFile } from "../globalApi.svelte";
import { getModuleLorebooks } from "./modules";
import { CCardLib } from "@risuai/ccardlib";
import { getChatVar, setChatVar } from "../parser.svelte";
+import { v4 } from "uuid";
export function addLorebook(type:number) {
const selectedID = get(selectedCharID)
@@ -40,6 +41,36 @@ export function addLorebook(type:number) {
}
}
+export function addLorebookFolder(type:number) {
+ const selectedID = get(selectedCharID)
+ const id = v4()
+ if(type === 0){
+ DBState.db.characters[selectedID].globalLore.push({
+ key: '\uf000folder:' + id,
+ comment: `New Folder`,
+ content: '',
+ mode: 'folder',
+ insertorder: 100,
+ alwaysActive: false,
+ secondkey: "",
+ selective: false,
+ })
+ }
+ else{
+ const page = DBState.db.characters[selectedID].chatPage
+ DBState.db.characters[selectedID].chats[page].localLore.push({
+ key: '\uf000folder:' + id,
+ comment: `New Folder`,
+ content: '',
+ mode: 'folder',
+ insertorder: 100,
+ alwaysActive: false,
+ secondkey: "",
+ selective: false,
+ })
+ }
+}
+
export async function loadLoreBookV3Prompt(){
const selectedID = get(selectedCharID)
const char = DBState.db.characters[selectedID]
diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts
index 57d8384f..b453ffb0 100644
--- a/src/ts/storage/database.svelte.ts
+++ b/src/ts/storage/database.svelte.ts
@@ -1070,7 +1070,7 @@ export interface loreBook{
insertorder: number
comment: string
content: string
- mode: 'multiple'|'constant'|'normal'|'child',
+ mode: 'multiple'|'constant'|'normal'|'child'|'folder',
alwaysActive: boolean
selective:boolean
extentions?:{
@@ -1084,6 +1084,7 @@ export interface loreBook{
useRegex?:boolean
bookVersion?:number
id?:string
+ folder?:string
}
export interface character{