diff --git a/src/lang/en.ts b/src/lang/en.ts
index 5800ca0d..d6a87022 100644
--- a/src/lang/en.ts
+++ b/src/lang/en.ts
@@ -595,4 +595,8 @@ export const languageEnglish = {
dynamicAssets: "Dynamic Assets",
dynamicAssetsEditDisplay: "Use Dynamic Assets in Display",
longTermMemory: "Long Term Memory",
+ grid: "Grid",
+ list: "List",
+ trash: "Trash",
+ trashDesc: "Deleted characters are moved to trash. you can restore or delete them permanently. deleted characters are automatically purged after 3 days.",
}
\ No newline at end of file
diff --git a/src/lib/Others/GridCatalog.svelte b/src/lib/Others/GridCatalog.svelte
index 258592ec..72c68be9 100644
--- a/src/lib/Others/GridCatalog.svelte
+++ b/src/lib/Others/GridCatalog.svelte
@@ -1,12 +1,17 @@
-
-
Catalog
-
-
-
- {#each formatChars(search) as char}
-
- {#if char.image}
- {changeChar(char.index)}} additionalStyle={getCharImage(char.image, 'css')}>
- {:else}
- {changeChar(char.index)}} additionalStyle={char.index === $selectedCharID ? 'background:var(--risu-theme-selected)' : ''}>
- {#if char.type === 'group'}
-
- {:else}
-
- {/if}
-
- {/if}
-
- {/each}
+
+
+
+ Catalog
+
+
+
+
+
+
+
+ {#if selected === 0}
+
+
+ {#each formatChars(search, $DataBase) as char}
+
+ {#if char.image}
+ {changeChar(char.index)}} additionalStyle={getCharImage(char.image, 'css')}>
+ {:else}
+ {changeChar(char.index)}} additionalStyle={char.index === $selectedCharID ? 'background:var(--risu-theme-selected)' : ''}>
+ {#if char.type === 'group'}
+
+ {:else}
+
+ {/if}
+
+ {/if}
+
+ {/each}
+
+
+ {:else if selected === 1}
+ {#each formatChars(search, $DataBase) as char}
+
+
{changeChar(char.index)}} additionalStyle={getCharImage(char.image, 'css')}>
+
+
{char.name || "Unnamed"}
+
{parseMultilangString(char.desc)['en'] || parseMultilangString(char.desc)['xx'] || 'No description'}
+
+
+
+
+
+
+ {/each}
+ {:else if selected === 2}
+
{language.trashDesc}
+ {#each formatChars(search, $DataBase, true) as char}
+
+
{changeChar(char.index)}} additionalStyle={getCharImage(char.image, 'css')}>
+
+
{char.name || "Unnamed"}
+
{parseMultilangString(char.desc)['en'] || parseMultilangString(char.desc)['xx'] || 'No description'}
+
+
+
+
+
+
+ {/each}
+ {/if}
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte
index dfb9244e..5bebdd00 100644
--- a/src/lib/SideBars/CharConfig.svelte
+++ b/src/lib/SideBars/CharConfig.svelte
@@ -5,7 +5,7 @@
import { selectedCharID } from "../../ts/stores";
import { PlusIcon, SmileIcon, TrashIcon, UserIcon, ActivityIcon, BookIcon, User, CurlyBraces, Volume2Icon } from 'lucide-svelte'
import Check from "../UI/GUI/CheckInput.svelte";
- import { addCharEmotion, addingEmotion, getCharImage, rmCharEmotion, selectCharImg, makeGroupImage } from "../../ts/characters";
+ import { addCharEmotion, addingEmotion, getCharImage, rmCharEmotion, selectCharImg, makeGroupImage, removeChar } from "../../ts/characters";
import LoreBook from "./LoreBook/LoreBookSetting.svelte";
import { alertConfirm, alertNormal, alertSelectChar, alertTOS, showHypaV2Alert } from "../../ts/alert";
import BarIcon from "./BarIcon.svelte";
@@ -874,20 +874,7 @@
{/if}
{/if}
{/if}
diff --git a/src/ts/characters.ts b/src/ts/characters.ts
index c319d647..fed8b0b8 100644
--- a/src/ts/characters.ts
+++ b/src/ts/characters.ts
@@ -1,6 +1,6 @@
import { get, writable } from "svelte/store";
import { DataBase, saveImage, setDatabase, type character, type Chat, defaultSdDataFunc } from "./storage/database";
-import { alertError, alertNormal, alertSelect, alertStore } from "./alert";
+import { alertConfirm, alertError, alertNormal, alertSelect, alertStore } from "./alert";
import { language } from "../lang";
import { decode as decodeMsgpack } from "msgpackr";
import { checkNullish, findCharacterbyId, selectMultipleFile, selectSingleFile, sleep } from "./util";
@@ -508,4 +508,29 @@ export async function addDefaultCharacters() {
type: 'none',
msg: ''
})
+}
+
+export async function removeChar(index:number,name:string, type:'normal'|'permanent'|'permanentForce' = 'normal'){
+ const db = get(DataBase)
+ if(type !== 'permanentForce'){
+ const conf = await alertConfirm(language.removeConfirm + name)
+ if(!conf){
+ return
+ }
+ const conf2 = await alertConfirm(language.removeConfirm2 + name)
+ if(!conf2){
+ return
+ }
+ }
+ let chars = db.characters
+ if(type === 'normal'){
+ chars[index].trashTime = Date.now()
+ }
+ else{
+ chars.splice(index, 1)
+ }
+ checkCharOrder()
+ db.characters = chars
+ setDatabase(db)
+ selectedCharID.set(-1)
}
\ No newline at end of file
diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts
index 387c8678..2d3eeb77 100644
--- a/src/ts/storage/database.ts
+++ b/src/ts/storage/database.ts
@@ -772,6 +772,7 @@ export interface character{
vits?: OnnxModelFiles
realmId?:string
imported?:boolean
+ trashTime?:number
}
@@ -815,6 +816,7 @@ export interface groupChat{
oneAtTime?:boolean
virtualscript?:string
lorePlus?:boolean
+ trashTime?:number
}
export interface botPreset{
diff --git a/src/ts/storage/globalApi.ts b/src/ts/storage/globalApi.ts
index 89cf642d..e98386c0 100644
--- a/src/ts/storage/globalApi.ts
+++ b/src/ts/storage/globalApi.ts
@@ -977,6 +977,14 @@ async function checkNewFormat() {
if(db.mainPrompt === oldJailbreak){
db.mainPrompt = defaultJailbreak
}
+ for(let i=0;i