UI Theme import/export
This commit is contained in:
parent
87668f5962
commit
cbea5bf996
|
@ -3114,8 +3114,17 @@
|
|||
<div id="user-settings-block-content" class="flex-container spaceEvenly">
|
||||
<div name="UserSettingsFirstColumn" id="UI-Theme-Block" class="flex-container flexFlowColumn wide100p">
|
||||
<div id="UI-presets-block" class="flex-container flexFlowColumn">
|
||||
<h4>
|
||||
<span data-i18n="UI Theme Preset">Theme Preset</span>
|
||||
<h4 class="title_restorable">
|
||||
<span data-i18n="UI Theme">UI Theme</span>
|
||||
<div class="flex-container">
|
||||
<div id="ui_preset_import_button" class="menu_button menu_button_icon margin0" title="Import a theme file" data-i18n="[title]Import a theme file">
|
||||
<i class="fa-solid fa-file-import"></i>
|
||||
</div>
|
||||
<div id="ui_preset_export_button" class="menu_button menu_button_icon margin0" title="Export a theme file" data-i18n="[title]Export a theme file">
|
||||
<i class="fa-solid fa-file-export"></i>
|
||||
</div>
|
||||
</div>
|
||||
<input type="file" id="ui_preset_import_file" accept=".json" hidden>
|
||||
</h4>
|
||||
<div class="flex-container flexnowrap alignitemscenter">
|
||||
<select id="themes" class="margin0">
|
||||
|
|
|
@ -38,7 +38,7 @@ import { tags } from './tags.js';
|
|||
import { tokenizers } from './tokenizers.js';
|
||||
import { BIAS_CACHE } from './logit-bias.js';
|
||||
|
||||
import { countOccurrences, debounce, delay, isOdd, resetScrollHeight, shuffle, sortMoments, stringToRange, timestampToMoment } from './utils.js';
|
||||
import { countOccurrences, debounce, delay, download, getFileText, isOdd, resetScrollHeight, shuffle, sortMoments, stringToRange, timestampToMoment } from './utils.js';
|
||||
|
||||
export {
|
||||
loadPowerUserSettings,
|
||||
|
@ -1981,10 +1981,51 @@ async function updateTheme() {
|
|||
toastr.success('Theme saved.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the current theme to a file.
|
||||
*/
|
||||
async function exportTheme() {
|
||||
const themeFile = await saveTheme(power_user.theme);
|
||||
const fileName = `${themeFile.name}.json`;
|
||||
download(JSON.stringify(themeFile, null, 4), fileName, 'application/json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a theme from a file.
|
||||
* @param {File} file File to import.
|
||||
* @returns {Promise<void>} A promise that resolves when the theme is imported.
|
||||
*/
|
||||
async function importTheme(file) {
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fileText = await getFileText(file);
|
||||
const parsed = JSON.parse(fileText);
|
||||
|
||||
if (!parsed.name) {
|
||||
throw new Error('Missing name');
|
||||
}
|
||||
|
||||
if (themes.some(t => t.name === parsed.name)) {
|
||||
throw new Error('Theme with that name already exists');
|
||||
}
|
||||
|
||||
themes.push(parsed);
|
||||
await applyTheme(parsed.name);
|
||||
await saveTheme(parsed.name);
|
||||
const option = document.createElement('option');
|
||||
option.selected = true;
|
||||
option.value = parsed.name;
|
||||
option.innerText = parsed.name;
|
||||
$('#themes').append(option);
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current theme to the server.
|
||||
* @param {string|undefined} name Theme name. If undefined, a popup will be shown to enter a name.
|
||||
* @returns {Promise<void>} A promise that resolves when the theme is saved.
|
||||
* @returns {Promise<object>} A promise that resolves when the theme is saved.
|
||||
*/
|
||||
async function saveTheme(name = undefined) {
|
||||
if (typeof name !== 'string') {
|
||||
|
@ -2056,6 +2097,8 @@ async function saveTheme(name = undefined) {
|
|||
power_user.theme = name;
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
async function saveMovingUI() {
|
||||
|
@ -3278,6 +3321,30 @@ $(document).ready(() => {
|
|||
reloadCurrentChat();
|
||||
});
|
||||
|
||||
$('#ui_preset_import_button').on('click', function () {
|
||||
$('#ui_preset_import_file').trigger('click');
|
||||
});
|
||||
|
||||
$('#ui_preset_import_file').on('change', async function() {
|
||||
const inputElement = this instanceof HTMLInputElement && this;
|
||||
|
||||
try {
|
||||
const file = inputElement?.files?.[0];
|
||||
await importTheme(file);
|
||||
} catch (error) {
|
||||
console.error('Error importing UI theme', error);
|
||||
toastr.error(String(error), 'Failed to import UI theme');
|
||||
} finally {
|
||||
if (inputElement) {
|
||||
inputElement.value = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#ui_preset_export_button').on('click', async function () {
|
||||
await exportTheme();
|
||||
});
|
||||
|
||||
$(document).on('click', '#debug_table [data-debug-function]', function () {
|
||||
const functionId = $(this).data('debug-function');
|
||||
const functionRecord = debug_functions.find(f => f.functionId === functionId);
|
||||
|
|
Loading…
Reference in New Issue