diff --git a/public/index.html b/public/index.html
index 5f5fd3191..46f1f58c5 100644
--- a/public/index.html
+++ b/public/index.html
@@ -3201,6 +3201,7 @@
@@ -3218,6 +3219,7 @@
+
diff --git a/public/script.js b/public/script.js
index 1b08c7950..fa7a46a96 100644
--- a/public/script.js
+++ b/public/script.js
@@ -5916,6 +5916,7 @@ function select_rm_characters() {
menu_type = "characters";
selectRightMenuWithAnimation('rm_characters_block');
setRightTabSelectedClass('rm_button_characters');
+ printCharacters(false); // Do a quick refresh of the characters list
}
function setExtensionPrompt(key, value, position, depth) {
diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js
index 0b2812fc9..898388e5f 100644
--- a/public/scripts/group-chats.js
+++ b/public/scripts/group-chats.js
@@ -7,8 +7,8 @@ import {
createThumbnail,
extractAllWords,
} from './utils.js';
-import { RA_CountCharTokens, humanizedDateTime, dragElement } from "./RossAscends-mods.js";
-import { sortGroupMembers, loadMovingUIState } from './power-user.js';
+import { RA_CountCharTokens, humanizedDateTime, dragElement, favsToHotswap } from "./RossAscends-mods.js";
+import { loadMovingUIState, sortEntitiesList } from './power-user.js';
import {
chat,
@@ -87,7 +87,8 @@ let groups = [];
let selected_group = null;
let group_generation_id = null;
let fav_grp_checked = false;
-let fav_filter_on = false;
+let openGroupId = null;
+let newGroupMembers = [];
export const group_activation_strategy = {
NATURAL: 0,
@@ -96,12 +97,7 @@ export const group_activation_strategy = {
export const groupCandidatesFilter = new FilterHelper(debounce(printGroupCandidates, 100));
const groupAutoModeInterval = setInterval(groupChatAutoModeWorker, 5000);
-const saveGroupDebounced = debounce(async (group) => await _save(group), 500);
-
-function printGroupCandidates(fullRefresh = false) {
- toastr.info('Group candidates tags filter is temporarily unavailable.');
- console.log('TODO: implement printGroupCandidates');
-}
+const saveGroupDebounced = debounce(async (group, reload) => await _save(group, reload), 500);
async function _save(group, reload = true) {
await fetch("/editgroup", {
@@ -232,7 +228,7 @@ async function saveGroupChat(groupId, shouldSaveGroup) {
});
if (shouldSaveGroup && response.ok) {
- await editGroup(groupId);
+ await editGroup(groupId, false, false);
}
}
@@ -250,7 +246,7 @@ export async function renameGroupMember(oldAvatar, newAvatar, newName) {
// Replace group member avatar id and save the changes
group.members[memberIndex] = newAvatar;
- await editGroup(group.id, true);
+ await editGroup(group.id, true, false);
console.log(`Renamed character ${newName} in group: ${group.name}`)
// Load all chats from this group
@@ -791,8 +787,6 @@ function activateNaturalOrder(members, input, lastMessage, allowSelfResponses, i
return memberIds;
}
-
-
async function deleteGroup(id) {
const response = await fetch("/deletegroup", {
method: "POST",
@@ -831,7 +825,7 @@ export async function editGroup(id, immediately, reload = true) {
return await _save(group, reload);
}
- saveGroupDebounced(group);
+ saveGroupDebounced(group, reload);
}
let groupAutoModeAbortController = null;
@@ -857,104 +851,222 @@ async function groupChatAutoModeWorker() {
async function modifyGroupMember(chat_id, groupMember, isDelete) {
const id = groupMember.data("id");
-
- const template = groupMember.clone();
- let _thisGroup = groups.find((x) => x.id == chat_id);
- template.data("id", id);
+ const thisGroup = groups.find((x) => x.id == chat_id);
+ const membersArray = thisGroup?.members ?? newGroupMembers;
if (isDelete) {
- $("#rm_group_add_members").prepend(template);
- } else {
- $("#rm_group_members").prepend(template);
- }
-
- if (_thisGroup) {
- if (isDelete) {
- const index = _thisGroup.members.findIndex((x) => x === id);
- if (index !== -1) {
- _thisGroup.members.splice(index, 1);
- }
- } else {
- _thisGroup.members.push(id);
- template.css({ 'order': _thisGroup.members.length });
+ const index = membersArray.findIndex((x) => x === id);
+ if (index !== -1) {
+ membersArray.splice(membersArray.indexOf(id), 1);
}
- await editGroup(selected_group);
- updateGroupAvatar(_thisGroup);
- }
- else {
- template.css({ 'order': 'unset' });
+ } else {
+ membersArray.unshift(id);
}
- groupMember.remove();
- const groupHasMembers = !!$("#rm_group_members").children().length;
+ if (openGroupId) {
+ await editGroup(openGroupId, false, false);
+ updateGroupAvatar(thisGroup);
+ }
+
+ printGroupCandidates();
+ printGroupMembers();
+
+ const groupHasMembers = getGroupCharacters({ doFilter: false, onlyMembers: true }).length > 0;
$("#rm_group_submit").prop("disabled", !groupHasMembers);
}
async function reorderGroupMember(chat_id, groupMember, direction) {
const id = groupMember.data("id");
const group = groups.find((x) => x.id == chat_id);
+ const memberArray = group?.members ?? newGroupMembers;
+
+ const indexOf = memberArray.indexOf(id);
+ if (direction == 'down') {
+ const next = memberArray[indexOf + 1];
+ if (next) {
+ memberArray[indexOf + 1] = memberArray[indexOf];
+ memberArray[indexOf] = next;
+ }
+ }
+ if (direction == 'up') {
+ const prev = memberArray[indexOf - 1];
+ if (prev) {
+ memberArray[indexOf - 1] = memberArray[indexOf];
+ memberArray[indexOf] = prev;
+ }
+ }
+
+ printGroupMembers();
// Existing groups need to modify members list
- if (group && group.members.length > 1) {
- const indexOf = group.members.indexOf(id);
- if (direction == 'down') {
- const next = group.members[indexOf + 1];
- if (next) {
- group.members[indexOf + 1] = group.members[indexOf];
- group.members[indexOf] = next;
- }
- }
- if (direction == 'up') {
- const prev = group.members[indexOf - 1];
- if (prev) {
- group.members[indexOf - 1] = group.members[indexOf];
- group.members[indexOf] = prev;
- }
- }
-
- await editGroup(chat_id);
+ if (openGroupId) {
+ await editGroup(chat_id, false, false);
updateGroupAvatar(group);
- // stupid but lifts the manual reordering
- select_group_chats(chat_id, true);
}
- // New groups just can't be DOM-ordered
- else {
- if (direction == 'down') {
- groupMember.insertAfter(groupMember.next());
- }
- if (direction == 'up') {
- groupMember.insertBefore(groupMember.prev());
- }
+}
+
+async function onGroupActivationStrategyInput(e) {
+ if (openGroupId) {
+ let _thisGroup = groups.find((x) => x.id == openGroupId);
+ _thisGroup.activation_strategy = Number(e.target.value);
+ await editGroup(openGroupId, false, false);
+ }
+}
+
+async function onGroupNameInput() {
+ if (openGroupId) {
+ let _thisGroup = groups.find((x) => x.id == openGroupId);
+ _thisGroup.name = $(this).val();
+ $("#rm_button_selected_ch").children("h2").text(_thisGroup.name);
+ await editGroup(openGroupId);
+ }
+}
+
+function isGroupMember(group, avatarId) {
+ if (group && Array.isArray(group.members)) {
+ return group.members.includes(avatarId);
+ } else {
+ return newGroupMembers.includes(avatarId);
+ }
+}
+
+function getGroupCharacters({ doFilter, onlyMembers } = {}) {
+ function sortMembersFn(a, b) {
+ const membersArray = thisGroup?.members ?? newGroupMembers;
+ const aIndex = membersArray.indexOf(a.item.avatar);
+ const bIndex = membersArray.indexOf(b.item.avatar);
+ return aIndex - bIndex;
+ }
+
+ const thisGroup = openGroupId && groups.find((x) => x.id == openGroupId);
+ let candidates = characters.map((x, index) => ({ item: x, id: index, type: 'character' }));
+ candidates = candidates.filter((x) => isGroupMember(thisGroup, x.item.avatar) == onlyMembers);
+
+ if (onlyMembers) {
+ candidates.sort(sortMembersFn);
+ } else {
+ sortEntitiesList(candidates);
+ }
+
+ if (doFilter) {
+ candidates = groupCandidatesFilter.applyFilters(candidates);
+ }
+
+ return candidates;
+}
+
+function printGroupCandidates() {
+ $("#rm_group_add_members_pagination").pagination({
+ dataSource: getGroupCharacters({ doFilter: true, onlyMembers: false }),
+ pageSize: 5,
+ pageRange: 1,
+ position: 'top',
+ showPageNumbers: false,
+ showSizeChanger: false,
+ prevText: '<',
+ nextText: '>',
+ showNavigator: true,
+ callback: function (data) {
+ $("#rm_group_add_members").empty();
+ for (const i of data) {
+ $("#rm_group_add_members").append(getGroupCharacterBlock(i.item));
+ }
+ },
+ });
+}
+
+function printGroupMembers() {
+ $("#rm_group_members_pagination").pagination({
+ dataSource: getGroupCharacters({ doFilter: false, onlyMembers: true }),
+ pageSize: 5,
+ pageRange: 1,
+ position: 'top',
+ showPageNumbers: false,
+ showSizeChanger: false,
+ prevText: '<',
+ nextText: '>',
+ showNavigator: true,
+ callback: function (data) {
+ $("#rm_group_members").empty();
+ for (const i of data) {
+ $("#rm_group_members").append(getGroupCharacterBlock(i.item));
+ }
+ },
+ });
+}
+
+function getGroupCharacterBlock(character) {
+ const avatar = getThumbnailUrl('avatar', character.avatar);
+ const template = $("#group_member_template .group_member").clone();
+ const isFav = character.fav || character.fav == 'true';
+ template.data("id", character.avatar);
+ template.find(".avatar img").attr({ "src": avatar, "title": character.avatar });
+ template.find(".ch_name").text(character.name);
+ template.attr("chid", characters.indexOf(character));
+ template.find('.ch_fav').val(isFav);
+ template.toggleClass('is_fav', isFav);
+ template.toggleClass('disabled', isGroupMemberDisabled(character.avatar));
+
+ // Display inline tags
+ const tags = getTagsList(character.avatar);
+ const tagsElement = template.find('.tags');
+ tags.forEach(tag => appendTagToList(tagsElement, tag, {}));
+
+ if (!openGroupId) {
+ template.find('[data-action="speak"]').hide();
+ template.find('[data-action="enable"]').hide();
+ template.find('[data-action="disable"]').hide();
+ }
+
+ return template;
+}
+
+function isGroupMemberDisabled(avatarId) {
+ const thisGroup = openGroupId && groups.find((x) => x.id == openGroupId);
+ return Boolean(thisGroup && thisGroup.disabled_members.includes(avatarId));
+}
+
+function onDeleteGroupClick() {
+ if (is_group_generating) {
+ toastr.warning('Not so fast! Wait for the characters to stop typing before deleting the group.');
+ return;
+ }
+
+ $("#dialogue_popup").data("group_id", openGroupId);
+ callPopup('Delete the group?
This will also delete all your chats with that group. If you want to delete a single conversation, select a "View past chats" option in the lower left menu.
', "del_group");
+}
+
+async function onFavoriteGroupClick() {
+ updateFavButtonState(!fav_grp_checked);
+ if (openGroupId) {
+ let _thisGroup = groups.find((x) => x.id == openGroupId);
+ _thisGroup.fav = fav_grp_checked;
+ await editGroup(openGroupId, false, false);
+ favsToHotswap();
+ }
+}
+
+async function onGroupSelfResponsesClick() {
+ if (openGroupId) {
+ let _thisGroup = groups.find((x) => x.id == openGroupId);
+ const value = $(this).prop("checked");
+ _thisGroup.allow_self_responses = value;
+ await editGroup(openGroupId, false, false);
}
}
function select_group_chats(groupId, skipAnimation) {
- const group = groupId && groups.find((x) => x.id == groupId);
+ openGroupId = groupId;
+ newGroupMembers = [];
+ const group = openGroupId && groups.find((x) => x.id == openGroupId);
const groupName = group?.name ?? "";
+ const replyStrategy = Number(group?.activation_strategy ?? group_activation_strategy.NATURAL);
+
setMenuType(!!group ? 'group_edit' : 'group_create');
$("#group_avatar_preview").empty().append(getGroupAvatar(group));
$("#rm_group_restore_avatar").toggle(!!group && isDataURL(group.avatar_url));
$("#rm_group_chat_name").val(groupName);
- $("#rm_group_chat_name").off();
- $("#rm_group_chat_name").on("input", async function () {
- if (groupId) {
- let _thisGroup = groups.find((x) => x.id == groupId);
- _thisGroup.name = $(this).val();
- $("#rm_button_selected_ch").children("h2").text(_thisGroup.name);
- await editGroup(groupId);
- }
- });
$("#rm_group_filter").val("").trigger("input");
-
- $('input[name="rm_group_activation_strategy"]').off();
- $('input[name="rm_group_activation_strategy"]').on("input", async function (e) {
- if (groupId) {
- let _thisGroup = groups.find((x) => x.id == groupId);
- _thisGroup.activation_strategy = Number(e.target.value);
- await editGroup(groupId);
- }
- });
- const replyStrategy = Number(group?.activation_strategy ?? group_activation_strategy.NATURAL);
$(`input[name="rm_group_activation_strategy"][value="${replyStrategy}"]`).prop('checked', true);
if (!skipAnimation) {
@@ -962,53 +1074,15 @@ function select_group_chats(groupId, skipAnimation) {
}
// render characters list
- $("#rm_group_add_members").empty();
- $("#rm_group_members").empty();
- for (let character of characters) {
- const avatar =
- character.avatar != "none"
- ? getThumbnailUrl('avatar', character.avatar)
- : default_avatar;
- const template = $("#group_member_template .group_member").clone();
- const isFav = character.fav || character.fav == 'true';
- template.data("id", character.avatar);
- template.find(".avatar img").attr("src", avatar);
- template.find(".avatar img").attr("title", character.avatar);
- template.find(".ch_name").text(character.name);
- template.attr("chid", characters.indexOf(character));
- template.find('.ch_fav').val(isFav);
- template.toggleClass('is_fav', isFav);
-
- // Display inline tags
- const tags = getTagsList(character.avatar);
- const tagsElement = template.find('.tags');
- tags.forEach(tag => appendTagToList(tagsElement, tag, {}));
-
- if (!group) {
- template.find('[data-action="speak"]').hide();
- }
-
- if (
- group &&
- Array.isArray(group.members) &&
- group.members.includes(character.avatar)
- ) {
- template.css({ 'order': group.members.indexOf(character.avatar) });
- template.toggleClass('disabled', group.disabled_members.includes(character.avatar));
- $("#rm_group_members").append(template);
- } else {
- $("#rm_group_add_members").append(template);
- }
- }
-
- sortGroupMembers("#rm_group_add_members .group_member");
+ printGroupCandidates();
+ printGroupMembers();
const groupHasMembers = !!$("#rm_group_members").children().length;
$("#rm_group_submit").prop("disabled", !groupHasMembers);
$("#rm_group_allow_self_responses").prop("checked", group && group.allow_self_responses);
// bottom buttons
- if (groupId) {
+ if (openGroupId) {
$("#rm_group_submit").hide();
$("#rm_group_delete").show();
$("#rm_group_scenario").show();
@@ -1021,39 +1095,8 @@ function select_group_chats(groupId, skipAnimation) {
$("#rm_group_scenario").hide();
}
- $("#rm_group_delete").off();
- $("#rm_group_delete").on("click", function () {
- if (is_group_generating) {
- toastr.warning('Not so fast! Wait for the characters to stop typing before deleting the group.');
- return;
- }
-
- $("#dialogue_popup").data("group_id", groupId);
- callPopup('Delete the group?
This will also delete all your chats with that group. If you want to delete a single conversation, select a "View past chats" option in the lower left menu.
', "del_group");
- });
-
updateFavButtonState(group?.fav ?? false);
- $("#group_favorite_button").off('click');
- $("#group_favorite_button").on('click', async function () {
- updateFavButtonState(!fav_grp_checked);
- if (group) {
- let _thisGroup = groups.find((x) => x.id == groupId);
- _thisGroup.fav = fav_grp_checked;
- await editGroup(groupId);
- }
- });
-
- $("#rm_group_allow_self_responses").off();
- $("#rm_group_allow_self_responses").on("input", async function () {
- if (group) {
- let _thisGroup = groups.find((x) => x.id == groupId);
- const value = $(this).prop("checked");
- _thisGroup.allow_self_responses = value;
- await editGroup(groupId);
- }
- });
-
// top bar
if (group) {
$("#rm_group_automode_label").show();
@@ -1064,118 +1107,112 @@ function select_group_chats(groupId, skipAnimation) {
$("#rm_group_automode_label").hide();
}
- $("#group_avatar_button").off('input').on("input", uploadGroupAvatar);
- $("#rm_group_restore_avatar").off('click').on("click", restoreGroupAvatar);
+ eventSource.emit('groupSelected', {detail: {id: openGroupId, group: group}});
+}
+async function uploadGroupAvatar(event) {
+ const file = event.target.files[0];
- async function uploadGroupAvatar(event) {
- const file = event.target.files[0];
-
- if (!file) {
- return;
- }
-
- const e = await new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.onload = resolve;
- reader.onerror = reject;
- reader.readAsDataURL(file);
- });
-
- $('#dialogue_popup').addClass('large_dialogue_popup wide_dialogue_popup');
-
- const croppedImage = await callPopup(getCropPopup(e.target.result), 'avatarToCrop');
-
- if (!croppedImage) {
- return;
- }
-
- const thumbnail = await createThumbnail(croppedImage, 96, 144);
-
- if (!groupId) {
- $('#group_avatar_preview img').attr('src', thumbnail);
- $('#rm_group_restore_avatar').show();
- return;
- }
-
- let _thisGroup = groups.find((x) => x.id == groupId);
- _thisGroup.avatar_url = thumbnail;
- $("#group_avatar_preview").empty().append(getGroupAvatar(_thisGroup));
- $("#rm_group_restore_avatar").show();
- await editGroup(groupId, true, true);
+ if (!file) {
+ return;
}
- async function restoreGroupAvatar() {
- const confirm = await callPopup('Are you sure you want to restore the group avatar?
Your custom image will be deleted, and a collage will be used instead.', 'confirm');
-
- if (!confirm) {
- return;
- }
-
- if (!groupId) {
- $("#group_avatar_preview img").attr("src", default_avatar);
- $("#rm_group_restore_avatar").hide();
- return;
- }
-
- let _thisGroup = groups.find((x) => x.id == groupId);
- _thisGroup.avatar_url = '';
- $("#group_avatar_preview").empty().append(getGroupAvatar(_thisGroup));
- $("#rm_group_restore_avatar").hide();
- await editGroup(groupId, true, true);
- }
-
- $(document).off("click", ".group_member .right_menu_button");
- $(document).on("click", ".group_member .right_menu_button", async function (event) {
- event.stopPropagation();
- const action = $(this).data('action');
- const member = $(this).closest('.group_member');
-
- if (action === 'remove') {
- await modifyGroupMember(groupId, member, true);
- }
-
- if (action === 'add') {
- await modifyGroupMember(groupId, member, false);
- }
-
- if (action === 'enable') {
- member.removeClass('disabled');
- const _thisGroup = groups.find(x => x.id === groupId);
- const index = _thisGroup.disabled_members.indexOf(member.data('id'));
- if (index !== -1) {
- _thisGroup.disabled_members.splice(index, 1);
- }
- await editGroup(groupId);
- }
-
- if (action === 'disable') {
- member.addClass('disabled');
- const _thisGroup = groups.find(x => x.id === groupId);
- _thisGroup.disabled_members.push(member.data('id'));
- await editGroup(groupId);
- }
-
- if (action === 'up' || action === 'down') {
- await reorderGroupMember(groupId, member, action);
- }
-
- if (action === 'view') {
- openCharacterDefinition(member);
- }
-
- if (action === 'speak') {
- const chid = Number(member.attr('chid'));
- if (Number.isInteger(chid)) {
- Generate('normal', { force_chid: chid });
- }
- }
-
- sortGroupMembers("#rm_group_add_members .group_member");
- await eventSource.emit(event_types.GROUP_UPDATED);
+ const e = await new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = resolve;
+ reader.onerror = reject;
+ reader.readAsDataURL(file);
});
- eventSource.emit('groupSelected', {detail: {id: groupId, group: group}});
+ $('#dialogue_popup').addClass('large_dialogue_popup wide_dialogue_popup');
+
+ const croppedImage = await callPopup(getCropPopup(e.target.result), 'avatarToCrop');
+
+ if (!croppedImage) {
+ return;
+ }
+
+ const thumbnail = await createThumbnail(croppedImage, 96, 144);
+
+ if (!openGroupId) {
+ $('#group_avatar_preview img').attr('src', thumbnail);
+ $('#rm_group_restore_avatar').show();
+ return;
+ }
+
+ let _thisGroup = groups.find((x) => x.id == openGroupId);
+ _thisGroup.avatar_url = thumbnail;
+ $("#group_avatar_preview").empty().append(getGroupAvatar(_thisGroup));
+ $("#rm_group_restore_avatar").show();
+ await editGroup(openGroupId, true, true);
+}
+
+async function restoreGroupAvatar() {
+ const confirm = await callPopup('Are you sure you want to restore the group avatar?
Your custom image will be deleted, and a collage will be used instead.', 'confirm');
+
+ if (!confirm) {
+ return;
+ }
+
+ if (!openGroupId) {
+ $("#group_avatar_preview img").attr("src", default_avatar);
+ $("#rm_group_restore_avatar").hide();
+ return;
+ }
+
+ let _thisGroup = groups.find((x) => x.id == openGroupId);
+ _thisGroup.avatar_url = '';
+ $("#group_avatar_preview").empty().append(getGroupAvatar(_thisGroup));
+ $("#rm_group_restore_avatar").hide();
+ await editGroup(openGroupId, true, true);
+}
+
+async function onGroupActionClick(event) {
+ event.stopPropagation();
+ const action = $(this).data('action');
+ const member = $(this).closest('.group_member');
+
+ if (action === 'remove') {
+ await modifyGroupMember(openGroupId, member, true);
+ }
+
+ if (action === 'add') {
+ await modifyGroupMember(openGroupId, member, false);
+ }
+
+ if (action === 'enable') {
+ member.removeClass('disabled');
+ const _thisGroup = groups.find(x => x.id === openGroupId);
+ const index = _thisGroup.disabled_members.indexOf(member.data('id'));
+ if (index !== -1) {
+ _thisGroup.disabled_members.splice(index, 1);
+ }
+ await editGroup(openGroupId, false, false);
+ }
+
+ if (action === 'disable') {
+ member.addClass('disabled');
+ const _thisGroup = groups.find(x => x.id === openGroupId);
+ _thisGroup.disabled_members.push(member.data('id'));
+ await editGroup(openGroupId, false, false);
+ }
+
+ if (action === 'up' || action === 'down') {
+ await reorderGroupMember(openGroupId, member, action);
+ }
+
+ if (action === 'view') {
+ openCharacterDefinition(member);
+ }
+
+ if (action === 'speak') {
+ const chid = Number(member.attr('chid'));
+ if (Number.isInteger(chid)) {
+ Generate('normal', { force_chid: chid });
+ }
+ }
+
+ await eventSource.emit(event_types.GROUP_UPDATED);
}
function updateFavButtonState(state) {
@@ -1243,10 +1280,7 @@ async function createGroup() {
let name = $("#rm_group_chat_name").val();
let allow_self_responses = !!$("#rm_group_allow_self_responses").prop("checked");
let activation_strategy = $('input[name="rm_group_activation_strategy"]:checked').val() ?? group_activation_strategy.NATURAL;
- const members = $("#rm_group_members .group_member")
- .map((_, x) => $(x).data("id"))
- .toArray();
-
+ const members = newGroupMembers;
const memberNames = characters.filter(x => members.includes(x.avatar)).map(x => x.name).join(", ");
if (!name) {
@@ -1276,6 +1310,7 @@ async function createGroup() {
});
if (createGroupResponse.ok) {
+ newGroupMembers = [];
const data = await createGroupResponse.json();
createTagMapFromList("#groupTagList", data.id);
await getCharacters();
@@ -1359,7 +1394,7 @@ export async function openGroupChat(groupId, chatId) {
group['date_last_chat'] = Date.now();
updateChatMetadata(group.chat_metadata, true);
- await editGroup(groupId, true);
+ await editGroup(groupId, true, false);
await getGroupChat(groupId);
}
@@ -1452,7 +1487,7 @@ export async function saveGroupBookmarkChat(groupId, name, metadata, mesId) {
? chat.slice(0, parseInt(mesId) + 1)
: chat;
- await editGroup(groupId, true);
+ await editGroup(groupId, true, false);
await fetch("/savegroupchat", {
method: "POST",
@@ -1520,4 +1555,12 @@ jQuery(() => {
});
$("#send_textarea").on("keyup", onSendTextareaInput);
$("#groupCurrentMemberPopoutButton").on('click', doCurMemberListPopout);
+ $("#rm_group_chat_name").on("input", onGroupNameInput)
+ $("#rm_group_delete").off().on("click", onDeleteGroupClick);
+ $("#group_favorite_button").on('click', onFavoriteGroupClick);
+ $("#rm_group_allow_self_responses").on("input", onGroupSelfResponsesClick);
+ $('input[name="rm_group_activation_strategy"]').on("input", onGroupActivationStrategyInput);
+ $("#group_avatar_button").on("input", uploadGroupAvatar);
+ $("#rm_group_restore_avatar").on("click", restoreGroupAvatar);
+ $(document).on("click", ".group_member .right_menu_button", onGroupActionClick);
});
diff --git a/public/scripts/power-user.js b/public/scripts/power-user.js
index 42f1c9aa3..9a696850f 100644
--- a/public/scripts/power-user.js
+++ b/public/scripts/power-user.js
@@ -33,7 +33,6 @@ export {
loadMovingUIState,
collapseNewlines,
playMessageSound,
- sortGroupMembers,
sortEntitiesList,
fixMarkdown,
power_user,
@@ -1133,19 +1132,6 @@ function sortEntitiesList(entities) {
entities.sort((a, b) => sortFunc(a.item, b.item));
}
-
-function sortGroupMembers(selector) {
- if (power_user.sort_field == undefined || characters.length === 0) {
- return;
- }
-
- let orderedList = characters.slice().sort(sortFunc);
-
- for (let i = 0; i < characters.length; i++) {
- $(`${selector}[chid="${i}"]`).css({ 'order': orderedList.indexOf(characters[i]) });
- }
-}
-
async function saveTheme() {
const name = await callPopup('Enter a theme preset name:', 'input');
diff --git a/public/style.css b/public/style.css
index 7ea35a71b..535aa5768 100644
--- a/public/style.css
+++ b/public/style.css
@@ -3234,6 +3234,12 @@ h5 {
display: none;
}
+.group_pagination {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
#rm_group_chats_block .tag.filterByGroups {
display: none;
}