+
+
+
+
+
+
diff --git a/public/script.js b/public/script.js
index c17a78cd6..185784f39 100644
--- a/public/script.js
+++ b/public/script.js
@@ -3919,6 +3919,7 @@ function appendUserAvatar(name) {
template.attr('title', personaName);
}
template.find('.avatar').attr('imgfile', name);
+ template.toggleClass('default_persona', name === power_user.default_persona)
template.find('img').attr('src', `User Avatars/${name}`);
$("#user_avatar_block").append(template);
highlightSelectedAvatar();
@@ -3939,9 +3940,9 @@ export function setUserName(value) {
name1 = value;
if (name1 === undefined || name1 == "")
name1 = default_user_name;
- console.log(name1);
+ console.log(`User name changed to ${name1}`);
$("#your_name").val(name1);
- toastr.success(`Your messages will now be sent as ${name1}`, 'User Name updated');
+ toastr.success(`Your messages will now be sent as ${name1}`, 'Current persona updated');
saveSettings("change_name");
} else {
toastr.warning('You cannot change your name while sending a message', 'Warning');
@@ -3951,6 +3952,7 @@ export function setUserName(value) {
export function autoSelectPersona(name) {
for (const [key, value] of Object.entries(power_user.personas)) {
if (value === name) {
+ console.log(`Auto-selecting persona ${key} for name ${name}`);
$(`.avatar[imgfile="${key}"]`).trigger('click');
return;
}
@@ -3967,11 +3969,22 @@ async function bindUserNameToPersona() {
const existingPersona = power_user.personas[avatarId];
const personaName = await callPopup('
Enter a name for this persona:
(If empty name is provided, this will unbind the name from this avatar)', 'input', existingPersona || '');
- if (personaName) {
+
+ // If the user clicked cancel, don't do anything
+ if (personaName === false) {
+ return;
+ }
+
+ if (personaName.length > 0) {
+ // If the user clicked ok and entered a name, bind the name to the persona
+ console.log(`Binding persona ${avatarId} to name ${personaName}`);
power_user.personas[avatarId] = personaName;
} else {
+ // If the user clicked ok, but didn't enter a name, delete the persona
+ console.log(`Unbinding persona ${avatarId}`);
delete power_user.personas[avatarId];
}
+
saveSettingsDebounced();
await getUserAvatars();
}
@@ -3997,6 +4010,57 @@ function setUserAvatar() {
}
}
+async function setUserInfo() {
+ // TODO Replace with actual implementation
+ callPopup('This functionality is under development.
Please check back later.', 'text');
+}
+
+async function setDefaultPersona() {
+ const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
+
+ if (!avatarId) {
+ console.warn('No avatar id found');
+ return;
+ }
+
+ const currentDefault = power_user.default_persona;
+
+ if (power_user.personas[avatarId] === undefined) {
+ console.warn(`No persona name found for avatar ${avatarId}`);
+ toastr.warning('You must bind a name to this persona before you can set it as the default.', 'Persona name not set');
+ return;
+ }
+
+ const personaName = power_user.personas[avatarId];
+
+ if (avatarId === currentDefault) {
+ const confirm = await callPopup('Are you sure you want to remove the default persona?', 'confirm');
+
+ if (!confirm) {
+ console.debug('User cancelled removing default persona');
+ return;
+ }
+
+ console.log(`Removing default persona ${avatarId}`);
+ toastr.info('This persona will no longer be used by default when you open a new chat.', `Default persona removed`);
+ delete power_user.default_persona;
+ } else {
+ const confirm = await callPopup(`Are you sure you want to set "${personaName}" as the default persona?
+ This name and avatar will be used for all new chats, as well as existing chats where the user persona is not locked.`, 'confirm');
+
+ if (!confirm) {
+ console.debug('User cancelled setting default persona');
+ return;
+ }
+
+ power_user.default_persona = avatarId;
+ toastr.success('This persona will be used by default when you open a new chat.', `Default persona set to ${personaName}`);
+ }
+
+ saveSettingsDebounced();
+ await getUserAvatars();
+}
+
async function deleteUserAvatar() {
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
@@ -4006,6 +4070,7 @@ async function deleteUserAvatar() {
}
if (avatarId == user_avatar) {
+ console.warn(`User tried to delete their current avatar ${avatarId}`);
toastr.warning('You cannot delete the avatar you are currently using', 'Warning');
return;
}
@@ -4013,6 +4078,7 @@ async function deleteUserAvatar() {
const confirm = await callPopup('Are you sure you want to delete this avatar?', 'confirm');
if (!confirm) {
+ console.debug('User cancelled deleting avatar');
return;
}
@@ -4025,7 +4091,14 @@ async function deleteUserAvatar() {
});
if (request.ok) {
+ console.log(`Deleted avatar ${avatarId}`);
delete power_user.personas[avatarId];
+
+ if (avatarId === power_user.default_persona) {
+ toastr.warning('The default persona was deleted. You will need to set a new default persona.', 'Default persona deleted');
+ power_user.default_persona = null;
+ }
+
saveSettingsDebounced();
await getUserAvatars();
}
@@ -4033,6 +4106,7 @@ async function deleteUserAvatar() {
function lockUserNameToChat() {
if (chat_metadata['persona']) {
+ console.log(`Unlocking persona for this chat ${chat_metadata['persona']}`);
delete chat_metadata['persona'];
saveMetadata();
toastr.info('User persona is now unlocked for this chat. Click the "Lock" to bind again.', 'Persona unlocked');
@@ -4040,6 +4114,7 @@ function lockUserNameToChat() {
}
if (!(user_avatar in power_user.personas)) {
+ console.log(`Creating a new persona ${user_avatar}`);
toastr.info('Creating a new persona for currently selected user name and avatar...', 'Persona not set for this avatar');
power_user.personas[user_avatar] = name1;
}
@@ -4047,24 +4122,50 @@ function lockUserNameToChat() {
chat_metadata['persona'] = user_avatar;
saveMetadata();
saveSettingsDebounced();
+ console.log(`Locking persona for this chat ${user_avatar}`);
toastr.success(`User persona is locked to ${name1} in this chat`);
}
eventSource.on(event_types.CHAT_CHANGED, () => {
- // If persona is locked, select it
+ // Define a persona for this chat
+ let chatPersona = '';
+
if (chat_metadata['persona']) {
- // Find the avatar file
- const personaAvatar = $(`.avatar[imgfile="${chat_metadata['persona']}"]`).trigger('click');
-
- // Avatar missing (persona deleted)
- if (personaAvatar.length == 0) {
- console.warn('Persona avatar not found, unlocking persona');
- delete chat_metadata['persona'];
- return;
- }
-
- personaAvatar.trigger('click');
+ // If persona is locked in chat metadata, select it
+ console.log(`Using locked persona ${chat_metadata['persona']}`);
+ chatPersona = chat_metadata['persona'];
+ } else if (power_user.default_persona) {
+ // If default persona is set, select it
+ console.log(`Using default persona ${power_user.default_persona}`);
+ chatPersona = power_user.default_persona;
}
+
+ // No persona set: user current settings
+ if (!chatPersona) {
+ console.debug('No default or locked persona set for this chat');
+ return;
+ }
+
+ // Find the avatar file
+ const personaAvatar = $(`.avatar[imgfile="${chatPersona}"]`).trigger('click');
+
+ // Avatar missing (persona deleted)
+ if (chat_metadata['persona'] && personaAvatar.length == 0) {
+ console.warn('Persona avatar not found, unlocking persona');
+ delete chat_metadata['persona'];
+ return;
+ }
+
+ // Default persona missing
+ if (power_user.default_persona && personaAvatar.length == 0) {
+ console.warn('Default persona avatar not found, clearing default persona');
+ power_user.default_persona = null;
+ saveSettingsDebounced();
+ return;
+ }
+
+ // Persona avatar found, select it
+ personaAvatar.trigger('click');
});
//***************SETTINGS****************//
@@ -6690,7 +6791,7 @@ $(document).ready(function () {
if (this_chid !== undefined || selected_group) {
// Previously system messages we're allowed to be edited
/*const message = $(this).closest(".mes");
-
+
if (message.data("isSystem")) {
return;
}*/
@@ -6947,6 +7048,8 @@ $(document).ready(function () {
$(document).on('click', '.bind_user_name', bindUserNameToPersona);
$(document).on('click', '.delete_avatar', deleteUserAvatar);
+ $(document).on('click', '.set_default_persona', setDefaultPersona);
+ $(document).on('click', '.set_user_info', setUserInfo);
$('#lock_user_name').on('click', lockUserNameToChat);
//**************************CHARACTER IMPORT EXPORT*************************//
diff --git a/public/scripts/power-user.js b/public/scripts/power-user.js
index 84c496ce8..a330d259b 100644
--- a/public/scripts/power-user.js
+++ b/public/scripts/power-user.js
@@ -146,6 +146,7 @@ let power_user = {
},
personas: {},
+ default_persona: null,
};
let themes = [];
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index 16393e915..88d696548 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -262,6 +262,7 @@ function executeSlashCommands(text) {
continue;
}
+ console.debug('Slash command executing:', result);
result.command.callback(result.args, result.value);
if (result.command.interruptsGeneration) {
diff --git a/public/style.css b/public/style.css
index 6c7de3d52..9c3edca97 100644
--- a/public/style.css
+++ b/public/style.css
@@ -34,6 +34,7 @@
--orangered: rgb(255, 90, 0);
--greyCAIbg: rgb(36, 36, 37);
--ivory: rgb(220, 220, 210);
+ --golden: rgba(212, 175, 55, 1);
/*Default Theme, will be changed by ToolCool Color Picker*/
@@ -1239,7 +1240,8 @@ select option:not(:checked) {
}
#form_character_search_form .menu_button,
-#GroupFavDelOkBack .menu_button {
+#GroupFavDelOkBack .menu_button,
+.avatar-container .menu_button {
margin: 0;
height: fit-content;
padding: 5px;
@@ -1529,12 +1531,26 @@ input[type=search]:focus::-webkit-search-cancel-button {
pointer-events: all;
}
+.avatar-buttons-bottom {
+ bottom: 0;
+ left: 0;
+}
+
+.avatar-buttons-top {
+ top: 0;
+ left: 0;
+}
+
+/* Ross should be able to handle this later */
+/*.big-avatars .avatar-buttons{
+ justify-content: center;
+ width: fit-content;
+}*/
+
.avatar-buttons {
pointer-events: none;
display: none;
position: absolute;
- top: 0;
- left: 0;
width: 100%;
justify-content: space-between;
}
@@ -2077,6 +2093,11 @@ input[type=search]:focus::-webkit-search-cancel-button {
margin-right: 12px;
}
+/* Override toastr default styles */
+body #toast-container>div {
+ opacity: 0.95;
+}
+
#dialogue_del_mes {
display: none;
}
@@ -2152,6 +2173,15 @@ input[type='checkbox']:not(#nav-toggle):not(#rm_button_panel_pin):not(#lm_button
outline: 2px solid transparent;
}
+#user_avatar_block .default_persona .avatar {
+ border: 2px solid var(--golden);
+ box-sizing: content-box;
+}
+
+#user_avatar_block .default_persona .set_default_persona {
+ color: var(--golden);
+}
+
#user_avatar_block .avatar img {
width: 64px;
height: 64px;
@@ -4621,4 +4651,4 @@ body.waifuMode #avatar_zoom_popup {
overflow-y: auto;
overflow-x: hidden;
}
-}
\ No newline at end of file
+}