mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Work on translation
This commit is contained in:
@@ -682,9 +682,9 @@ function getExtensionData(extension) {
|
||||
* @return {string} - The HTML string for the module information.
|
||||
*/
|
||||
function getModuleInformation() {
|
||||
let moduleInfo = modules.length ? `<p>${DOMPurify.sanitize(modules.join(', '))}</p>` : '<p class="failure">Not connected to the API!</p>';
|
||||
let moduleInfo = modules.length ? `<p>${DOMPurify.sanitize(modules.join(', '))}</p>` : '<p class="failure">' + t`Not connected to the API!` + '</p>';
|
||||
return `
|
||||
<h3>Modules provided by your Extras API:</h3>
|
||||
<h3>` + t`Modules provided by your Extras API:` + `</h3>
|
||||
${moduleInfo}
|
||||
`;
|
||||
}
|
||||
@@ -703,11 +703,11 @@ async function showExtensionsDetails() {
|
||||
initialScrollTop = oldPopup.content.scrollTop;
|
||||
await oldPopup.completeCancelled();
|
||||
}
|
||||
const htmlDefault = $('<div class="marginBot10"><h3 class="textAlignCenter">Built-in Extensions:</h3></div>');
|
||||
const htmlExternal = $('<div class="marginBot10"><h3 class="textAlignCenter">Installed Extensions:</h3></div>');
|
||||
const htmlDefault = $('<div class="marginBot10"><h3 class="textAlignCenter">' + t`Built-in Extensions:` + '</h3></div>');
|
||||
const htmlExternal = $('<div class="marginBot10"><h3 class="textAlignCenter">' + t`Installed Extensions:` + '</h3></div>');
|
||||
const htmlLoading = $(`<div class="flex-container alignItemsCenter justifyCenter marginTop10 marginBot5">
|
||||
<i class="fa-solid fa-spinner fa-spin"></i>
|
||||
<span>Loading third-party extensions... Please wait...</span>
|
||||
<span>` + t`Loading third-party extensions... Please wait...` + `</span>
|
||||
</div>`);
|
||||
|
||||
htmlExternal.append(htmlLoading);
|
||||
@@ -728,7 +728,7 @@ async function showExtensionsDetails() {
|
||||
|
||||
/** @type {import('./popup.js').CustomPopupButton} */
|
||||
const updateAllButton = {
|
||||
text: 'Update all',
|
||||
text: t`Update all`,
|
||||
appendAtEnd: true,
|
||||
action: async () => {
|
||||
requiresReload = true;
|
||||
@@ -740,7 +740,7 @@ async function showExtensionsDetails() {
|
||||
let waitingForSave = false;
|
||||
|
||||
const popup = new Popup(html, POPUP_TYPE.TEXT, '', {
|
||||
okButton: 'Close',
|
||||
okButton: t`Close`,
|
||||
wide: true,
|
||||
large: true,
|
||||
customButtons: [updateAllButton],
|
||||
@@ -833,7 +833,7 @@ async function updateExtension(extensionName, quiet) {
|
||||
toastr.success('Extension is already up to date');
|
||||
}
|
||||
} else {
|
||||
toastr.success(`Extension ${extensionName} updated to ${data.shortCommitHash}`, 'Reload the page to apply updates');
|
||||
toastr.success(t`Extension ${extensionName} updated to ${data.shortCommitHash}`, t`Reload the page to apply updates`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
@@ -1001,7 +1001,7 @@ export async function installExtension(url, global) {
|
||||
}
|
||||
|
||||
const response = await request.json();
|
||||
toastr.success(`Extension "${response.display_name}" by ${response.author} (version ${response.version}) has been installed successfully!`, 'Extension installation successful');
|
||||
toastr.success(t`Extension '${response.display_name}' by ${response.author} (version ${response.version}) has been installed successfully!`, t`Extension installation successful`);
|
||||
console.debug(`Extension "${response.display_name}" has been installed successfully at ${response.extensionPath}`);
|
||||
await loadExtensionSettings({}, false, false);
|
||||
await eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED);
|
||||
@@ -1175,7 +1175,7 @@ async function checkForExtensionUpdates(force) {
|
||||
await Promise.allSettled(promises);
|
||||
|
||||
if (updatesAvailable.length > 0) {
|
||||
toastr.info(`${updatesAvailable.map(x => `• ${x}`).join('\n')}`, 'Extension updates available');
|
||||
toastr.info(`${updatesAvailable.map(x => `• ${x}`).join('\n')}`, t`Extension updates available`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1189,7 +1189,7 @@ async function autoUpdateExtensions(forceAll) {
|
||||
return;
|
||||
}
|
||||
|
||||
const banner = toastr.info('Auto-updating extensions. This may take several minutes.', 'Please wait...', { timeOut: 10000, extendedTimeOut: 10000 });
|
||||
const banner = toastr.info(t`Auto-updating extensions. This may take several minutes.`, t`Please wait...`, { timeOut: 10000, extendedTimeOut: 10000 });
|
||||
const isCurrentUserAdmin = isAdmin();
|
||||
const promises = [];
|
||||
for (const [id, manifest] of Object.entries(manifests)) {
|
||||
|
@@ -1,10 +1,10 @@
|
||||
<div>
|
||||
<h3>Included settings:</h3>
|
||||
<h3 data-i18n="Included settings:">Included settings:</h3>
|
||||
<div class="justifyLeft flex-container flexFlowColumn flexNoGap">
|
||||
{{#each settings}}
|
||||
<label class="checkbox_label">
|
||||
<input type="checkbox" value="{{@key}}" name="exclude"{{#if this}} checked{{/if}}>
|
||||
<span>{{@key}}</span>
|
||||
<span data-i18n="{{@key}}">{{@key}}</span>
|
||||
</label>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
@@ -12,8 +12,8 @@
|
||||
</div>
|
||||
<div class="marginTop5">
|
||||
<small>
|
||||
<b>Hint:</b>
|
||||
<i>Click on the setting name to omit it from the profile.</i>
|
||||
<b data-i18n="Hint:">Hint:</b>
|
||||
<i data-i18n="Click on the setting name to omit it from the profile.">Click on the setting name to omit it from the profile.</i>
|
||||
</small>
|
||||
</div>
|
||||
<h3 data-i18n="Enter a name:">
|
||||
|
@@ -5491,8 +5491,8 @@ export function initOpenAI() {
|
||||
|
||||
if (!isMobile()) {
|
||||
$('#model_openrouter_select').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
templateResult: getOpenRouterModelTemplate,
|
||||
|
@@ -5,6 +5,7 @@ import { textgenerationwebui_settings as textgen_settings, textgen_types } from
|
||||
import { tokenizers } from './tokenizers.js';
|
||||
import { renderTemplateAsync } from './templates.js';
|
||||
import { POPUP_TYPE, callGenericPopup } from './popup.js';
|
||||
import { t } from './i18n.js';
|
||||
|
||||
let mancerModels = [];
|
||||
let togetherModels = [];
|
||||
@@ -936,71 +937,71 @@ export function initTextGenModels() {
|
||||
|
||||
if (!isMobile()) {
|
||||
$('#mancer_model').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
templateResult: getMancerModelTemplate,
|
||||
});
|
||||
$('#model_togetherai_select').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
templateResult: getTogetherModelTemplate,
|
||||
});
|
||||
$('#ollama_model').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
});
|
||||
$('#tabby_model').select2({
|
||||
placeholder: '[Currently loaded]',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`[Currently loaded]`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
allowClear: true,
|
||||
});
|
||||
$('#model_infermaticai_select').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
templateResult: getInfermaticAIModelTemplate,
|
||||
});
|
||||
$('#model_dreamgen_select').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
templateResult: getDreamGenModelTemplate,
|
||||
});
|
||||
$('#openrouter_model').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
templateResult: getOpenRouterModelTemplate,
|
||||
});
|
||||
$('#vllm_model').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
templateResult: getVllmModelTemplate,
|
||||
});
|
||||
$('#aphrodite_model').select2({
|
||||
placeholder: 'Select a model',
|
||||
searchInputPlaceholder: 'Search models...',
|
||||
placeholder: t`Select a model`,
|
||||
searchInputPlaceholder: t`Search models...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
templateResult: getAphroditeModelTemplate,
|
||||
});
|
||||
providersSelect.select2({
|
||||
sorter: data => data.sort((a, b) => a.text.localeCompare(b.text)),
|
||||
placeholder: 'Select providers. No selection = all providers.',
|
||||
searchInputPlaceholder: 'Search providers...',
|
||||
placeholder: t`Select providers. No selection = all providers.`,
|
||||
searchInputPlaceholder: t`Search providers...`,
|
||||
searchInputCssClass: 'text_pole',
|
||||
width: '100%',
|
||||
closeOnSelect: false,
|
||||
|
@@ -20,6 +20,7 @@ import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js';
|
||||
import { callGenericPopup, Popup, POPUP_TYPE } from './popup.js';
|
||||
import { StructuredCloneMap } from './util/StructuredCloneMap.js';
|
||||
import { renderTemplateAsync } from './templates.js';
|
||||
import { t } from './i18n.js';
|
||||
|
||||
export const world_info_insertion_strategy = {
|
||||
evenly: 0,
|
||||
@@ -909,21 +910,21 @@ function registerWorldInfoSlashCommands() {
|
||||
|
||||
async function getEntriesFromFile(file) {
|
||||
if (!file || !world_names.includes(file)) {
|
||||
toastr.warning('Valid World Info file name is required');
|
||||
toastr.warning(t`Valid World Info file name is required`);
|
||||
return '';
|
||||
}
|
||||
|
||||
const data = await loadWorldInfo(file);
|
||||
|
||||
if (!data || !('entries' in data)) {
|
||||
toastr.warning('World Info file has an invalid format');
|
||||
toastr.warning(t`World Info file has an invalid format`);
|
||||
return '';
|
||||
}
|
||||
|
||||
const entries = Object.values(data.entries);
|
||||
|
||||
if (!entries || entries.length === 0) {
|
||||
toastr.warning('World Info file has no entries');
|
||||
toastr.warning(t`World Info file has no entries`);
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -951,7 +952,7 @@ function registerWorldInfoSlashCommands() {
|
||||
name = String(name ?? '') || context.characters[context.characterId]?.avatar || null;
|
||||
const character = findChar({ name });
|
||||
if (!character) {
|
||||
toastr.error('Character not found.');
|
||||
toastr.error(t`Character not found.`);
|
||||
return '';
|
||||
}
|
||||
const books = [];
|
||||
@@ -977,7 +978,7 @@ function registerWorldInfoSlashCommands() {
|
||||
const chatId = getCurrentChatId();
|
||||
|
||||
if (!chatId) {
|
||||
toastr.warning('Open a chat to get a name of the chat-bound lorebook');
|
||||
toastr.warning(t`Open a chat to get a name of the chat-bound lorebook`);
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -4773,7 +4774,7 @@ export async function importEmbeddedWorldInfo(skipPopup = false) {
|
||||
const bookName = characters[chid]?.data?.character_book?.name || `${characters[chid]?.name}'s Lorebook`;
|
||||
|
||||
if (!skipPopup) {
|
||||
const confirmation = await Popup.show.confirm(`Are you sure you want to import "${bookName}"?`, world_names.includes(bookName) ? 'It will overwrite the World/Lorebook with the same name.' : '');
|
||||
const confirmation = await Popup.show.confirm(t`Are you sure you want to import '${bookName}'?`, world_names.includes(bookName) ? t`It will overwrite the World/Lorebook with the same name.` : '');
|
||||
if (!confirmation) {
|
||||
return;
|
||||
}
|
||||
@@ -4785,7 +4786,7 @@ export async function importEmbeddedWorldInfo(skipPopup = false) {
|
||||
await updateWorldInfoList();
|
||||
$('#character_world').val(bookName).trigger('change');
|
||||
|
||||
toastr.success(`The world "${bookName}" has been imported and linked to the character successfully.`, 'World/Lorebook imported');
|
||||
toastr.success(t`The world '${bookName}' has been imported and linked to the character successfully.`, t`World/Lorebook imported`);
|
||||
|
||||
const newIndex = world_names.indexOf(bookName);
|
||||
if (newIndex >= 0) {
|
||||
@@ -4813,9 +4814,9 @@ export function onWorldInfoChange(args, text) {
|
||||
if (selected_world_info.includes(name)) {
|
||||
selected_world_info.splice(selected_world_info.indexOf(name), 1);
|
||||
wiElement.prop('selected', false);
|
||||
if (!silent) toastr.success(`Deactivated world: ${name}`);
|
||||
if (!silent) toastr.success(t`Deactivated world: ${name}`);
|
||||
} else {
|
||||
if (!silent) toastr.error(`World was not active: ${name}`);
|
||||
if (!silent) toastr.error(t`World was not active: ${name}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4823,11 +4824,11 @@ export function onWorldInfoChange(args, text) {
|
||||
if (selected_world_info.includes(name)) {
|
||||
selected_world_info.splice(selected_world_info.indexOf(name), 1);
|
||||
wiElement.prop('selected', false);
|
||||
if (!silent) toastr.success(`Deactivated world: ${name}`);
|
||||
if (!silent) toastr.success(t`Deactivated world: ${name}`);
|
||||
} else {
|
||||
selected_world_info.push(name);
|
||||
wiElement.prop('selected', true);
|
||||
if (!silent) toastr.success(`Activated world: ${name}`);
|
||||
if (!silent) toastr.success(t`Activated world: ${name}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4835,16 +4836,16 @@ export function onWorldInfoChange(args, text) {
|
||||
default: {
|
||||
selected_world_info.push(name);
|
||||
wiElement.prop('selected', true);
|
||||
if (!silent) toastr.success(`Activated world: ${name}`);
|
||||
if (!silent) toastr.success(t`Activated world: ${name}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!silent) toastr.error(`No world found named: ${worldName}`);
|
||||
if (!silent) toastr.error(t`No world found named: ${worldName}`);
|
||||
}
|
||||
});
|
||||
$('#world_info').trigger('change');
|
||||
} else { // if no args, unset all worlds
|
||||
if (!silent) toastr.success('Deactivated all worlds');
|
||||
if (!silent) toastr.success(t`Deactivated all worlds`);
|
||||
selected_world_info = [];
|
||||
$('#world_info').val(null).trigger('change');
|
||||
}
|
||||
@@ -4860,7 +4861,7 @@ export function onWorldInfoChange(args, text) {
|
||||
} else {
|
||||
const wiElement = getWIElement(existingWorldName);
|
||||
wiElement.prop('selected', false);
|
||||
toastr.error(`The world with ${existingWorldName} is invalid or corrupted.`);
|
||||
toastr.error(t`The world with ${existingWorldName} is invalid or corrupted.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -4892,7 +4893,7 @@ export async function importWorldInfo(file) {
|
||||
}
|
||||
|
||||
if (jsonData === undefined || jsonData === null) {
|
||||
toastr.error(`File is not valid: ${file.name}`);
|
||||
toastr.error(t`File is not valid: ${file.name}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5038,7 +5039,7 @@ jQuery(() => {
|
||||
|
||||
$('#world_create_button').on('click', async () => {
|
||||
const tempName = getFreeWorldName();
|
||||
const finalName = await Popup.show.input('Create a new World Info', 'Enter a name for the new file:', tempName);
|
||||
const finalName = await Popup.show.input(t`Create a new World Info`, t`Enter a name for the new file:`, tempName);
|
||||
|
||||
if (finalName) {
|
||||
await createNewWorldInfo(finalName, { interactive: true });
|
||||
|
Reference in New Issue
Block a user