Move shallow toggle to config.yaml

3d813e4ef6e0d09998a55bf074c8d8d68fabfd4f

Cohee <18619528+Cohee1207@users.noreply.github.com>

7 files changed, +21 -24Ignore whitespace
default/config.yaml+8 -2
@@ -1,8 +1,6 @@
1# -- DATA CONFIGURATION --1# -- DATA CONFIGURATION --
2# Root directory for user data storage2# Root directory for user data storage
3dataRoot: ./data3dataRoot: ./data
4# The maximum amount of memory that parsed character cards can use in MB
5cardsCacheCapacity: 100
6# -- SERVER CONFIGURATION --4# -- SERVER CONFIGURATION --
7# Listen for incoming connections5# Listen for incoming connections
8listen: false6listen: false
@@ -135,6 +133,14 @@ thumbnails:
135 # Maximum thumbnail dimensions per type [width, height]133 # Maximum thumbnail dimensions per type [width, height]
136 dimensions: { 'bg': [160, 90], 'avatar': [96, 144] }134 dimensions: { 'bg': [160, 90], 'avatar': [96, 144] }
137135
136# PERFORMANCE-RELATED CONFIGURATION
137performance:
138 # Enables lazy loading of character cards. Improves performances with large card libraries.
139 # May have compatibility issues with some extensions.
140 lazyLoadCharacters: false
141 # The maximum amount of memory that parsed character cards can use in MB
142 cardsCacheCapacity: 100
143
138# Allow secret keys exposure via API144# Allow secret keys exposure via API
139allowKeysExposure: false145allowKeysExposure: false
140# Skip new default content checks146# Skip new default content checks
post-install.js+5 -0
@@ -96,6 +96,11 @@ const keyMigrationMap = [
96 newKey: 'logging.minLogLevel',96 newKey: 'logging.minLogLevel',
97 migrate: (value) => value,97 migrate: (value) => value,
98 },98 },
99 {
100 oldKey: 'cardsCacheCapacity',
101 newKey: 'performance.cardsCacheCapacity',
102 migrate: (value) => value,
103 },
99 // uncomment one release after 1.12.13104 // uncomment one release after 1.12.13
100 /*105 /*
101 {106 {
public/index.html+0 -7
@@ -4424,13 +4424,6 @@
4424 <option data-i18n="tag_import_existing" value="4">Existing</option>4424 <option data-i18n="tag_import_existing" value="4">Existing</option>
4425 </select>4425 </select>
4426 </div>4426 </div>
4427 <label class="checkbox_label" for="shallow_characters" data-i18n="[title]Experimental feature. May behave unstable and have compatibility issues." title="Experimental feature. May behave unstable and have compatibility issues.">
4428 <input id="shallow_characters" type="checkbox" />
4429 <small data-i18n="Lazy Load Characters">
4430 Lazy Load Characters
4431 </small>
4432 <i class="fa-solid fa-flask"></i>
4433 </label>
4434 <label class="checkbox_label" for="fuzzy_search_checkbox" title="Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring." data-i18n="[title]Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring">4427 <label class="checkbox_label" for="fuzzy_search_checkbox" title="Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring." data-i18n="[title]Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring">
4435 <input id="fuzzy_search_checkbox" type="checkbox" />4428 <input id="fuzzy_search_checkbox" type="checkbox" />
4436 <small data-i18n="Advanced Character Search">Advanced Character Search</small>4429 <small data-i18n="Advanced Character Search">Advanced Character Search</small>
public/script.js+2 -3
@@ -1780,9 +1780,7 @@ export async function getCharacters() {
1780 const response = await fetch('/api/characters/all', {1780 const response = await fetch('/api/characters/all', {
1781 method: 'POST',1781 method: 'POST',
1782 headers: getRequestHeaders(),1782 headers: getRequestHeaders(),
1783 body: JSON.stringify({1783 body: JSON.stringify({}),
1784 shallow: power_user.shallow_characters,
1785 }),
1786 });1784 });
1787 if (response.ok === true) {1785 if (response.ok === true) {
1788 characters.splice(0, characters.length);1786 characters.splice(0, characters.length);
@@ -6718,6 +6716,7 @@ export async function unshallowCharacter(characterId) {
6718 return;6716 return;
6719 }6717 }
67206718
6719 /** @type {import('./scripts/char-data.js').v1CharData} */
6721 const character = characters[characterId];6720 const character = characters[characterId];
6722 if (!character) {6721 if (!character) {
6723 console.warn('Character not found:', characterId);6722 console.warn('Character not found:', characterId);
public/scripts/char-data.js+1 -0
@@ -113,5 +113,6 @@
113 * @property {string} chat - name of the current chat file chat113 * @property {string} chat - name of the current chat file chat
114 * @property {string} avatar - file name of the avatar image (acts as a unique identifier)114 * @property {string} avatar - file name of the avatar image (acts as a unique identifier)
115 * @property {string} json_data - the full raw JSON data of the character115 * @property {string} json_data - the full raw JSON data of the character
116 * @property {boolean?} shallow - if the data is shallow (lazy-loaded)
116 */117 */
117export default 0;// now this file is a module118export default 0;// now this file is a module
public/scripts/power-user.js+0 -8
@@ -314,7 +314,6 @@ let power_user = {
314 forbid_external_media: true,314 forbid_external_media: true,
315 external_media_allowed_overrides: [],315 external_media_allowed_overrides: [],
316 external_media_forbidden_overrides: [],316 external_media_forbidden_overrides: [],
317 shallow_characters: false,
318};317};
319318
320let themes = [];319let themes = [];
@@ -1596,7 +1595,6 @@ async function loadPowerUserSettings(settings, data) {
1596 $('#auto-connect-checkbox').prop('checked', power_user.auto_connect);1595 $('#auto-connect-checkbox').prop('checked', power_user.auto_connect);
1597 $('#auto-load-chat-checkbox').prop('checked', power_user.auto_load_chat);1596 $('#auto-load-chat-checkbox').prop('checked', power_user.auto_load_chat);
1598 $('#forbid_external_media').prop('checked', power_user.forbid_external_media);1597 $('#forbid_external_media').prop('checked', power_user.forbid_external_media);
1599 $('#shallow_characters').prop('checked', power_user.shallow_characters);
16001598
1601 for (const theme of themes) {1599 for (const theme of themes) {
1602 const option = document.createElement('option');1600 const option = document.createElement('option');
@@ -3890,12 +3888,6 @@ $(document).ready(() => {
3890 await exportTheme();3888 await exportTheme();
3891 });3889 });
38923890
3893 $('#shallow_characters').on('input', function () {
3894 power_user.shallow_characters = !!$(this).prop('checked');
3895 saveSettingsDebounced();
3896 toastr.info('Reload the page for this setting to take effect');
3897 });
3898
3899 $(document).on('click', '#debug_table [data-debug-function]', function () {3891 $(document).on('click', '#debug_table [data-debug-function]', function () {
3900 const functionId = $(this).data('debug-function');3892 const functionId = $(this).data('debug-function');
3901 const functionRecord = debug_functions.find(f => f.functionId === functionId);3893 const functionRecord = debug_functions.find(f => f.functionId === functionId);
src/endpoints/characters.js+5 -4
@@ -24,11 +24,13 @@ import { importRisuSprites } from './sprites.js';
24const defaultAvatarPath = './public/img/ai4.png';24const defaultAvatarPath = './public/img/ai4.png';
2525
26// KV-store for parsed character data26// KV-store for parsed character data
27const cacheCapacity = Number(getConfigValue('cardsCacheCapacity', 100, 'number')); // MB27const cacheCapacity = Number(getConfigValue('performance.cardsCacheCapacity', 100, 'number')); // MB
28// With 100 MB limit it would take roughly 3000 characters to reach this limit28// With 100 MB limit it would take roughly 3000 characters to reach this limit
29const characterDataCache = new MemoryLimitedMap(1024 * 1024 * cacheCapacity);29const characterDataCache = new MemoryLimitedMap(1024 * 1024 * cacheCapacity);
30// Some Android devices require tighter memory management30// Some Android devices require tighter memory management
31const isAndroid = process.platform === 'android';31const isAndroid = process.platform === 'android';
32// Use shallow character data for the character list
33const useShallowCharacters = !!getConfigValue('performance.lazyLoadCharacters', false, 'boolean');
3234
33/**35/**
34 * Reads the character card from the specified image file.36 * Reads the character card from the specified image file.
@@ -207,6 +209,7 @@ const calculateDataSize = (data) => {
207 */209 */
208const toShallow = (character) => {210const toShallow = (character) => {
209 return {211 return {
212 shallow: true,
210 name: character.name,213 name: character.name,
211 avatar: character.avatar,214 avatar: character.avatar,
212 chat: character.chat,215 chat: character.chat,
@@ -225,7 +228,6 @@ const toShallow = (character) => {
225 fav: _.get(character, 'data.extensions.fav', false),228 fav: _.get(character, 'data.extensions.fav', false),
226 },229 },
227 },230 },
228 shallow: true,
229 };231 };
230};232};
231233
@@ -1022,10 +1024,9 @@ router.post('/delete', jsonParser, validateAvatarUrlMiddleware, async function (
1022 */1024 */
1023router.post('/all', jsonParser, async function (request, response) {1025router.post('/all', jsonParser, async function (request, response) {
1024 try {1026 try {
1025 const shallow = !!request.body.shallow;
1026 const files = fs.readdirSync(request.user.directories.characters);1027 const files = fs.readdirSync(request.user.directories.characters);
1027 const pngFiles = files.filter(file => file.endsWith('.png'));1028 const pngFiles = files.filter(file => file.endsWith('.png'));
1028 const processingPromises = pngFiles.map(file => processCharacter(file, request.user.directories, { shallow }));1029 const processingPromises = pngFiles.map(file => processCharacter(file, request.user.directories, { shallow: useShallowCharacters }));
1029 const data = (await Promise.all(processingPromises)).filter(c => c.name);1030 const data = (await Promise.all(processingPromises)).filter(c => c.name);
1030 return response.send(data);1031 return response.send(data);
1031 } catch (err) {1032 } catch (err) {