mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Theme Saver
This commit is contained in:
@ -1203,14 +1203,9 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-container flexnowrap alignitemscenter">
|
<div class="flex-container flexnowrap alignitemscenter">
|
||||||
<select id="main_api" class="margin0 margin-r5">
|
<select id="themes" class="margin0 margin-r5">
|
||||||
<option value="###">Coming Soon</option>
|
|
||||||
<option value="###">Don't Do</option>
|
|
||||||
<option value="###">Anything Yet</option>
|
|
||||||
<option value="###">Feature Currently</option>
|
|
||||||
<option value="###">Under Construction</option>
|
|
||||||
</select>
|
</select>
|
||||||
<div id="ui-preset-save-button" class="menu_button padding5 margin0">+</div>
|
<div id="ui-preset-save-button" title="Save changes to a new theme file" class="menu_button padding5 margin0">+</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2612,7 +2612,7 @@ async function getSettings(type) {
|
|||||||
loadPoeSettings(settings);
|
loadPoeSettings(settings);
|
||||||
|
|
||||||
// Load power user settings
|
// Load power user settings
|
||||||
loadPowerUserSettings(settings);
|
loadPowerUserSettings(settings, data);
|
||||||
|
|
||||||
|
|
||||||
//Enable GUI deference settings if GUI is selected for Kobold
|
//Enable GUI deference settings if GUI is selected for Kobold
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { saveSettingsDebounced, characters } from "../script.js";
|
import { saveSettingsDebounced, characters, callPopup, token } from "../script.js";
|
||||||
import { delay, debounce } from "./utils.js";
|
import { delay } from "./utils.js";
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@ -52,19 +52,13 @@ let power_user = {
|
|||||||
blur_tint_color: `${getComputedStyle(document.documentElement).getPropertyValue('--SmartThemeBlurTintColor').trim()}`,
|
blur_tint_color: `${getComputedStyle(document.documentElement).getPropertyValue('--SmartThemeBlurTintColor').trim()}`,
|
||||||
|
|
||||||
waifuMode: false,
|
waifuMode: false,
|
||||||
|
theme: 'Default (Dark)',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let themes = [];
|
||||||
|
|
||||||
const storage_keys = {
|
const storage_keys = {
|
||||||
collapse_newlines: "TavernAI_collapse_newlines",
|
|
||||||
force_pygmalion_formatting: "TavernAI_force_pygmalion_formatting",
|
|
||||||
pin_examples: "TavernAI_pin_examples",
|
|
||||||
disable_description_formatting: "TavernAI_disable_description_formatting",
|
|
||||||
disable_scenario_formatting: "TavernAI_disable_scenario_formatting",
|
|
||||||
disable_personality_formatting: "TavernAI_disable_personality_formatting",
|
|
||||||
always_force_name2: "TavernAI_always_force_name2",
|
|
||||||
custom_chat_separator: "TavernAI_custom_chat_separator",
|
|
||||||
fast_ui_mode: "TavernAI_fast_ui_mode",
|
fast_ui_mode: "TavernAI_fast_ui_mode",
|
||||||
multigen: "TavernAI_multigen",
|
|
||||||
avatar_style: "TavernAI_avatar_style",
|
avatar_style: "TavernAI_avatar_style",
|
||||||
chat_display: "TavernAI_chat_display",
|
chat_display: "TavernAI_chat_display",
|
||||||
sheld_width: "TavernAI_sheld_width",
|
sheld_width: "TavernAI_sheld_width",
|
||||||
@ -207,6 +201,39 @@ async function applyFontScale() {
|
|||||||
chat.style.transition = chatTransition;
|
chat.style.transition = chatTransition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function applyTheme(name) {
|
||||||
|
const theme = themes.find(x => x.name == name);
|
||||||
|
|
||||||
|
if (!theme) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const themeProperties = [
|
||||||
|
{ key: 'main_text_color', selector: '#main-text-color-picker', type: 'main' },
|
||||||
|
{ key: 'italics_text_color', selector: '#italics-color-picker', type: 'italics' },
|
||||||
|
{ key: 'fastui_bg_color', selector: '#fastui-bg-color-picker', type: 'fastUIBG' },
|
||||||
|
{ key: 'blur_tint_color', selector: '#blur-tint-color-picker', type: 'blurTint' },
|
||||||
|
{
|
||||||
|
key: 'blur_strength',
|
||||||
|
action: async () => {
|
||||||
|
localStorage.setItem(storage_keys.blur_strength, power_user.blur_strength);
|
||||||
|
await applyBlurStrength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const { key, selector, type, action } of themeProperties) {
|
||||||
|
if (theme[key] !== undefined) {
|
||||||
|
power_user[key] = theme[key];
|
||||||
|
if (selector) $(selector).attr('color', power_user[key]);
|
||||||
|
if (type) await applyThemeColor(type);
|
||||||
|
if (action) await action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('theme applied: ' + name);
|
||||||
|
}
|
||||||
|
|
||||||
applyAvatarStyle();
|
applyAvatarStyle();
|
||||||
switchUiMode();
|
switchUiMode();
|
||||||
applyChatDisplay();
|
applyChatDisplay();
|
||||||
@ -216,28 +243,16 @@ applyBlurStrength();
|
|||||||
applyThemeColor();
|
applyThemeColor();
|
||||||
switchWaifuMode()
|
switchWaifuMode()
|
||||||
|
|
||||||
// TODO delete in next release
|
function loadPowerUserSettings(settings, data) {
|
||||||
function loadFromLocalStorage() {
|
// Load from settings.json
|
||||||
power_user.collapse_newlines = localStorage.getItem(storage_keys.collapse_newlines) == "true";
|
|
||||||
power_user.force_pygmalion_formatting = localStorage.getItem(storage_keys.force_pygmalion_formatting) == "true";
|
|
||||||
power_user.pin_examples = localStorage.getItem(storage_keys.pin_examples) == "true";
|
|
||||||
power_user.disable_description_formatting = localStorage.getItem(storage_keys.disable_description_formatting) == "true";
|
|
||||||
power_user.disable_scenario_formatting = localStorage.getItem(storage_keys.disable_scenario_formatting) == "true";
|
|
||||||
power_user.disable_personality_formatting = localStorage.getItem(storage_keys.disable_personality_formatting) == "true";
|
|
||||||
power_user.always_force_name2 = localStorage.getItem(storage_keys.always_force_name2) == "true";
|
|
||||||
power_user.custom_chat_separator = localStorage.getItem(storage_keys.custom_chat_separator);
|
|
||||||
power_user.multigen = localStorage.getItem(storage_keys.multigen) == "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadPowerUserSettings(settings) {
|
|
||||||
// Migrate legacy settings
|
|
||||||
loadFromLocalStorage();
|
|
||||||
|
|
||||||
// Now do it properly from settings.json
|
|
||||||
if (settings.power_user !== undefined) {
|
if (settings.power_user !== undefined) {
|
||||||
Object.assign(power_user, settings.power_user);
|
Object.assign(power_user, settings.power_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.themes !== undefined) {
|
||||||
|
themes = data.themes;
|
||||||
|
}
|
||||||
|
|
||||||
// These are still local storage
|
// These are still local storage
|
||||||
const fastUi = localStorage.getItem(storage_keys.fast_ui_mode);
|
const fastUi = localStorage.getItem(storage_keys.fast_ui_mode);
|
||||||
const waifuMode = localStorage.getItem(storage_keys.waifuMode);
|
const waifuMode = localStorage.getItem(storage_keys.waifuMode);
|
||||||
@ -266,16 +281,23 @@ function loadPowerUserSettings(settings) {
|
|||||||
$(`input[name="chat_display"][value="${power_user.chat_display}"]`).prop("checked", true);
|
$(`input[name="chat_display"][value="${power_user.chat_display}"]`).prop("checked", true);
|
||||||
$(`input[name="sheld_width"][value="${power_user.sheld_width}"]`).prop("checked", true);
|
$(`input[name="sheld_width"][value="${power_user.sheld_width}"]`).prop("checked", true);
|
||||||
$("#font_scale").val(power_user.font_scale);
|
$("#font_scale").val(power_user.font_scale);
|
||||||
$("#font_scale_counter").html(power_user.font_scale);
|
$("#font_scale_counter").text(power_user.font_scale);
|
||||||
|
|
||||||
$("#blur_strength").val(power_user.blur_strength);
|
$("#blur_strength").val(power_user.blur_strength);
|
||||||
$("#blur_strength_counter").html(power_user.blur_strength);
|
$("#blur_strength_counter").text(power_user.blur_strength);
|
||||||
|
|
||||||
$("#main-text-color-picker").attr('color', power_user.main_text_color);
|
$("#main-text-color-picker").attr('color', power_user.main_text_color);
|
||||||
$("#italics-color-picker").attr('color', power_user.italics_text_color);
|
$("#italics-color-picker").attr('color', power_user.italics_text_color);
|
||||||
$("#fastui-bg-color-picker").attr('color', power_user.fastui_bg_color);
|
$("#fastui-bg-color-picker").attr('color', power_user.fastui_bg_color);
|
||||||
$("#blur-tint-color-picker").attr('color', power_user.blur_tint_color);
|
$("#blur-tint-color-picker").attr('color', power_user.blur_tint_color);
|
||||||
|
|
||||||
|
for (const theme of themes) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = theme.name;
|
||||||
|
option.innerText = theme.name;
|
||||||
|
option.selected = theme.name == power_user.theme;
|
||||||
|
$("#themes").append(option);
|
||||||
|
}
|
||||||
|
|
||||||
$(`#character_sort_order option[data-order="${power_user.sort_order}"][data-field="${power_user.sort_field}"]`).prop("selected", true);
|
$(`#character_sort_order option[data-order="${power_user.sort_order}"][data-field="${power_user.sort_field}"]`).prop("selected", true);
|
||||||
sortCharactersList();
|
sortCharactersList();
|
||||||
@ -415,6 +437,58 @@ $(document).ready(() => {
|
|||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#themes").on('change', function () {
|
||||||
|
const themeSelected = $(this).find(':selected').val();
|
||||||
|
power_user.theme = themeSelected;
|
||||||
|
applyTheme(themeSelected);
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#ui-preset-save-button").on('click', async function () {
|
||||||
|
const name = await callPopup('Name him, name your son:', 'input');
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const theme = {
|
||||||
|
name,
|
||||||
|
blur_strength: power_user.blur_strength,
|
||||||
|
main_text_color: power_user.main_text_color,
|
||||||
|
italics_text_color: power_user.italics_text_color,
|
||||||
|
fastui_bg_color: power_user.fastui_bg_color,
|
||||||
|
blur_tint_color: power_user.blur_tint_color,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await fetch('/savetheme', {
|
||||||
|
method: 'POST', headers: {
|
||||||
|
'X-CSRF-Token': token,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(theme)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const themeIndex = themes.findIndex(x => x.name == name);
|
||||||
|
|
||||||
|
if (themeIndex == -1) {
|
||||||
|
themes.push(theme);
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.selected = true;
|
||||||
|
option.value = name;
|
||||||
|
option.innerText = name;
|
||||||
|
$('#themes').append(option);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
themes[themeIndex] = theme;
|
||||||
|
$(`#themes option[value="${name}"]`).attr('selected', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
power_user.theme = name;
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$("#play_message_sound").on('input', function () {
|
$("#play_message_sound").on('input', function () {
|
||||||
power_user.play_message_sound = !!$(this).prop('checked');
|
power_user.play_message_sound = !!$(this).prop('checked');
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
|
8
public/themes/Aqua Blue.json
Normal file
8
public/themes/Aqua Blue.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "Aqua Blue",
|
||||||
|
"blur_strength": 2,
|
||||||
|
"main_text_color": "rgba(160, 190, 190, 1)",
|
||||||
|
"italics_text_color": "rgba(170, 200, 200, 1)",
|
||||||
|
"fastui_bg_color": "rgba(7, 54, 66, 0.9)",
|
||||||
|
"blur_tint_color": "rgba(0, 43, 54, 0.8)"
|
||||||
|
}
|
8
public/themes/Default (Dark).json
Normal file
8
public/themes/Default (Dark).json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "Default (Dark)",
|
||||||
|
"blur_strength": 10,
|
||||||
|
"main_text_color": "rgb(220, 220, 210)",
|
||||||
|
"italics_text_color": "rgb(175, 175, 175)",
|
||||||
|
"fastui_bg_color": "rgba(0, 0, 0, 0.9)",
|
||||||
|
"blur_tint_color": "rgba(0, 0, 0, 0.5)"
|
||||||
|
}
|
8
public/themes/Megumin Red.json
Normal file
8
public/themes/Megumin Red.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "Megumin Red",
|
||||||
|
"blur_strength": 10,
|
||||||
|
"main_text_color": "rgba(230, 230, 230, 1)",
|
||||||
|
"italics_text_color": "rgba(200, 200, 200, 1)",
|
||||||
|
"fastui_bg_color": "rgba(70, 5, 5, 0.9)",
|
||||||
|
"blur_tint_color": "rgba(50, 10, 10, 0.75)"
|
||||||
|
}
|
38
server.js
38
server.js
@ -117,6 +117,7 @@ const directories = {
|
|||||||
thumbnails: 'thumbnails/',
|
thumbnails: 'thumbnails/',
|
||||||
thumbnailsBg: 'thumbnails/bg/',
|
thumbnailsBg: 'thumbnails/bg/',
|
||||||
thumbnailsAvatar: 'thumbnails/avatar/',
|
thumbnailsAvatar: 'thumbnails/avatar/',
|
||||||
|
themes: 'public/themes',
|
||||||
};
|
};
|
||||||
|
|
||||||
// CSRF Protection //
|
// CSRF Protection //
|
||||||
@ -1037,6 +1038,7 @@ app.post('/getsettings', jsonParser, (request, response) => { //Wintermute's cod
|
|||||||
const openai_setting_names = [];
|
const openai_setting_names = [];
|
||||||
const textgenerationwebui_presets = [];
|
const textgenerationwebui_presets = [];
|
||||||
const textgenerationwebui_preset_names = [];
|
const textgenerationwebui_preset_names = [];
|
||||||
|
const themes = [];
|
||||||
const settings = fs.readFileSync('public/settings.json', 'utf8', (err, data) => {
|
const settings = fs.readFileSync('public/settings.json', 'utf8', (err, data) => {
|
||||||
if (err) return response.sendStatus(500);
|
if (err) return response.sendStatus(500);
|
||||||
|
|
||||||
@ -1139,6 +1141,30 @@ app.post('/getsettings', jsonParser, (request, response) => { //Wintermute's cod
|
|||||||
textgenerationwebui_preset_names.push(item.replace(/\.[^/.]+$/, ''));
|
textgenerationwebui_preset_names.push(item.replace(/\.[^/.]+$/, ''));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Theme files
|
||||||
|
const themeFiles = fs
|
||||||
|
.readdirSync(directories.themes)
|
||||||
|
.filter(x => path.parse(x).ext == '.json')
|
||||||
|
.sort();
|
||||||
|
|
||||||
|
themeFiles.forEach(item => {
|
||||||
|
const file = fs.readFileSync(
|
||||||
|
path.join(directories.themes, item),
|
||||||
|
'utf-8',
|
||||||
|
(err, data) => {
|
||||||
|
if (err) return response.sendStatus(500);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
themes.push(json5.parse(file));
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// skip
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
response.send({
|
response.send({
|
||||||
settings,
|
settings,
|
||||||
koboldai_settings,
|
koboldai_settings,
|
||||||
@ -1150,6 +1176,7 @@ app.post('/getsettings', jsonParser, (request, response) => { //Wintermute's cod
|
|||||||
openai_setting_names,
|
openai_setting_names,
|
||||||
textgenerationwebui_presets,
|
textgenerationwebui_presets,
|
||||||
textgenerationwebui_preset_names,
|
textgenerationwebui_preset_names,
|
||||||
|
themes,
|
||||||
enable_extensions: enableExtensions,
|
enable_extensions: enableExtensions,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1182,6 +1209,17 @@ app.post('/deleteworldinfo', jsonParser, (request, response) => {
|
|||||||
return response.sendStatus(200);
|
return response.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.post('/savetheme', jsonParser, (request, response) => {
|
||||||
|
if (!request.body || !request.body.name) {
|
||||||
|
return response.sendStatus(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const filename = path.join(directories.themes, sanitize(request.body.name) + '.json');
|
||||||
|
fs.writeFileSync(filename, JSON.stringify(request.body), 'utf8');
|
||||||
|
|
||||||
|
return response.sendStatus(200);
|
||||||
|
});
|
||||||
|
|
||||||
function readWorldInfoFile(worldInfoName) {
|
function readWorldInfoFile(worldInfoName) {
|
||||||
if (!worldInfoName) {
|
if (!worldInfoName) {
|
||||||
return { entries: {} };
|
return { entries: {} };
|
||||||
|
Reference in New Issue
Block a user